UNPKG

sunzi-fabric

Version:

made by fabric@3.2.0

122 lines (108 loc) 3.58 kB
/** * CircleBrush class * @class fabric.CircleBrush */ var ErasureGroup = fabric.util.createClass(fabric.Group, /** @lends fabric.ErasureGroup.prototype */ { /** * Width of a brush * @type Number * @default */ original: null, /** * Width of a brush * @type Number * @default */ erasedPath: null, /** * Constructor * @param {fabric.Canvas} canvas * @return {fabric.CircleBrush} Instance of a circle brush */ initialize: function(original, erasedPath, options, isAlreadyGrouped) { this.original = original; this.erasedPath = erasedPath; this.callSuper('initialize', [this.original, this.erasedPath], options, isAlreadyGrouped); }, _calcBounds: function (onlyWidthHeight) { var aX = [], aY = [], props = ['tr', 'br', 'bl', 'tl'], jLen = props.length, ignoreZoom = true; var o = this.original; o.setCoords(ignoreZoom); for (var j = 0; j < jLen; j++) { var prop = props[j]; aX.push(o.oCoords[prop].x); aY.push(o.oCoords[prop].y); } this._getBounds(aX, aY, onlyWidthHeight); } }); /* * Note1: Might not work with versions other than 3.1.0 * * Made it so that the path will be 'merged' with other objects * into a customized group and has a 'destination-out' composition */ fabric.ErasureBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.ErasureBrush.prototype */ { /** * On mouseup after drawing the path on contextTop canvas * we use the points captured to create an new fabric path object * and add it to the fabric canvas. */ _finalizeAndAddPath: function () { var ctx = this.canvas.contextTop; ctx.closePath(); if (this.decimate) { this._points = this.decimatePoints(this._points, this.decimate); } var pathData = this.convertPointsToSVGPath(this._points).join(''); if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') { // do not create 0 width/height paths, as they are // rendered inconsistently across browsers // Firefox 4, for example, renders a dot, // whereas Chrome 10 renders nothing this.canvas.requestRenderAll(); return; } // use globalCompositeOperation to 'fake' eraser var path = this.createPath(pathData); path.globalCompositeOperation = 'destination-out'; path.selectable = false; path.evented = false; path.absolutePositioned = true; // grab all the objects that intersects with the path var objects = this.canvas.getObjects().filter(function(obj) { // if (obj instanceof fabric.Textbox) return false; // if (obj instanceof fabric.IText) return false; if (!obj.intersectsWithObject(path)) return false; return true; }.bind(this)); if (objects.length > 0) { // merge those objects into a group var mergedGroup = new fabric.Group(objects); var newPath = new ErasureGroup(mergedGroup, path); var left = newPath.left; var top = newPath.top; // convert it into a dataURL, then back to a fabric image var newData = newPath.toDataURL({ withoutTransform: true }); fabric.Image.fromURL(newData, function(fabricImage) { fabricImage.set({ left: left, top: top, }); // remove the old objects then add the new image this.canvas.remove.apply(this.canvas, objects); this.canvas.add(fabricImage); }.bind(this)); } this.canvas.clearContext(this.canvas.contextTop); this.canvas.renderAll(); this._resetShadow(); }, });