fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
3 lines (2 loc) • 15.3 kB
JavaScript
import{defineProperty as t,objectSpread2 as e}from"../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{config as s}from"../config.min.mjs";import{CENTER as i,VERSION as r}from"../constants.min.mjs";import{createCollectionMixin as n,isCollection as o}from"../Collection.min.mjs";import{CommonMethods as a}from"../CommonMethods.min.mjs";import{Point as h}from"../Point.min.mjs";import{requestAnimFrame as c,cancelAnimFrame as l}from"../util/animation/AnimationFrameProvider.min.mjs";import{runningAnimations as d}from"../util/animation/AnimationRegistry.min.mjs";import{uid as m}from"../util/internals/uid.min.mjs";import{createCanvasElement as g,toDataURL as u}from"../util/misc/dom.min.mjs";import{transformPoint as p,invertTransform as v}from"../util/misc/matrix.min.mjs";import{enlivenObjects as f,enlivenObjectEnlivables as w}from"../util/misc/objectEnlive.min.mjs";import{pick as b}from"../util/misc/pick.min.mjs";import{matrixToSVG as O}from"../util/misc/svgParsing.min.mjs";import{toFixed as j}from"../util/misc/toFixed.min.mjs";import{isFiller as C,isTextObject as _,isPattern as y}from"../util/typeAssertions.min.mjs";import{StaticCanvasDOMManager as x}from"./DOMManagers/StaticCanvasDOMManager.min.mjs";import{staticCanvasDefaults as S}from"./StaticCanvasOptions.min.mjs";import{log as V,FabricError as k}from"../util/internals/console.min.mjs";import{getDevicePixelRatio as P}from"../env/index.min.mjs";class R extends(n(a)){get lowerCanvasEl(){var t;return null===(t=this.elements.lower)||void 0===t?void 0:t.el}get contextContainer(){var t;return null===(t=this.elements.lower)||void 0===t?void 0:t.ctx}static getDefaults(){return R.ownDefaults}constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,this.constructor.getDefaults()),this.set(e),this.initElements(t),this._setDimensionsImpl({width:this.width||this.elements.lower.el.width||0,height:this.height||this.elements.lower.el.height||0}),this.skipControlsDrawing=!1,this.viewportTransform=[...this.viewportTransform],this.calcViewportBoundaries()}initElements(t){this.elements=new x(t)}add(){const t=super.add(...arguments);return arguments.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}insertAt(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;i<e;i++)s[i-1]=arguments[i];const r=super.insertAt(t,...s);return s.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),r}remove(){const t=super.remove(...arguments);return t.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}_onObjectAdded(t){t.canvas&&t.canvas!==this&&(V("warn","Canvas is trying to add an object that belongs to a different canvas.\nResulting to default behavior: removing object from previous canvas and adding to new canvas"),t.canvas.remove(t)),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added",{target:this})}_onObjectRemoved(t){t._set("canvas",void 0),this.fire("object:removed",{target:t}),t.fire("removed",{target:this})}_onStackOrderChanged(){this.renderOnAddRemove&&this.requestRenderAll()}getRetinaScaling(){return this.enableRetinaScaling?P():1}calcOffset(){return this._offset=this.elements.calcOffset()}getWidth(){return this.width}getHeight(){return this.height}setWidth(t,e){return this.setDimensions({width:t},e)}setHeight(t,e){return this.setDimensions({height:t},e)}_setDimensionsImpl(t){let{cssOnly:s=!1,backstoreOnly:i=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!s){const s=e({width:this.width,height:this.height},t);this.elements.setDimensions(s,this.getRetinaScaling()),this.hasLostContext=!0,this.width=s.width,this.height=s.height}i||this.elements.setCSSDimensions(t),this.calcOffset()}setDimensions(t,e){this._setDimensionsImpl(t,e),e&&e.cssOnly||this.requestRenderAll()}getZoom(){return this.viewportTransform[0]}setViewportTransform(t){this.viewportTransform=t,this.calcViewportBoundaries(),this.renderOnAddRemove&&this.requestRenderAll()}zoomToPoint(t,e){const s=t,i=[...this.viewportTransform],r=p(t,v(i));i[0]=e,i[3]=e;const n=p(r,i);i[4]+=s.x-n.x,i[5]+=s.y-n.y,this.setViewportTransform(i)}setZoom(t){this.zoomToPoint(new h(0,0),t)}absolutePan(t){const e=[...this.viewportTransform];return e[4]=-t.x,e[5]=-t.y,this.setViewportTransform(e)}relativePan(t){return this.absolutePan(new h(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))}getElement(){return this.elements.lower.el}clearContext(t){t.clearRect(0,0,this.width,this.height)}getContext(){return this.elements.lower.ctx}clear(){this.remove(...this.getObjects()),this.backgroundImage=void 0,this.overlayImage=void 0,this.backgroundColor="",this.overlayColor="",this.clearContext(this.getContext()),this.fire("canvas:cleared"),this.renderOnAddRemove&&this.requestRenderAll()}renderAll(){this.cancelRequestedRender(),this.destroyed||this.renderCanvas(this.getContext(),this._objects)}renderAndReset(){this.nextRenderHandle=0,this.renderAll()}requestRenderAll(){this.nextRenderHandle||this.disposed||this.destroyed||(this.nextRenderHandle=c((()=>this.renderAndReset())))}calcViewportBoundaries(){const t=this.width,e=this.height,s=v(this.viewportTransform),i=p({x:0,y:0},s),r=p({x:t,y:e},s),n=i.min(r),o=i.max(r);return this.vptCoords={tl:n,tr:new h(o.x,n.y),bl:new h(n.x,o.y),br:o}}cancelRequestedRender(){this.nextRenderHandle&&(l(this.nextRenderHandle),this.nextRenderHandle=0)}drawControls(t){}renderCanvas(t,e){if(this.destroyed)return;const s=this.viewportTransform,i=this.clipPath;this.calcViewportBoundaries(),this.clearContext(t),t.imageSmoothingEnabled=this.imageSmoothingEnabled,t.patternQuality="best",this.fire("before:render",{ctx:t}),this._renderBackground(t),t.save(),t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),this._renderObjects(t,e),t.restore(),this.controlsAboveOverlay||this.skipControlsDrawing||this.drawControls(t),i&&(i._set("canvas",this),i.shouldCache(),i._transformDone=!0,i.renderCache({forClipping:!0}),this.drawClipPathOnCanvas(t,i)),this._renderOverlay(t),this.controlsAboveOverlay&&!this.skipControlsDrawing&&this.drawControls(t),this.fire("after:render",{ctx:t}),this.__cleanupTask&&(this.__cleanupTask(),this.__cleanupTask=void 0)}drawClipPathOnCanvas(t,e){const s=this.viewportTransform;t.save(),t.transform(...s),t.globalCompositeOperation="destination-in",e.transform(t),t.scale(1/e.zoomX,1/e.zoomY),t.drawImage(e._cacheCanvas,-e.cacheTranslationX,-e.cacheTranslationY),t.restore()}_renderObjects(t,e){for(let s=0,i=e.length;s<i;++s)e[s]&&e[s].render(t)}_renderBackgroundOrOverlay(t,e){const s=this["".concat(e,"Color")],i=this["".concat(e,"Image")],r=this.viewportTransform,n=this["".concat(e,"Vpt")];if(!s&&!i)return;const o=C(s);if(s){if(t.save(),t.beginPath(),t.moveTo(0,0),t.lineTo(this.width,0),t.lineTo(this.width,this.height),t.lineTo(0,this.height),t.closePath(),t.fillStyle=o?s.toLive(t):s,n&&t.transform(...r),o){t.transform(1,0,0,1,s.offsetX||0,s.offsetY||0);const e=s.gradientTransform||s.patternTransform;e&&t.transform(...e)}t.fill(),t.restore()}if(i){t.save();const{skipOffscreen:e}=this;this.skipOffscreen=n,n&&t.transform(...r),i.render(t),this.skipOffscreen=e,t.restore()}}_renderBackground(t){this._renderBackgroundOrOverlay(t,"background")}_renderOverlay(t){this._renderBackgroundOrOverlay(t,"overlay")}getCenter(){return{top:this.height/2,left:this.width/2}}getCenterPoint(){return new h(this.width/2,this.height/2)}centerObjectH(t){return this._centerObject(t,new h(this.getCenterPoint().x,t.getCenterPoint().y))}centerObjectV(t){return this._centerObject(t,new h(t.getCenterPoint().x,this.getCenterPoint().y))}centerObject(t){return this._centerObject(t,this.getCenterPoint())}viewportCenterObject(t){return this._centerObject(t,this.getVpCenter())}viewportCenterObjectH(t){return this._centerObject(t,new h(this.getVpCenter().x,t.getCenterPoint().y))}viewportCenterObjectV(t){return this._centerObject(t,new h(t.getCenterPoint().x,this.getVpCenter().y))}getVpCenter(){return p(this.getCenterPoint(),v(this.viewportTransform))}_centerObject(t,e){t.setXY(e,i,i),t.setCoords(),this.renderOnAddRemove&&this.requestRenderAll()}toDatalessJSON(t){return this.toDatalessObject(t)}toObject(t){return this._toObjectMethod("toObject",t)}toJSON(){return this.toObject()}toDatalessObject(t){return this._toObjectMethod("toDatalessObject",t)}_toObjectMethod(t,s){const i=this.clipPath,n=i&&!i.excludeFromExport?this._toObject(i,t,s):null;return e(e(e({version:r},b(this,s)),{},{objects:this._objects.filter((t=>!t.excludeFromExport)).map((e=>this._toObject(e,t,s)))},this.__serializeBgOverlay(t,s)),n?{clipPath:n}:null)}_toObject(t,e,s){let i;this.includeDefaultValues||(i=t.includeDefaultValues,t.includeDefaultValues=!1);const r=t[e](s);return this.includeDefaultValues||(t.includeDefaultValues=!!i),r}__serializeBgOverlay(t,e){const s={},i=this.backgroundImage,r=this.overlayImage,n=this.backgroundColor,o=this.overlayColor;return C(n)?n.excludeFromExport||(s.background=n.toObject(e)):n&&(s.background=n),C(o)?o.excludeFromExport||(s.overlay=o.toObject(e)):o&&(s.overlay=o),i&&!i.excludeFromExport&&(s.backgroundImage=this._toObject(i,t,e)),r&&!r.excludeFromExport&&(s.overlayImage=this._toObject(r,t,e)),s}toSVG(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0;t.reviver=e;const s=[];return this._setSVGPreamble(s,t),this._setSVGHeader(s,t),this.clipPath&&s.push('<g clip-path="url(#'.concat(this.clipPath.clipPathId,')" >\n')),this._setSVGBgOverlayColor(s,"background"),this._setSVGBgOverlayImage(s,"backgroundImage",e),this._setSVGObjects(s,e),this.clipPath&&s.push("</g>\n"),this._setSVGBgOverlayColor(s,"overlay"),this._setSVGBgOverlayImage(s,"overlayImage",e),s.push("</svg>"),s.join("")}_setSVGPreamble(t,e){e.suppressPreamble||t.push('<?xml version="1.0" encoding="',e.encoding||"UTF-8",'" standalone="no" ?>\n','<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ','"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')}_setSVGHeader(t,e){const i=e.width||"".concat(this.width),n=e.height||"".concat(this.height),o=s.NUM_FRACTION_DIGITS,a=e.viewBox;let h;if(a)h='viewBox="'.concat(a.x," ").concat(a.y," ").concat(a.width," ").concat(a.height,'" ');else if(this.svgViewportTransformation){const t=this.viewportTransform;h='viewBox="'.concat(j(-t[4]/t[0],o)," ").concat(j(-t[5]/t[3],o)," ").concat(j(this.width/t[0],o)," ").concat(j(this.height/t[3],o),'" ')}else h='viewBox="0 0 '.concat(this.width," ").concat(this.height,'" ');t.push("<svg ",'xmlns="http://www.w3.org/2000/svg" ','xmlns:xlink="http://www.w3.org/1999/xlink" ','version="1.1" ','width="',i,'" ','height="',n,'" ',h,'xml:space="preserve">\n',"<desc>Created with Fabric.js ",r,"</desc>\n","<defs>\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),this.createSVGClipPathMarkup(e),"</defs>\n")}createSVGClipPathMarkup(t){const e=this.clipPath;return e?(e.clipPathId="CLIPPATH_".concat(m()),'<clipPath id="'.concat(e.clipPathId,'" >\n').concat(e.toClipPathSVG(t.reviver),"</clipPath>\n")):""}createSVGRefElementsMarkup(){return["background","overlay"].map((t=>{const e=this["".concat(t,"Color")];if(C(e)){const s=this["".concat(t,"Vpt")],i=this.viewportTransform,r={isType:()=>!1,width:this.width/(s?i[0]:1),height:this.height/(s?i[3]:1)};return e.toSVG(r,{additionalTransform:s?O(i):""})}})).join("")}createSVGFontFacesMarkup(){const t=[],e={},i=s.fontPaths;this._objects.forEach((function e(s){t.push(s),o(s)&&s._objects.forEach(e)})),t.forEach((t=>{if(!_(t))return;const{styles:s,fontFamily:r}=t;!e[r]&&i[r]&&(e[r]=!0,s&&Object.values(s).forEach((t=>{Object.values(t).forEach((t=>{let{fontFamily:s=""}=t;!e[s]&&i[s]&&(e[s]=!0)}))})))}));const r=Object.keys(e).map((t=>"\t\t@font-face {\n\t\t\tfont-family: '".concat(t,"';\n\t\t\tsrc: url('").concat(i[t],"');\n\t\t}\n"))).join("");return r?'\t<style type="text/css"><![CDATA[\n'.concat(r,"]]></style>\n"):""}_setSVGObjects(t,e){this.forEachObject((s=>{s.excludeFromExport||this._setSVGObject(t,s,e)}))}_setSVGObject(t,e,s){t.push(e.toSVG(s))}_setSVGBgOverlayImage(t,e,s){const i=this[e];i&&!i.excludeFromExport&&i.toSVG&&t.push(i.toSVG(s))}_setSVGBgOverlayColor(t,e){const s=this["".concat(e,"Color")];if(s)if(C(s)){const i=s.repeat||"",r=this.width,n=this.height,o=this["".concat(e,"Vpt")]?O(v(this.viewportTransform)):"";t.push('<rect transform="'.concat(o," translate(").concat(r/2,",").concat(n/2,')" x="').concat(s.offsetX-r/2,'" y="').concat(s.offsetY-n/2,'" width="').concat("repeat-y"!==i&&"no-repeat"!==i||!y(s)?r:s.source.width,'" height="').concat("repeat-x"!==i&&"no-repeat"!==i||!y(s)?n:s.source.height,'" fill="url(#SVGID_').concat(s.id,')"></rect>\n'))}else t.push('<rect x="0" y="0" width="100%" height="100%" ','fill="',s,'"',"></rect>\n")}loadFromJSON(t,e){let{signal:s}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!t)return Promise.reject(new k("`json` is undefined"));const i="string"==typeof t?JSON.parse(t):t,{objects:r=[],backgroundImage:n,background:o,overlayImage:a,overlay:h,clipPath:c}=i,l=this.renderOnAddRemove;return this.renderOnAddRemove=!1,Promise.all([f(r,{reviver:e,signal:s}),w({backgroundImage:n,backgroundColor:o,overlayImage:a,overlayColor:h,clipPath:c},{signal:s})]).then((t=>{let[e,s]=t;return this.clear(),this.add(...e),this.set(i),this.set(s),this.renderOnAddRemove=l,this}))}clone(t){const e=this.toObject(t);return this.cloneWithoutData().loadFromJSON(e)}cloneWithoutData(){const t=g();return t.width=this.width,t.height=this.height,new this.constructor(t)}toDataURL(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{format:e="png",quality:s=1,multiplier:i=1,enableRetinaScaling:r=!1}=t,n=i*(r?this.getRetinaScaling():1);return u(this.toCanvasElement(n,t),e,s)}toCanvasElement(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,{width:e,height:s,left:i,top:r,filter:n}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=(e||this.width)*t,a=(s||this.height)*t,h=this.getZoom(),c=this.width,l=this.height,d=this.skipControlsDrawing,m=h*t,u=this.viewportTransform,p=[m,0,0,m,(u[4]-(i||0))*t,(u[5]-(r||0))*t],v=this.enableRetinaScaling,f=g(),w=n?this._objects.filter((t=>n(t))):this._objects;return f.width=o,f.height=a,this.enableRetinaScaling=!1,this.viewportTransform=p,this.width=o,this.height=a,this.skipControlsDrawing=!0,this.calcViewportBoundaries(),this.renderCanvas(f.getContext("2d"),w),this.viewportTransform=u,this.width=c,this.height=l,this.calcViewportBoundaries(),this.enableRetinaScaling=v,this.skipControlsDrawing=d,f}dispose(){return!this.disposed&&this.elements.cleanupDOM({width:this.width,height:this.height}),d.cancelByCanvas(this),this.disposed=!0,new Promise(((t,e)=>{const s=()=>{this.destroy(),t(!0)};s.kill=e,this.__cleanupTask&&this.__cleanupTask.kill("aborted"),this.destroyed?t(!1):this.nextRenderHandle?this.__cleanupTask=s:s()}))}destroy(){this.destroyed=!0,this.cancelRequestedRender(),this.forEachObject((t=>t.dispose())),this._objects=[],this.backgroundImage&&this.backgroundImage.dispose(),this.backgroundImage=void 0,this.overlayImage&&this.overlayImage.dispose(),this.overlayImage=void 0,this.elements.dispose()}toString(){return"#<Canvas (".concat(this.complexity(),"): { objects: ").concat(this._objects.length," }>")}}t(R,"ownDefaults",S);export{R as StaticCanvas};
//# sourceMappingURL=StaticCanvas.min.mjs.map