javascript - 双击 iText 的编辑器控件

标签 javascript jquery css fabricjs

如何在单击时显示文本编辑控件,like here for example (see: Add Text )? I've managed to incorporate some menu text editing controls before但想试一试。我尝试在此处发布代码,但 JS/HTML/CSS 片段工具对我来说是坏的。

提前致谢!

编辑答案:

// Add image from local
var canvas = new fabric.Canvas('c');

// display/hide controls on double click
fabric.util.addListener(canvas.upperCanvasEl, 'dblclick', function(e) {
   if (canvas.findTarget(e)) {
      let objType = canvas.findTarget(e).type;
      if (objType === 'i-text') {
         document.getElementById('textControls').hidden = false;
      }
   }
});
canvas.on('before:selection:cleared', function(e) {
   document.getElementById('trash').hidden = true;
   document.getElementById('forward').hidden = true;
   document.getElementById('back').hidden = true;
   if (e.target.type === 'i-text') {
      document.getElementById('textControls').hidden = true;
   }
});

document.getElementById('file').addEventListener("change", function(e) {
   var file = e.target.files[0];
   var reader = new FileReader();
   reader.onload = function(f) {
      var data = f.target.result;
      fabric.Image.fromURL(data, function(img) {
         var oImg = img.set({
            left: 0,
            top: 0,
            angle: 00,
            stroke: '#F0F0F0', //<-- set this
            strokeWidth: 40 //<-- set this
         }).scale(0.2);
         canvas.add(oImg).renderAll();
         //var a = canvas.setActiveObject(oImg);
         var dataURL = canvas.toDataURL({
            format: 'png',
            quality: 1
         });
      });
   };
   reader.readAsDataURL(file);
});
// Delete selected object
window.deleteObject = function() {
      canvas.getActiveObject().remove();
   }
   // Refresh page
function refresh() {
   setTimeout(function() {
      location.reload()
   }, 100);
}
// Add text
function Addtext() {
   canvas.add(new fabric.IText('Tap and Type', {
      left: 50,
      top: 100,
      fontFamily: 'helvetica neue',
      fill: '#333',
      stroke: '#F0F0F0',
      strokeWidth: 1,
      fontSize: 45
   }));
}
document.getElementById('text-color').onchange = function() {
   canvas.getActiveObject().setFill(this.value);
   canvas.renderAll();
};
document.getElementById('text-color').onchange = function() {
   canvas.getActiveObject().setFill(this.value);
   canvas.renderAll();
};
document.getElementById('text-bg-color').onchange = function() {
   canvas.getActiveObject().setBackgroundColor(this.value);
   canvas.renderAll();
};
document.getElementById('text-lines-bg-color').onchange = function() {
   canvas.getActiveObject().setTextBackgroundColor(this.value);
   canvas.renderAll();
};
document.getElementById('text-stroke-color').onchange = function() {
   canvas.getActiveObject().setStroke(this.value);
   canvas.renderAll();
};
document.getElementById('text-stroke-width').onchange = function() {
   canvas.getActiveObject().setStrokeWidth(this.value);
   canvas.renderAll();
};
document.getElementById('font-family').onchange = function() {
   canvas.getActiveObject().setFontFamily(this.value);
   canvas.renderAll();
};
document.getElementById('text-font-size').onchange = function() {
   canvas.getActiveObject().setFontSize(this.value);
   canvas.renderAll();
};
document.getElementById('text-line-height').onchange = function() {
   canvas.getActiveObject().setLineHeight(this.value);
   canvas.renderAll();
};
document.getElementById('text-align').onchange = function() {
   canvas.getActiveObject().setTextAlign(this.value);
   canvas.renderAll();
};
radios5 = document.getElementsByName("fonttype"); // wijzig naar button
for (var i = 0, max = radios5.length; i < max; i++) {
   radios5[i].onclick = function() {
      if (document.getElementById(this.id).checked == true) {
         if (this.id == "text-cmd-bold") {
            canvas.getActiveObject().set("fontWeight", "bold");
         }
         if (this.id == "text-cmd-italic") {
            canvas.getActiveObject().set("fontStyle", "italic");
         }
         if (this.id == "text-cmd-underline") {
            canvas.getActiveObject().set("textDecoration", "underline");
         }
         if (this.id == "text-cmd-linethrough") {
            canvas.getActiveObject().set("textDecoration", "line-through");
         }
         if (this.id == "text-cmd-overline") {
            canvas.getActiveObject().set("textDecoration", "overline");
         }
      } else {
         if (this.id == "text-cmd-bold") {
            canvas.getActiveObject().set("fontWeight", "");
         }
         if (this.id == "text-cmd-italic") {
            canvas.getActiveObject().set("fontStyle", "");
         }
         if (this.id == "text-cmd-underline") {
            canvas.getActiveObject().set("textDecoration", "");
         }
         if (this.id == "text-cmd-linethrough") {
            canvas.getActiveObject().set("textDecoration", "");
         }
         if (this.id == "text-cmd-overline") {
            canvas.getActiveObject().set("textDecoration", "");
         }
      }
      canvas.renderAll();
   }
}
// Send selected object to front or back
var selectedObject;
canvas.on('object:selected', function(event) {
   selectedObject = event.target;
});
var sendSelectedObjectBack = function() {
   canvas.sendToBack(selectedObject);
}
var sendSelectedObjectToFront = function() {
   canvas.bringToFront(selectedObject);
}
body {
   padding: 10px 10px 10px 10px;
   font-family: "HelveticaNeue";
}

