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