使用Fabric.js删除所有选定的对象

时间:2017-05-13 16:44:53

标签: javascript jquery fabricjs

我使用Fabric.js,虽然我可以删除单个对象(使用" Trash"按钮),但希望能够删除任何选定的对象。目前,当我选择多个对象时,不会删除任何内容。 I've seen this answered but it's only for multiple objects;我希望使用一个按钮来删除一个或多个选定对象。提前谢谢!



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

// display/hide text controls
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;
  }
});

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,
                border: '#000',
                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: '#000',
        stroke: '#fff',
        strokeWidth: .1,
        fontSize: 45
    }));
}

// Edit Text
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);
}

// Download
var imageSaver = document.getElementById('lnkDownload');
imageSaver.addEventListener('click', saveImage, false);

function saveImage(e) {
    this.href = canvas.toDataURL({
        format: 'png',
        quality: 0.8
    });
    this.download = 'custom.png'
}

// Do some initializing stuff
fabric.Object.prototype.set({
    transparentCorners: true,
    cornerColor: '#22A7F0',
    borderColor: '#22A7F0',
    cornerSize: 12,
    padding: 5
});
&#13;
body {
  padding: 10px 10px 10px 10px;
  font-family: "HelveticaNeue";
}
canvas {
  border: 1px solid #bdc3c7;
  margin: 10px 0px 0px 0px;
/*  background-image: url("bg.png"); */
}
.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);
}
.title {
  color: black;
  text-decoration: none;
  margin-bottom: 20px;
  display: block;
}
&#13;
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Title</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" class="title">Title</a>
  <label class="myFile"><button>Add Photo</button>&nbsp;<input type="file" id="file" /></label>
  <button onclick="Addtext()">Add Text</button>&emsp;&emsp;
  <button onclick="sendSelectedObjectToFront()">Front</button>
  <button onclick="sendSelectedObjectBack()">Back</button>
  <button onClick="deleteObject()">Trash</button>&emsp;&emsp;
  <button onclick="refresh()">Clear All</button>&emsp;&emsp;
  <a id="lnkDownload" href="#"><button>Save</button></a>

  <div id="textControls" hidden>
    <div id="text-wrapper" style="margin-top: 10px" ng-show="getText()">
      <div id="text-controls">
        <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>

        <input type="color" id="text-color" size="10">

        <select id="text-align">
          <option value="left">Align Left</option>
          <option value="center">Align Center</option>
          <option value="right">Align Right</option>
          <option value="justify">Align Justify</option>
        </select>

        <label for="text-stroke-color">Stroke C:</label>
        <input type="color" id="text-stroke-color">

        <label for="text-stroke-width">Stroke W:</label>
        <input type="number" value="1" min="1" max="5" id="text-stroke-width">

        <label for="text-font-size">Font S:</label>
        <input type="number" min="12" max="120" step="1" id="text-font-size">

        <label for="text-line-height">Line H:</label>
        <input type="number" min="0" max="10" step="0.1" id="text-line-height">

        <label for="text-bg-color">BG Color:</label>
        <input type="color" id="text-bg-color" size="10">

        <label for="text-lines-bg-color">BG Text Color:</label>
        <input type="color" id="text-lines-bg-color" size="10">

        <input type='checkbox' name='fonttype' id="text-cmd-bold"> <b>B</b>
        <input type='checkbox' name='fonttype' id="text-cmd-italic"> <em>I</em>
        <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>
  </div>

  <canvas id="c" width="700" height="500"></canvas>
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.js"></script>
  <script src="fabric/fabric.min.js"></script>
  <script src="javascript.js"></script>
</body>

</html>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

您可以使用以下功能删除一个或多个选定对象...

window.deleteObject = function () {
    var activeGroup = canvas.getActiveGroup();
    if (activeGroup) {
        var activeObjects = activeGroup.getObjects();
        for (let i in activeObjects) {
            canvas.remove(activeObjects[i]);
        }
        canvas.discardActiveGroup();
        canvas.renderAll();
    } else canvas.getActiveObject().remove();
}

<强>ᴅᴇᴍᴏ