canvas {
   border: 1px solid grey;
   margin: 10px 0px 0px 0px;
}

.myFile {
   position: relative;
   overflow: hidden;
   float: left;
   clear: left;
}

.myFile input[type="file"] {
   display: block;
   position: absolute;
   top: 0;
   right: 0;
   opacity: 0;
   font-size: 30px;
   filter: alpha(opacity=0);
}

.footerheader {
   margin-top: 10px;
   font-weight: bold;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<a href="index.html">Testing</a>
<br>
<br>
<label class="myFile">
   <button>+ Photo</button>&nbsp;
   <input type="file" id="file" />
</label>
<button onclick="Addtext()">+ Text</button> / Selected Object:
<button id="trash" onClick="deleteObject()">Trash</button>
<button id="forward" onclick="sendSelectedObjectToFront()">Forward</button>
<button id="back" onclick="sendSelectedObjectBack()">Back</button> /
<button onclick="refresh()">Clear All</button>
<canvas id="c" width="800" height="600"></canvas>

<div id="textControls" hidden>
   <h2>Test Text Controls</h2>
   <div id="text-wrapper" style="margin-top: 10px" ng-show="getText()">
      <div id="text-controls">
         <input type="color" id="text-color" size="10">
         <label for="font-family" style="display:inline-block">Font family:</label>
         <select id="font-family">
            <option value="arial">Arial</option>
            <option value="helvetica" selected>Helvetica</option>
            <option value="myriad pro">Myriad Pro</option>
            <option value="delicious">Delicious</option>
            <option value="verdana">Verdana</option>
            <option value="georgia">Georgia</option>
            <option value="courier">Courier</option>
            <option value="comic sans ms">Comic Sans MS</option>
            <option value="impact">Impact</option>
            <option value="monaco">Monaco</option>
            <option value="optima">Optima</option>
            <option value="hoefler text">Hoefler Text</option>
            <option value="plaster">Plaster</option>
            <option value="engagement">Engagement</option>
         </select>
         <br>
         <label for="text-align" style="display:inline-block">Text align:</label>
         <select id="text-align">
            <option value="left">Left</option>
            <option value="center">Center</option>
            <option value="right">Right</option>
            <option value="justify">Justify</option>
         </select>
         <div>
            <label for="text-bg-color">Background color:</label>
            <input type="color" id="text-bg-color" size="10">
         </div>
         <div>
            <label for="text-lines-bg-color">Background text color:</label>
            <input type="color" id="text-lines-bg-color" size="10">
         </div>
         <div>
            <label for="text-stroke-color">Stroke color:</label>
            <input type="color" id="text-stroke-color">
         </div>
         <div>
            <label for="text-stroke-width">Stroke width:</label>
            <input type="range" value="1" min="1" max="5" id="text-stroke-width">
         </div>
         <div>
            <label for="text-font-size">Font size:</label>
            <input type="range" min="1" max="120" step="1" id="text-font-size">
         </div>
         <div>
            <label for="text-line-height">Line height:</label>
            <input type="range" min="0" max="10" step="0.1" id="text-line-height">
         </div>
      </div>
      <div id="text-controls-additional">
         <input type='checkbox' name='fonttype' id="text-cmd-bold"> Bold
         <input type='checkbox' name='fonttype' id="text-cmd-italic"> Italic
         <input type='checkbox' name='fonttype' id="text-cmd-underline"> Underline
         <input type='checkbox' name='fonttype' id="text-cmd-linethrough"> Linethrough
         <input type='checkbox' name='fonttype' id="text-cmd-overline"> Overline
      </div>
      <div class="footer">
         <div class="footerheader">asdasd</div>

         <ul>
            <li>1</li>
            <li>1</li>
            <li>1</li>
         </ul>

      </div>
   </div>
</div>

最佳答案

你可以使用 fabric.util.addListener 方法来检测 fabricjs Canvas 上的双击事件,双击时您必须检查是否单击了文本对象(iText),此后相应地显示文本编辑控件.

fabric.util.addListener(canvas.upperCanvasEl, 'dblclick', function(e) {
   if (canvas.findTarget(e)) {
      let objType = canvas.findTarget(e).type;
      if (objType === 'i-text') {
         document.getElementById('textControls').hidden = false; //show controls
      }
   }
});

ᴅᴇᴍᴏ⧩

// Add image from local
var canvas = new fabric.Canvas('c');

// display/hide controls on double click
fabric.util.addListener(canvas.upperCanvasEl, 'dblclick', function(e) {
   if (canvas.findTarget(e)) {
      let objType = canvas.findTarget(e).type;
      if (objType === 'i-text') {
         document.getElementById('textControls').hidden = false;
      }
   }
});
canvas.on('before:selection:cleared', function(e) {
   document.getElementById('trash').hidden = true;
   document.getElementById('forward').hidden = true;
   document.getElementById('back').hidden = true;
   if (e.target.type === 'i-text') {
      document.getElementById('textControls').hidden = true;
   }
});

document.getElementById('file').addEventListener("change", function(e) {
   var file = e.target.files[0];
   var reader = new FileReader();
   reader.onload = function(f) {
      var data = f.target.result;
      fabric.Image.fromURL(data, function(img) {
         var oImg = img.set({
            left: 0,
            top: 0,
            angle: 00,
            stroke: '#F0F0F0', //<-- set this
            strokeWidth: 40 //<-- set this
         }).scale(0.2);
         canvas.add(oImg).renderAll();
         //var a = canvas.setActiveObject(oImg);
         var dataURL = canvas.toDataURL({
            format: 'png',
            quality: 1
         });
      });
   };
   reader.readAsDataURL(file);
});
// Delete selected object
window.deleteObject = function() {
      canvas.getActiveObject().remove();
   }
   // Refresh page
function refresh() {
   setTimeout(function() {
      location.reload()
   }, 100);
}
// Add text
function Addtext() {
   canvas.add(new fabric.IText('Tap and Type', {
      left: 50,
      top: 100,
      fontFamily: 'helvetica neue',
      fill: '#333',
      stroke: '#F0F0F0',
      strokeWidth: 1,
      fontSize: 45
   }));
}
document.getElementById('text-color').onchange = function() {
   canvas.getActiveObject().setFill(this.value);
   canvas.renderAll();
};
document.getElementById('text-color').onchange = function() {
   canvas.getActiveObject().setFill(this.value);
   canvas.renderAll();
};
document.getElementById('text-bg-color').onchange = function() {
   canvas.getActiveObject().setBackgroundColor(this.value);
   canvas.renderAll();
};
document.getElementById('text-lines-bg-color').onchange = function() {
   canvas.getActiveObject().setTextBackgroundColor(this.value);
   canvas.renderAll();
};
document.getElementById('text-stroke-color').onchange = function() {
   canvas.getActiveObject().setStroke(this.value);
   canvas.renderAll();
};
document.getElementById('text-stroke-width').onchange = function() {
   canvas.getActiveObject().setStrokeWidth(this.value);
   canvas.renderAll();
};
document.getElementById('font-family').onchange = function() {
   canvas.getActiveObject().setFontFamily(this.value);
   canvas.renderAll();
};
document.getElementById('text-font-size').onchange = function() {
   canvas.getActiveObject().setFontSize(this.value);
   canvas.renderAll();
};
document.getElementById('text-line-height').onchange = function() {
   canvas.getActiveObject().setLineHeight(this.value);
   canvas.renderAll();
};
document.getElementById('text-align').onchange = function() {
   canvas.getActiveObject().setTextAlign(this.value);
   canvas.renderAll();
};
radios5 = document.getElementsByName("fonttype"); // wijzig naar button
for (var i = 0, max = radios5.length; i < max; i++) {
   radios5[i].onclick = function() {
      if (document.getElementById(this.id).checked == true) {
         if (this.id == "text-cmd-bold") {
            canvas.getActiveObject().set("fontWeight", "bold");
         }
         if (this.id == "text-cmd-italic") {
            canvas.getActiveObject().set("fontStyle", "italic");
         }
         if (this.id == "text-cmd-underline") {
            canvas.getActiveObject().set("textDecoration", "underline");
         }
         if (this.id == "text-cmd-linethrough") {
            canvas.getActiveObject().set("textDecoration", "line-through");
         }
         if (this.id == "text-cmd-overline") {
            canvas.getActiveObject().set("textDecoration", "overline");
         }
      } else {
         if (this.id == "text-cmd-bold") {
            canvas.getActiveObject().set("fontWeight", "");
         }
         if (this.id == "text-cmd-italic") {
            canvas.getActiveObject().set("fontStyle", "");
         }
         if (this.id == "text-cmd-underline") {
            canvas.getActiveObject().set("textDecoration", "");
         }
         if (this.id == "text-cmd-linethrough") {
            canvas.getActiveObject().set("textDecoration", "");
         }
         if (this.id == "text-cmd-overline") {
            canvas.getActiveObject().set("textDecoration", "");
         }
      }
      canvas.renderAll();
   }
}
// Send selected object to front or back
var selectedObject;
canvas.on('object:selected', function(event) {
   selectedObject = event.target;
});
var sendSelectedObjectBack = function() {
   canvas.sendToBack(selectedObject);
}
var sendSelectedObjectToFront = function() {
   canvas.bringToFront(selectedObject);
}
body {
   padding: 10px 10px 10px 10px;
   font-family: "HelveticaNeue";
}

canvas {
   border: 1px solid grey;
   margin: 10px 0px 0px 0px;
}

.myFile {
   position: relative;
   overflow: hidden;
   float: left;
   clear: left;
}

.myFile input[type="file"] {
   display: block;
   position: absolute;
   top: 0;
   right: 0;
   opacity: 0;
   font-size: 30px;
   filter: alpha(opacity=0);
}

.footerheader {
   margin-top: 10px;
   font-weight: bold;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<a href="index.html">Testing</a>
<br>
<br>
<label class="myFile">
   <button>+ Photo</button>&nbsp;
   <input type="file" id="file" />
</label>
<button onclick="Addtext()">+ Text</button> / Selected Object:
<button id="trash" onClick="deleteObject()">Trash</button>
<button id="forward" onclick="sendSelectedObjectToFront()">Forward</button>
<button id="back" onclick="sendSelectedObjectBack()">Back</button> /
<button onclick="refresh()">Clear All</button>
<canvas id="c" width="800" height="600"></canvas>

<div id="textControls" hidden>
   <h2>Test Text Controls</h2>
   <div id="text-wrapper" style="margin-top: 10px" ng-show="getText()">
      <div id="text-controls">
         <input type="color" id="text-color" size="10">
         <label for="font-family" style="display:inline-block">Font family:</label>
         <select id="font-family">
            <option value="arial">Arial</option>
            <option value="helvetica" selected>Helvetica</option>
            <option value="myriad pro">Myriad Pro</option>
            <option value="delicious">Delicious</option>
            <option value="verdana">Verdana</option>
            <option value="georgia">Georgia</option>
            <option value="courier">Courier</option>
            <option value="comic sans ms">Comic Sans MS</option>
            <option value="impact">Impact</option>
            <option value="monaco">Monaco</option>
            <option value="optima">Optima</option>
            <option value="hoefler text">Hoefler Text</option>
            <option value="plaster">Plaster</option>
            <option value="engagement">Engagement</option>
         </select>
         <br>
         <label for="text-align" style="display:inline-block">Text align:</label>
         <select id="text-align">
            <option value="left">Left</option>
            <option value="center">Center</option>
            <option value="right">Right</option>
            <option value="justify">Justify</option>
         </select>
         <div>
            <label for="text-bg-color">Background color:</label>
            <input type="color" id="text-bg-color" size="10">
         </div>
         <div>
            <label for="text-lines-bg-color">Background text color:</label>
            <input type="color" id="text-lines-bg-color" size="10">
         </div>
         <div>
            <label for="text-stroke-color">Stroke color:</label>
            <input type="color" id="text-stroke-color">
         </div>
         <div>
            <label for="text-stroke-width">Stroke width:</label>
            <input type="range" value="1" min="1" max="5" id="text-stroke-width">
         </div>
         <div>
            <label for="text-font-size">Font size:</label>
            <input type="range" min="1" max="120" step="1" id="text-font-size">
         </div>
         <div>
            <label for="text-line-height">Line height:</label>
            <input type="range" min="0" max="10" step="0.1" id="text-line-height">
         </div>
      </div>
      <div id="text-controls-additional">
         <input type='checkbox' name='fonttype' id="text-cmd-bold"> Bold
         <input type='checkbox' name='fonttype' id="text-cmd-italic"> Italic
         <input type='checkbox' name='fonttype' id="text-cmd-underline"> Underline
         <input type='checkbox' name='fonttype' id="text-cmd-linethrough"> Linethrough
         <input type='checkbox' name='fonttype' id="text-cmd-overline"> Overline
      </div>
      <div class="footer">
         <div class="footerheader">asdasd</div>

         <ul>
            <li>1</li>
            <li>1</li>
            <li>1</li>
         </ul>

      </div>
   </div>
</div>

关于javascript - 双击 iText 的编辑器控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44412993/

相关文章:

javascript - 如何跟踪我的数据结构?

javascript - 导航栏链接不起作用

jquery - CSS:向左浮动和向左溢出

javascript - 为什么子组件没有渲染?

javascript - 获取过去几天的名称(例如 : 7 days ago, 8 天前...)

javascript - 以 dd_mm 格式获取过去一周的日期数组

javascript - 选中的选择框中更新选项的性能

php - 在 anchor 标记内添加动态计数器编号

导航栏后不运行 HTML 代码

html - 嵌套容器中的整页宽度规则