sxd hace 6 años
padre
commit
d430933b02

+ 82 - 1
src/css/style.css

@@ -37,7 +37,41 @@
   vertical-align: middle;
   margin-right: 15px;
 }
-
+.toolbar .dashboard{
+  border-top: 1px solid #ddd;
+  background-color: inherit;
+  padding: 10px;
+  overflow: auto;
+  display: none;
+}
+.toolbar .dashboard label{
+  font-weight: bolder;
+}
+.toolbar .dashboard input[type=number]{
+  padding: 6px 12px;
+  color: inherit;
+  background-color: transparent;
+  border: 1px solid #ddd;
+  border-radius: 5px;
+  width: 50px;
+  margin-left: 20px;
+}
+.toolbar>.dashboard button {
+  color: inherit;
+  background-color: inherit;
+  padding: 4px 12px;
+  white-space: nowrap;
+  vertical-align: middle;
+  cursor: pointer;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  border: 1px solid #ddd;
+  border-radius: 5px;
+  margin-right: 4px;
+  margin-left: 30px;
+}
 /* 组件的样式 */
 .outer-box{
   color: rgb(103, 103, 103);
@@ -184,4 +218,51 @@
   top: 50%;
   right: -2px;
   margin-top: -5px;
+}
+
+/*这里是下划线的样式*/
+.question-selection-content .outer-underline{
+  line-height: 20px;
+  display: inline-block;
+  padding: 5px 10px;
+  margin-left: 10px;
+  margin-top: 15px;
+}
+.question-selection-content .outer-underline .underline{
+  width: 100%;
+  height: 20px;
+  border-bottom: 1px solid #000;
+}
+
+/*这里是空格的组件*/
+.question-selection-content .outer-blank{
+  margin-left: 10px;
+  display: inline-block;
+  padding: 5px;
+}
+.question-selection-content .outer-blank .blank{
+  width: 25px;
+  height: 25px;
+  border: 1px solid #000;
+}
+
+/*添加作文的样式*/
+.question-selection-content .outer-composition{
+  margin-top: 20px;
+  padding: 10px;
+  display: block;
+}
+.question-selection-content .outer-composition .composition-col{
+  margin-bottom: 10px;
+}
+.question-selection-content .outer-composition .composition-col .composition-blank{
+  width: 25px;
+  height: 25px;
+  display: inline-block;
+  border-top:1px solid #000;
+  border-left:1px solid #000;
+  border-bottom:1px solid #000;
+}
+.question-selection-content .outer-composition .composition-col .composition-blank:last-child{
+  border-right:1px solid #000;
 }

+ 22 - 0
src/js/box/blank.js

@@ -0,0 +1,22 @@
+/**
+ * Create by sxd
+ * date 2018-04-13
+ * Description:
+ */
+var Blank = function(cfg){
+
+  this.vdom = null;
+
+};
+
+Blank.prototype.renderToDom = function () {
+  this.vdom = $('<div class="outer-blank"></div>');
+  this.renderBlankDom();
+};
+
+Blank.prototype.renderBlankDom = function () {
+  let blank = $('<div class="blank"></div>');
+  this.vdom.append(blank);
+};
+
+export default Blank;

+ 11 - 5
src/js/box/boxContent.js

