javascript - 使用 Fabric.js 显示适用的控件

标签 javascript jquery fabricjs

使用fabric.js,我如何仅在选择文本时隐藏/显示控件,例如文本控件?现在我有一个按钮可以让人们插入文本和文本编辑选项,但是我并不总是希望显示它。理想情况下,选择时它会是一个弹出窗口。

现在,我的代码是:

// Add image from local
var canvas = new fabric.Canvas('c');
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;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Testing</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>

<body>
  <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 onClick="deleteObject()">Trash</button>
  <button onclick="sendSelectedObjectToFront()">Forward</button>
  <button onclick="sendSelectedObjectBack()">Back</button> /
  <button onclick="refresh()">Clear All</button>
  <canvas id="c" width="800" height="600"></canvas>

  <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>
      <p>
        <ul>
          <li>1</li>
          <li>1</li>
          <li>1</li>
        </ul>
      </p>

    <script src="fabric/fabric.min.js"></script>
    <script src="javascript.js"></script>
</body>
</html>

最佳答案

以下是实现这一目标的方法...

  • 使用 div 元素包裹文本控件,并设置 hidden 属性使其默认隐藏
  • 添加以下鼠标事件,使控件分别在选择和取消选择文本时显示和隐藏
<小时/>
canvas.on('object:selected', function(e) {
  if (e.target.type === 'i-text') {
    document.getElementById('textControls').hidden = false;
  }
});
canvas.on('before:selection:cleared', function(e) {
  if (e.target.type === 'i-text') {
    document.getElementById('textControls').hidden = true;
  }
});
<小时/>

ᴅᴇᴍᴏ

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

// display/hide controls
canvas.on('object:selected', function(e) {
   document.getElementById('trash').hidden = false;
   document.getElementById('forward').hidden = false;
   document.getElementById('back').hidden = false;
   if (e.target.type === '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()" hidden>Trash</button>
<button id="forward" onclick="sendSelectedObjectToFront()" hidden>Forward</button>
<button id="back" onclick="sendSelectedObjectBack()" hidden>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 - 使用 Fabric.js 显示适用的控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43924988/

相关文章:

javascript - FabricJs 多个 Canvas 多次加载同一图像

javascript - 如何让2个异步API调用相继执行

php - 出站联属营销链接 : Nth click goes to house

javascript - 在 jQuery UI 中获取 ul 和 li 值可在拖放时排序

javascript - Ajax 和 MySql 插入、检查和检索

android - 输入焦点时 JQuery Mobile 不适合屏幕

javascript - 如何设置带 Angular 文本阴影?

javascript - 以编程方式从坐标中选择 Fabricjs Canvas 中的对象

javascript - 我想在谷歌浏览器扩展中访问下载的文件(在我的例子中是 csv 文件)并获取其中的内容

javascript - 在 php 中嵌入 javascript 中的 php