&#13;
&#13;
// Add image from local
var canvas = new fabric.Canvas('c');
// display/hide text controls
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;
    }
});
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,
                border: '#000',
                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 () {
    var activeGroup = canvas.getActiveGroup();
    if (activeGroup) {
        var activeObjects = activeGroup.getObjects();
        for (let i in activeObjects) {
            canvas.remove(activeObjects[i]);
        }
        canvas.discardActiveGroup();
        canvas.renderAll();
    } else 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: '#000',
        stroke: '#fff',
        strokeWidth: .1,
        fontSize: 45
    }));
}
// Edit Text
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);
}
// Download
var imageSaver = document.getElementById('lnkDownload');
imageSaver.addEventListener('click', saveImage, false);

function saveImage(e) {
    this.href = canvas.toDataURL({
        format: 'png',
        quality: 0.8
    });
    this.download = 'custom.png'
}
// Do some initializing stuff
fabric.Object.prototype.set({
    transparentCorners: true,
    cornerColor: '#22A7F0',
    borderColor: '#22A7F0',
    cornerSize: 12,
    padding: 5
});
&#13;
body {
    padding: 10px 10px 10px 10px;
    font-family: "HelveticaNeue";
}
canvas {
    border: 1px solid #bdc3c7;
    margin: 10px 0px 0px 0px;
    /*  background-image: url("bg.png"); */
}
.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);
}
.title {
    color: black;
    text-decoration: none;
    margin-bottom: 20px;
    display: block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.9/fabric.min.js"></script>
<a href="index.html" class="title">Title</a>
<label class="myFile">
    <button>Add Photo</button>&nbsp;
    <input type="file" id="file" />
</label>
<button onclick="Addtext()">Add Text</button>&emsp;&emsp;
<button onclick="sendSelectedObjectToFront()">Front</button>
<button onclick="sendSelectedObjectBack()">Back</button>
<button onClick="deleteObject()">Trash</button>&emsp;&emsp;
<button onclick="refresh()">Clear All</button>&emsp;&emsp;
<a id="lnkDownload" href="#">
    <button>Save</button>
</a>

<div id="textControls" hidden>
    <div id="text-wrapper" style="margin-top: 10px" ng-show="getText()">
        <div id="text-controls">
            <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>

            <input type="color" id="text-color" size="10">

            <select id="text-align">
                <option value="left">Align Left</option>
                <option value="center">Align Center</option>
                <option value="right">Align Right</option>
                <option value="justify">Align Justify</option>
            </select>

            <label for="text-stroke-color">Stroke C:</label>
            <input type="color" id="text-stroke-color">

            <label for="text-stroke-width">Stroke W:</label>
            <input type="number" value="1" min="1" max="5" id="text-stroke-width">

            <label for="text-font-size">Font S:</label>
            <input type="number" min="12" max="120" step="1" id="text-font-size">

            <label for="text-line-height">Line H:</label>
            <input type="number" min="0" max="10" step="0.1" id="text-line-height">

            <label for="text-bg-color">BG Color:</label>
            <input type="color" id="text-bg-color" size="10">

            <label for="text-lines-bg-color">BG Text Color:</label>
            <input type="color" id="text-lines-bg-color" size="10">

            <input type='checkbox' name='fonttype' id="text-cmd-bold"> <b>B</b>
            <input type='checkbox' name='fonttype' id="text-cmd-italic"> <em>I</em>
            <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>
</div>

<canvas id="c" width="700" height="500"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

对于下载第2版或更高版本后来到此处的任何人,getActiveGroup()discardActiveGroup()方法已被删除。相反,您需要使用新的ActiveSelection类来抓取所选对象。

我想在扩展程序中添加类似的功能,并在getActiveGroup()返回错误消息时不断加入。这就是我最终用来删除多个对象的内容:

deleteImage = function () {
        var selected = canvas.getActiveObjects(),
            selGroup = new fabric.ActiveSelection(selected, {
                canvas: canvas
            });
        if (selGroup) {
            if (confirm('Deleted selected image(s)?')) {
                selGroup.forEachObject(function (obj) {
                    canvas.remove(obj);
                });
            }
        } else {
            return false;
        }
        // Use discardActiveObject to remove the selection border
        canvas.discardActiveObject().renderAll();
    };

jsfiddle

More info about the changes in v2

更新:正如Durga指出的那样,您还可以使用spread operator而不是ActiveSelection类来抓取所选对象。所以,相同的功能看起来像这样:

deleteObj = function() {
 var selected = canvas.getActiveObjects();
 if (selected) {
   if (confirm('Deleted selected?')) {
     canvas.remove(...selected);
   }
   canvas.discardActiveObject().renderAll();
  }
};