fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
3 lines (2 loc) • 15.5 kB
JavaScript
import{defineProperty as t,objectSpread2 as e}from"../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{config as i}from"../config.min.mjs";import{CENTER as s,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{createCanvasElementFor as g,toDataURL as u,toBlob as p}from"../util/misc/dom.min.mjs";import{transformPoint as v,invertTransform as f}from"../util/misc/matrix.min.mjs";import{enlivenObjects as w,enlivenObjectEnlivables as b}from"../util/misc/objectEnlive.min.mjs";import{pick as O}from"../util/misc/pick.min.mjs";import{matrixToSVG as j}from"../util/misc/svgExport.min.mjs";import{toFixed as C}from"../util/misc/toFixed.min.mjs";import{isFiller as y,isTextObject as _,isPattern as x}from"../util/typeAssertions.min.mjs";import{StaticCanvasDOMManager as S}from"./DOMManagers/StaticCanvasDOMManager.min.mjs";import{staticCanvasDefaults as V}from"./StaticCanvasOptions.min.mjs";import{log as k,FabricError as R}from"../util/internals/console.min.mjs";import{getDevicePixelRatio as P}from"../env/index.min.mjs";class T 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 T.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 S(t)}add(){const t=super.add(...arguments);return arguments.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}insertAt(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),s=1;s<e;s++)i[s-1]=arguments[s];const r=super.insertAt(t,...i);return i.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&&(k("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:i=!1,backstoreOnly:s=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!i){const i=e({width:this.width,height:this.height},t);this.elements.setDimensions(i,this.getRetinaScaling()),this.hasLostContext=!0,this.width=i.width,this.height=i.height}s||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 i=t,s=[...this.viewportTransform],r=v(t,f(s));s[0]=e,s[3]=e;const n=v(r,s);s[4]+=i.x-n.x,s[5]+=i.y-n.y,this.setViewportTransform(s)}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,i=f(this.viewportTransform),s=v({x:0,y:0},i),r=v({x:t,y:e},i),n=s.min(r),o=s.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 i=this.viewportTransform,s=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(i[0],i[1],i[2],i[3],i[4],i[5]),this._renderObjects(t,e),t.restore(),this.controlsAboveOverlay||this.skipControlsDrawing||this.drawControls(t),s&&(s._set("canvas",this),s.shouldCache(),s._transformDone=!0,s.renderCache({forClipping:!0}),this.drawClipPathOnCanvas(t,s)),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 i=this.viewportTransform;t.save(),t.transform(...i),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 i=0,s=e.length;i<s;++i)e[i]&&e[i].render(t)}_renderBackgroundOrOverlay(t,e){const i=this["".concat(e,"Color")],s=this["".concat(e,"Image")],r=this.viewportTransform,n=this["".concat(e,"Vpt")];if(!i&&!s)return;const o=y(i);if(i){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?i.toLive(t):i,n&&t.transform(...r),o){t.transform(1,0,0,1,i.offsetX||0,i.offsetY||0);const e=i.gradientTransform||i.patternTransform;e&&t.transform(...e)}t.fill(),t.restore()}if(s){t.save();const{skipOffscreen:e}=this;this.skipOffscreen=n,n&&t.transform(...r),s.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 v(this.getCenterPoint(),f(this.viewportTransform))}_centerObject(t,e){t.setXY(e,s,s),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,i){const s=this.clipPath,n=s&&!s.excludeFromExport?this._toObject(s,t,i):null;return e(e(e({version:r},O(this,i)),{},{objects:this._objects.filter((t=>!t.excludeFromExport)).map((e=>this._toObject(e,t,i)))},this.__serializeBgOverlay(t,i)),n?{clipPath:n}:null)}_toObject(t,e,i){let s;this.includeDefaultValues||(s=t.includeDefaultValues,t.includeDefaultValues=!1);const r=t[e](i);return this.includeDefaultValues||(t.includeDefaultValues=!!s),r}__serializeBgOverlay(t,e){const i={},s=this.backgroundImage,r=this.overlayImage,n=this.backgroundColor,o=this.overlayColor;return y(n)?n.excludeFromExport||(i.background=n.toObject(e)):n&&(i.background=n),y(o)?o.excludeFromExport||(i.overlay=o.toObject(e)):o&&(i.overlay=o),s&&!s.excludeFromExport&&(i.backgroundImage=this._toObject(s,t,e)),r&&!r.excludeFromExport&&(i.overlayImage=this._toObject(r,t,e)),i}toSVG(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0;t.reviver=e;const i=[];return this._setSVGPreamble(i,t),this._setSVGHeader(i,t),this.clipPath&&i.push('<g clip-path="url(#'.concat(this.clipPath.clipPathId,')" >\n')),this._setSVGBgOverlayColor(i,"background"),this._setSVGBgOverlayImage(i,"backgroundImage",e),this._setSVGObjects(i,e),this.clipPath&&i.push("</g>\n"),this._setSVGBgOverlayColor(i,"overlay"),this._setSVGBgOverlayImage(i,"overlayImage",e),i.push("</svg>"),i.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 s=e.width||"".concat(this.width),n=e.height||"".concat(this.height),o=i.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(C(-t[4]/t[0],o)," ").concat(C(-t[5]/t[3],o)," ").concat(C(this.width/t[0],o)," ").concat(C(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="',s,'" ','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(y(e)){const i=this["".concat(t,"Vpt")],s=this.viewportTransform,r={isType:()=>!1,width:this.width/(i?s[0]:1),height:this.height/(i?s[3]:1)};return e.toSVG(r,{additionalTransform:i?j(s):""})}})).join("")}createSVGFontFacesMarkup(){const t=[],e={},s=i.fontPaths;this._objects.forEach((function e(i){t.push(i),o(i)&&i._objects.forEach(e)})),t.forEach((t=>{if(!_(t))return;const{styles:i,fontFamily:r}=t;!e[r]&&s[r]&&(e[r]=!0,i&&Object.values(i).forEach((t=>{Object.values(t).forEach((t=>{let{fontFamily:i=""}=t;!e[i]&&s[i]&&(e[i]=!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(s[t],"');\n\t\t}\n"))).join("");return r?'\t<style type="text/css"><![CDATA[\n'.concat(r,"]]></style>\n"):""}_setSVGObjects(t,e){this.forEachObject((i=>{i.excludeFromExport||this._setSVGObject(t,i,e)}))}_setSVGObject(t,e,i){t.push(e.toSVG(i))}_setSVGBgOverlayImage(t,e,i){const s=this[e];s&&!s.excludeFromExport&&s.toSVG&&t.push(s.toSVG(i))}_setSVGBgOverlayColor(t,e){const i=this["".concat(e,"Color")];if(i)if(y(i)){const s=i.repeat||"",r=this.width,n=this.height,o=this["".concat(e,"Vpt")]?j(f(this.viewportTransform)):"";t.push('<rect transform="'.concat(o," translate(").concat(r/2,",").concat(n/2,')" x="').concat(i.offsetX-r/2,'" y="').concat(i.offsetY-n/2,'" width="').concat("repeat-y"!==s&&"no-repeat"!==s||!x(i)?r:i.source.width,'" height="').concat("repeat-x"!==s&&"no-repeat"!==s||!x(i)?n:i.source.height,'" fill="url(#SVGID_').concat(i.id,')"></rect>\n'))}else t.push('<rect x="0" y="0" width="100%" height="100%" ','fill="',i,'"',"></rect>\n")}loadFromJSON(t,e){let{signal:i}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!t)return Promise.reject(new R("`json` is undefined"));const s="string"==typeof t?JSON.parse(t):t,{objects:r=[],backgroundImage:n,background:o,overlayImage:a,overlay:h,clipPath:c}=s,l=this.renderOnAddRemove;return this.renderOnAddRemove=!1,Promise.all([w(r,{reviver:e,signal:i}),b({backgroundImage:n,backgroundColor:o,overlayImage:a,overlayColor:h,clipPath:c},{signal:i})]).then((t=>{let[e,i]=t;return this.clear(),this.add(...e),this.set(s),this.set(i),this.renderOnAddRemove=l,this}))}clone(t){const e=this.toObject(t);return this.cloneWithoutData().loadFromJSON(e)}cloneWithoutData(){const t=g(this);return new this.constructor(t)}toDataURL(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{format:e="png",quality:i=1,multiplier:s=1,enableRetinaScaling:r=!1}=t,n=s*(r?this.getRetinaScaling():1);return u(this.toCanvasElement(n,t),e,i)}toBlob(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{format:e="png",quality:i=1,multiplier:s=1,enableRetinaScaling:r=!1}=t,n=s*(r?this.getRetinaScaling():1);return p(this.toCanvasElement(n,t),e,i)}toCanvasElement(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,{width:e,height:i,left:s,top:r,filter:n}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=(e||this.width)*t,a=(i||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]-(s||0))*t,(u[5]-(r||0))*t],v=this.enableRetinaScaling,f=g({width:o,height:a}),w=n?this._objects.filter((t=>n(t))):this._objects;return 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 i=()=>{this.destroy(),t(!0)};i.kill=e,this.__cleanupTask&&this.__cleanupTask.kill("aborted"),this.destroyed?t(!1):this.nextRenderHandle?this.__cleanupTask=i:i()}))}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(T,"ownDefaults",V);export{T as StaticCanvas};
//# sourceMappingURL=StaticCanvas.min.mjs.map