@@ -18,8 +18,10 @@ var boxContent = function(style) {
   //一个实例化的dom
   this.vdom = null;
   //组件当中的所有html
-  this.editorContent = null;
+  this.editorContentArray = [];
 
+
+  // 拖拽和伸缩
   this.drag = false;
   this.smove = false;
   this.nmove = false;
@@ -46,7 +48,7 @@ boxContent.prototype.renderBoxDom = function() {
   let editorDom = $('<div class="element comp_paragraph editable-text" contenteditable="true"></div>');
   let circleDom = $('<div class="eqc-select"></div>');
   editorDom.text('双击此处进行编辑');
-  if(this.editorContent)editorDom.html(this.editorContent);
+  if(this.editorContentArray.length > 0)editorDom.html(this.editorContentArray); // 这里之后再进行操作
   editorDom.css({ 'pointer-events': this.isEditor ? 'all' : 'none' });
   circleDom.append(this.boxTpl);
   this.vdom.append(editorDom);
@@ -71,7 +73,7 @@ boxContent.prototype.renderBoxDom = function() {
 boxContent.prototype.bindDragEvent = function (el) {
   let _this = this;
   el.on('mousedown' , function(e) {
-    console.log(123);
+    e.stopPropagation();
     let $this = $(this);
     _this.ox = e.pageX;//原始x位置
     _this.oy = e.pageY;
@@ -79,7 +81,7 @@ boxContent.prototype.bindDragEvent = function (el) {
     _this.left = parseInt($this.css('left').replace('px', ''));
     _this.drag = true;
     el.on('mousemove', function (e) {
-      if(_this.drag){
+      if(_this.drag && _this.isEditor == false){
         let x = e.pageX - _this.ox;
         let y = e.pageY - _this.oy;
         $(this).css({
@@ -303,15 +305,19 @@ boxContent.prototype.bindMoveSEEvent = function (el){
 
 
 boxContent.prototype.bindEditorEvent = function(el) {
+
+  let _this = this;
   el.on('dblclick', function(e) {
     let child = e.target.children[0] || e.target;
-    $(this).find('.comp_paragraph').css('pointer-events','all').select();
+    $(this).css({ height: 'auto' }).find('.comp_paragraph').css({'pointer-events':'all', height: 'auto'}).select();
     let range = window.getSelection();// 创建range
     range.selectAllChildren(child);// range 选择obj下所有子内容
+    _this.isEditor = true;
   });
 
   this.vdom.find('.comp_paragraph').on('blur',function(){
     $(this).css('pointer-events','none');
+    _this.isEditor = false;
   });
 
 };

+ 35 - 0
src/js/box/composition.js

@@ -0,0 +1,35 @@
+/**
+ * Create by sxd
+ * date 2018-04-13
+ * Description:
+ */
+var Composition = function(cfg){
+  this.words = (cfg && cfg.words) || 980;
+  this.col = (cfg && cfg.col) || 2;
+  this.vdom = null;
+  this.parentWidth = 0;
+};
+
+Composition.prototype.renderToDom = function () {
+  this.vdom = $('<div class="outer-composition"></div>');
+  this.renderBlankDom();
+};
+Composition.prototype.renderBlankDom = function () {
+  let rowLen = 20;let blankNum = 40;
+  let divCol = document.createElement('div');
+  divCol.className = 'composition-col';
+  let colArray = [];let blankArray = [];
+  let blank = '<div class="composition-blank"></div>';
+  for(let i = 0;i<rowLen;i++){
+    divCol.innerHTML = '';
+    blankArray.length = 0;
+    for(let j=0;j<blankNum;j++){
+      blankArray.push(blank);
+    }
+    divCol.innerHTML = blankArray.join('');
+    colArray.push(divCol.outerHTML);
+  }
+  this.vdom.append(colArray.join(''));
+};
+
+export default Composition;

+ 180 - 0
src/js/box/photo.js

@@ -0,0 +1,180 @@
+/**
+ * Create by sxd
+ * date 2018-04-13
+ * Description:
+ */
+var Photo = function(cfg) {
+
+  this.width = (cfg && cfg.width) || 150;
+  this.height = (cfg && cfg.height) || 120;
+  this.top = (cfg && cfg.height) || 10;
+  this.left = (cfg && cfg.height) || 20;
+  this.url = (cfg && cfg.url);
+  this.vdom = null;
+  this.inputDom = (cfg && cfg.dom) || null;
+
+  this.config = {
+    // server: null,
+    // fieldName: 'image',
+    // compress: true,
+    // width: 1600,
+    // height: 1600,
+    // quality: 80,
+    sizeLimit: 512 * 1024,// 512k
+    // upload: {
+    //     url: null,
+    //     headers: {},
+    //     params: {},
+    //     fieldName: {}
+    // },
+    compress: {
+      width: 1600,
+      height: 1600,
+      quality: 80
+    },
+    uploadHandler(responseText){
+      const json = JSON.parse(responseText);
+      return json.ok ? json.data : null
+    }
+  };
+
+};
+
+Photo.prototype.renderToDom = function () {
+  this.vdom = $('<div class="outer-photo"></div>');
+  this.vdom({ width: this.width, height: this.height ,top: this.top, left: this.left })
+  this.renderPhotoDom();
+};
+
+Photo.prototype.renderPhotoDom = function () {
+  let image = $('<img class="question-photo" src='+ this.url +' />');
+  this.vdom.append(image);
+};
+
+Photo.prototype.process = function () {
+  const _this = this;
+  const config = this.config;
+  if (!config.upload && typeof config.server === 'string') {
+    config.upload = {url: config.server}
+  }
+  if (config.upload && !config.upload.url) {
+    config.upload = null
+  }
+  if (config.upload && typeof config.fieldName === 'string') {
+    config.upload.fieldName = config.fieldName
+  }
+
+  if (typeof config.compress === 'boolean') {
+    config.compress = {
+      width: config.width,
+      height: config.height,
+      quality: config.quality
+    }
+  }
+
+  const file = this.inputDom.files[0];
+
+  if (file.size > config.sizeLimit) {
+    alter('上传的图片不能大于' + config.sizeLimit);
+    return
+  }
+
+  this.inputDom.value = null;
+
+  if (config.compress) {
+    config.compress.fieldName = config.upload && config.upload.fieldName
+      ? config.upload.fieldName : 'image';
+    lrz(file, config.compress).then((rst) => {
+      if (config.upload) {
+        _this.uploadToServer(rst.file)
+      } else {
+        _this.insertBase64(rst.base64)
+      }
+    }).catch((err) => {
+      this.setUploadError(err.toString())
+    });
+    return
+  }
+
+  if (!config.upload) {
+    const reader = new FileReader();
+    reader.onload = (e) => {
+      _this.insertBase64(e.target.result)
+    }
+    reader.readAsDataURL(file);
+    return
+  }
+  // 上传服务器
+  _this.uploadToServer(file)
+
+};
+
+Photo.prototype.uploadToServer = function(file) {
+  const config = this.config;
+
+  const formData = new FormData()
+  formData.append(config.upload.fieldName || 'image', file)
+
+  if (typeof config.upload.params === 'object') {
+    Object.keys(config.upload.params).forEach((key) => {
+      const value = config.upload.params[key]
+      if (Array.isArray(value)) {
+        value.forEach((v) => {
+          formData.append(key, v)
+        })
+      } else {
+        formData.append(key, value)
+      }
+    })
+  }
+
+  const xhr = new XMLHttpRequest()
+
+  xhr.onprogress = (e) => {
+    this.upload.status = 'progress'
+    if (e.lengthComputable) {
+      this.upload.progressComputable = true
+      const percentComplete = e.loaded / e.total
+      this.upload.complete = (percentComplete * 100).toFixed(2)
+    } else {
+      this.upload.progressComputable = false
+    }
+  }
+
+  xhr.onload = () => {
+    if (xhr.status >= 300) {
+      this.setUploadError(`request error,code ${xhr.status}`)
+      return
+    }
+
+    try {
+      const url = config.uploadHandler(xhr.responseText)
+      if (url) {
+        this.$parent.execCommand(Command.INSERT_IMAGE, url)
+      }
+    } catch (err) {
+      this.setUploadError(err.toString())
+    } finally {
+      this.upload.status = 'ready'
+    }
+  }
+
+  xhr.onerror = () => {
+    // find network info in brower tools
+    this.setUploadError('request error')
+  }
+
+  xhr.onabort = () => {
+    this.upload.status = 'abort'
+  }
+
+  xhr.open('POST', config.upload.url)
+  if (typeof config.upload.headers === 'object') {
+    Object.keys(config.upload.headers).forEach((k) => {
+      xhr.setRequestHeader(k, config.upload.headers[k])
+    })
+  }
+  xhr.send(formData)
+}
+
+export default Photo;

+ 26 - 0
src/js/box/underline.js

@@ -0,0 +1,26 @@
+/**
+ * Create by sxd
+ * date 2018-04-13
+ * Description:
+ */
+var Underline = function (cfg) {
+
+  this.uwidth = (cfg && cfg.width) || 350;
+
+  this.domId = ('underline_' + Math.random()).replace('.','_');
+  this.vdom = null;
+
+};
+
+Underline.prototype.renderToDom = function () {
+  this.vdom = $('<div class="outer-underline" id="'+ this.domId +'"></div>');
+  this.vdom.css({ width: this.uwidth });
+  this.renderUnderlineDom();
+};
+
+Underline.prototype.renderUnderlineDom = function() {
+  let underline = $('<div class="underline"></div>');
+  this.vdom.append(underline);
+};
+
+export default Underline;

+ 30 - 1
src/js/box/yzComponents.js

@@ -1,10 +1,17 @@
 import boxContent from './boxContent';
+import Underline from './underline';
+import Blank from './blank';
+import Composition from './composition';
+import Photo from './photo';
+
 let yzComponent = function (cfg) {
   this.parentDom = cfg.content;
   this.boxes = cfg.boxes || [];
   this.boxDom = [];
+
 };
 
+// 添加主键
 yzComponent.prototype.addComponent = function () {
   let box = new boxContent();
   box.renderToDom();
@@ -12,10 +19,32 @@ yzComponent.prototype.addComponent = function () {
   this.boxes.push(box);
 };
 
-
 //添加下划线
 yzComponent.prototype.addUnderline = function() {
+  let underline = new Underline();
+  underline.renderToDom();
+  this.parentDom.append(underline.vdom);
+};
+
+//添加空格
+yzComponent.prototype.addBlank = function () {
+  let blank = new Blank();
+  blank.renderToDom();
+  this.parentDom.append(blank.vdom);
+};
+
+//添加作文字数
+yzComponent.prototype.addComposition = function(words) {
+  let composition = new Composition(words);
+  composition.renderToDom();
+  this.parentDom.append(composition.vdom);
+};
 
+// 添加图片
+yzComponent.prototype.addPhoto = function (_this) {
+  let photo = new Photo({ url: _this.value, dom: _this });
+  photo.renderToDom();
+  this.parentDom.append(photo.vdom);
 };
 
 yzComponent.prototype.renderDom = function() {

+ 2 - 1
src/js/main2.js

@@ -394,6 +394,7 @@ pageManager.prototype.refreshToolBar = function(pNum = null, content) {
     this.toolBar.setSubjectTitle(pNum, content);
     $('#toolbar').remove();
   }
-  this.domBody.append(this.toolBar.toolbarContent());
+  let tool = this.toolBar.toolbarContent();
+  this.domBody.append(tool);
 };
 export default pageManager

+ 1 - 2
src/js/yzQuestion.js

@@ -53,7 +53,6 @@ yzQuestion.prototype._renderObjectiveDom = function () {
   this.vdom.append(ul);
 };
 
-
 /** 
  * function 生成主观题的dom
  * @TODO 生成content
@@ -75,7 +74,7 @@ yzQuestion.prototype._renderCommonDom = function () {
   }
   this.vdom.append(content);
   // 冒泡监听事件
-  this.vdom.on('mousedown', (e)=>{
+  this.vdom.on('mousedown', (e) => {
     // 将题目和domId冒泡到顶层
     this.vdom.trigger('getQuestion',[this.pNum,this.content]);
   });

+ 82 - 7
src/js/yzToolbar.js

@@ -4,12 +4,15 @@
  * Description:
  */
 import $ from 'jquery';
-import boxContent from './box/boxContent';
 
 var yzToolbar = function(){
   this.menu = [{
-    name: 'table',
-    title: '表格',
+    name: 'blank',
+    title: '加空',
+    icon: 'fa-square-o'
+  },{
+    name: 'composition',
+    title: '作文格',
     icon: 'fa-table'
   },{
     name: 'underline',
@@ -22,18 +25,23 @@ var yzToolbar = function(){
   },{
     name: 'component',
     title: '组件框',
-    icon: 'fa-square'
+    icon: 'fa-object-ungroup'
   },{
     name: 'subject',
     title: '无',
     icon: 'fa-list-alt'
   }];
 
+  // 导航栏的dom;
+  this.vdom = null;
+
   // 问题编号
   this.subjectNum = null;
   // 获取当前需要插入的Dom
   this.currentContent = null;
 
+  this.$dashboard = $('<div class="dashboard" style="max-height: 300px"></div>');
+
 };
 
 yzToolbar.prototype.toolbarContent = function () {
@@ -48,26 +56,55 @@ yzToolbar.prototype.toolbarContent = function () {
     liDom.setAttribute('title',item.title);
     liDom.appendChild(spanDom);
     liDom.appendChild(liText);
-    ulDom.appendChild(liDom);
     if( item.name == 'component' ){
       liDom.addEventListener('click', () => {
         this.addComponent(liDom);
       },!0);
     }
-
     if( item.name == 'underline' ){
       liDom.addEventListener('click', () => {
         this.addUnderline();
       },!0);
     }
-
+    if( item.name == 'blank' ){
+      liDom.addEventListener('click', () => {
+        this.addBlank();
+      },!0);
+    }
+    if( item.name == 'composition' ){
+      liDom.addEventListener('click',() => {
+        this.addComposition();
+      },!0);
+    }
+    if( item.name == 'picture' ){
+      let input = document.createElement('input');
+      input.setAttribute('type','file');input.setAttribute('accept','image/png,image/jpeg,image/gif,image/jpg');
+      input.style.display = 'none';input.setAttribute('id','uploadPhoto');
+      liDom.appendChild(input);
+      liDom.addEventListener('click',() => {
+        this.addPhoto();
+      },!0);
+    }
+    ulDom.appendChild(liDom);
   });
   toolDom.className = 'toolbar';
   toolDom.appendChild(ulDom);
   toolDom.setAttribute('id','toolbar');
+  this.removeCompositionNumDom();
+  this.vdom = toolDom;
   return toolDom;
 };
 
+yzToolbar.prototype.compositionNumDom = function(){
+  let table = $('<div class="table-dashboard"><label>作文字数<input class="blank-number" type="number" min="0" step="5" width="80px"></label><button class="submit-btn">添加</button></div>');
+  this.$dashboard.append(table);
+  $(this.vdom).append(this.$dashboard);
+};
+
+yzToolbar.prototype.removeCompositionNumDom = function () {
+  this.$dashboard.html('');
+};
+
 yzToolbar.prototype.setSubjectTitle = function(pNum,content) {
   this.subjectNum = pNum;
   this.currentContent = content;
@@ -89,7 +126,45 @@ yzToolbar.prototype.addComponent = function() {
 };
 
 yzToolbar.prototype.addUnderline = function() {
+  if(this.subjectNum == 'none' || !this.subjectNum){
+    alert('请选择主观题');return;
+  }
   this.currentContent.addUnderline();
 };
 
+yzToolbar.prototype.addBlank = function () {
+  if(this.subjectNum == 'none' || !this.subjectNum){
+    alert('请选择主观题');return;
+  }
+  this.currentContent.addBlank();
+};
+
+// 添加作文格
+yzToolbar.prototype.addComposition = function () {
+  if(this.subjectNum == 'none' || !this.subjectNum){
+    alert('请选择主观题');return;
+  }
+  if(this.$dashboard.children().length === 0)this.compositionNumDom();
+  this.$dashboard.slideToggle().finish();
+  let _this = this;
+  $('.submit-btn').on('click', function(e){
+    e.stopPropagation();
+    _this.currentContent.addComposition($('.blank-number').val());
+    $(this).off('click')
+  });
+};
+
+// 上传图片
+yzToolbar.prototype.addPhoto = function () {
+  if(this.subjectNum == 'none' || !this.subjectNum){
+    alert('请选择主观题');return;
+  }
+  let _this = this;
+  $('#uploadPhoto').on('change',function(e){
+    let inputDom = this;
+    _this.currentContent.addPhoto(inputDom);
+    $(this).off('change');
+  }).get(0).click();
+};
+
 export default yzToolbar;