polotno 4.2.2 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/canvas/apply-filters.d.ts +11 -0
- package/canvas/apply-filters.js +1 -1
- package/canvas/gif-element.js +1 -1
- package/canvas/image-element.js +1 -1
- package/canvas/text-element.js +1 -1
- package/canvas/tooltip.js +1 -1
- package/canvas/use-filtered-source.d.ts +2 -0
- package/canvas/use-filtered-source.js +1 -0
- package/canvas/use-mediabunny-video.js +1 -1
- package/canvas/video-element.d.ts +1 -1
- package/canvas/video-element.js +1 -1
- package/model/group-model.d.ts +1 -0
- package/model/group-model.js +1 -1
- package/model/page-model.d.ts +1 -0
- package/model/store.d.ts +9 -0
- package/model/store.js +1 -1
- package/model/text-model.d.ts +1 -0
- package/model/text-model.js +1 -1
- package/package.json +3 -3
- package/pages-timeline/page-preview.js +1 -1
- package/polotno.bundle.js +125 -125
- package/side-panel/effects-panel.js +1 -1
- package/utils/clipboard.d.ts +2 -0
- package/utils/errors.d.ts +7 -0
- package/utils/errors.js +1 -0
- package/utils/fonts.js +1 -1
- package/utils/l10n.d.ts +4 -0
- package/utils/l10n.js +1 -1
- package/utils/loader.d.ts +3 -2
- package/utils/loader.js +1 -1
- package/utils/text-html.d.ts +1 -0
- package/utils/text-html.js +1 -1
- package/utils/text-types.d.ts +2 -0
- package/utils/text-types.js +1 -1
- package/utils/to-html.js +1 -1
- package/utils/to-svg.js +1 -1
- package/utils/validate-key.js +1 -1
- package/utils/video.js +1 -1
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
import Konva from 'konva';
|
|
2
2
|
import { ShapeType } from '../model/shape-model.js';
|
|
3
|
+
import { Filter } from 'konva/lib/Node';
|
|
4
|
+
export declare function getFilterAttrs(element: ShapeType): {
|
|
5
|
+
filters: Filter[];
|
|
6
|
+
brightness?: number;
|
|
7
|
+
blurRadius?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function hasActiveFilters(element: ShapeType): boolean;
|
|
10
|
+
export declare function getEffectiveBlurRadius(blurRadius: number, width: number, height: number): number;
|
|
11
|
+
export declare function getElementBlurRadius(element: ShapeType): number;
|
|
12
|
+
export declare function applyFiltersToCanvas(canvas: HTMLCanvasElement, element: ShapeType): void;
|
|
13
|
+
export declare function getFiltersDepsKey(element: ShapeType): string;
|
|
3
14
|
export declare function applyFilter(node: Konva.Node, element: ShapeType): void;
|
package/canvas/apply-filters.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"konva";import{isAlive as a}from"mobx-state-tree";const
|
|
1
|
+
import t from"konva";import{isAlive as a}from"mobx-state-tree";const e={warm:t=>a=>{const e=a.data;t=Math.max(0,Math.min(1,t));for(let n=0;n<e.length;n+=4){e[n]=Math.min(e[n]+30*t,255),e[n+1]=Math.min(e[n+1]+15*t,255)}return a},cold:t=>a=>{const e=a.data;t=Math.max(0,Math.min(1,t));for(let n=0;n<e.length;n+=4){e[n]=Math.min(e[n]-15*t,255),e[n+1]=Math.min(e[n+1]-10*t,255),e[n+2]=Math.min(e[n+2]+15*t,255)}return a},natural:t=>a=>{const e=a.data;t=Math.max(0,Math.min(1,t));for(let n=0;n<e.length;n+=4){e[n]=Math.min(e[n]*(1+.1*t),255),e[n+1]=Math.min(e[n+1]*(1+.1*t),255),e[n+2]=Math.min(e[n+2]*(1+.1*t),255);const a=(e[n]+e[n+1]+e[n+2])/3;e[n]=Math.min((e[n]-a)*(1+.2*t)+a,255),e[n+1]=Math.min((e[n+1]-a)*(1+.2*t)+a,255),e[n+2]=Math.min((e[n+2]-a)*(1+.2*t)+a,255)}return a},temperature:t=>a=>{const e=a.data;t=Math.max(-1,Math.min(1,t));for(let n=0;n<e.length;n+=4){const a=e[n],i=(e[n+1],e[n+2]);e[n]=Math.min(Math.max(a+15*t,0),255),e[n+2]=Math.min(Math.max(i-15*t,0),255)}return a},contrast:t=>a=>{const e=a.data,n=100*(t=Math.max(-1,Math.min(1,t))),i=259*(n+255)/(255*(259-n));for(let t=0;t<e.length;t+=4){e[t]=Math.min(Math.max(i*(e[t]-128)+128,0),255),e[t+1]=Math.min(Math.max(i*(e[t+1]-128)+128,0),255),e[t+2]=Math.min(Math.max(i*(e[t+2]-128)+128,0),255)}return a},shadows:t=>a=>{const e=a.data;t=Math.max(-1,Math.min(1,t));for(let n=0;n<e.length;n+=4){const a=(e[n]+e[n+1]+e[n+2])/3;if(a<128){const i=1+t*(1-a/128)*2;e[n]=Math.min(Math.max(e[n]*i,0),255),e[n+1]=Math.min(Math.max(e[n+1]*i,0),255),e[n+2]=Math.min(Math.max(e[n+2]*i,0),255)}}return a},white:t=>a=>{const e=a.data;t=Math.max(-1,Math.min(1,t));for(let n=0;n<e.length;n+=4){const a=e[n],i=e[n+1],r=e[n+2],h=(a+i+r)/3;if(h>128){const s=1+t*((h-128)/127);e[n]=Math.min(Math.max(a*s,0),255),e[n+1]=Math.min(Math.max(i*s,0),255),e[n+2]=Math.min(Math.max(r*s,0),255)}}return a},black:t=>a=>{const e=a.data;t=Math.max(-1,Math.min(1,t));for(let n=0;n<e.length;n+=4){const a=e[n],i=e[n+1],r=e[n+2],h=(a+i+r)/3;if(h<128){const s=1+t*((128-h)/128);e[n]=Math.min(Math.max(a*s,0),255),e[n+1]=Math.min(Math.max(i*s,0),255),e[n+2]=Math.min(Math.max(r*s,0),255)}}return a},vibrance:t=>a=>{const e=a.data;t=Math.max(-1,Math.min(1,t));for(let n=0;n<e.length;n+=4){const a=e[n],i=e[n+1],r=e[n+2],h=Math.max(a,i,r),s=t<0?(1-(0===h?0:(h-(a+i+r)/3)/h))*t*1.5:.5*t;e[n]=Math.min(Math.max(a-(h-a)*s,0),255),e[n+1]=Math.min(Math.max(i-(h-i)*s,0),255),e[n+2]=Math.min(Math.max(r-(h-r)*s,0),255)}return a},saturation:t=>a=>{const e=a.data;t=Math.max(-1,Math.min(1,t));for(let n=0;n<e.length;n+=4){const a=e[n],i=e[n+1],r=e[n+2],h=.2126*a+.7152*i+.0722*r;e[n]=Math.min(Math.max(h+(a-h)*(1+t),0),255),e[n+1]=Math.min(Math.max(h+(i-h)*(1+t),0),255),e[n+2]=Math.min(Math.max(h+(r-h)*(1+t),0),255)}return a}};export function getFilterAttrs(a){const n={filters:[]};return a.brightnessEnabled&&(n.filters.push(t.Filters.Brighten),n.brightness=a.brightness),a.blurEnabled&&(n.filters.push(t.Filters.Blur),n.blurRadius=a.blurRadius),a.sepiaEnabled&&n.filters.push(t.Filters.Sepia),a.grayscaleEnabled&&n.filters.push(t.Filters.Grayscale),a.filters.forEach((t,a)=>{const i=e[a];i&&n.filters.push(i(t.intensity))}),n}export function hasActiveFilters(t){if(t.brightnessEnabled||t.blurEnabled||t.sepiaEnabled||t.grayscaleEnabled){return!0}for(const a of t.filters.keys()){if(e[a]){return!0}}return!1}export function getEffectiveBlurRadius(t,a,e){return t/1e3*Math.min(a,e)}export function getElementBlurRadius(t){const a=t.cropWidth;return void 0===a?t.blurRadius:getEffectiveBlurRadius(t.blurRadius,t.width/(a||1),t.height/(t.cropHeight||1))}export function applyFiltersToCanvas(t,e){if(!a(e)){return}const n=getFilterAttrs(e);if(!n.filters.length||!t.width||!t.height){return}const i=t.getContext("2d");if(!i){return}const r=i.getImageData(0,0,t.width,t.height),h={brightness:()=>n.brightness,blurRadius:()=>{var a;return getEffectiveBlurRadius(null!==(a=n.blurRadius)&&void 0!==a?a:0,t.width,t.height)}};n.filters.forEach(t=>{"function"==typeof t&&t.call(h,r)}),i.putImageData(r,0,0)}export function getFiltersDepsKey(t){if(!a(t)){return""}const e=[];return t.filters.forEach((t,a)=>{e.push(a+":"+t.intensity)}),[t.brightnessEnabled&&t.brightness,t.blurEnabled&&t.blurRadius,t.sepiaEnabled,t.grayscaleEnabled,...e].join("|")}export function applyFilter(t,e){var n;if(!t||!a(e)){return}const i=getFilterAttrs(e),r={};e.blurEnabled&&"text"===e.type&&e.lineHeight<1&&(r.offset=e.fontSize),t.setAttrs(i),i.filters.length?t.cache(Object.assign(Object.assign({},r),{pixelRatio:e.store._elementsPixelRatio})):t.clearCache(),null===(n=t.getLayer())||void 0===n||n.batchDraw()}
|
package/canvas/gif-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as
|
|
1
|
+
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{nodeAutorun as a}from"../utils/mobx.js";import{Image as n,Group as s,Rect as h,Arc as d,Text as l}from"react-konva";import{ROLES as c}from"../model/store.js";import g from"konva";import{parseGIF as m,decompressFrames as f}from"gifuct-js";import{useCornerRadiusAndCrop as u}from"./video-element.js";import{useImageLoader as p}from"./image-element.js";import{useWorkspaceStyle as w}from"./workspace-style.js";import{useFilteredSource as x}from"./use-filtered-source.js";import{useFadeIn as y}from"./use-fadein.js";import{isTouchDevice as E}from"../utils/screen.js";import{useEvent as v}from"../hooks/use-event.js";function b(t,e,r){const i=e.getContext("2d"),o=r.getContext("2d");if(!i||!o){return}2===t.disposalType&&i.clearRect(0,0,e.width,e.height),r.width=t.width,r.height=t.height;const a=o.createImageData(t.width,t.height);a.data.set(t.patch),o.putImageData(a,0,0),i.drawImage(r,t.left,t.top)}const S=o(({element:r})=>{const o=Math.min(30,r.width/4,r.height/4),a=i.useRef(null);i.useEffect(()=>{const t=a.current;if(!t){return}const e=new g.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}},[]);const{mediaLoadingStyle:n}=w();return e(s,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(h,{width:r.width,height:r.height,fill:n.fill}),t(d,{ref:a,x:r.width/2,y:r.height/2,fill:n.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),I=o(({element:r})=>{const{mediaErrorStyle:i}=w(),o=Math.max(10,Math.min(30,r.width/22));return e(s,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(h,{width:r.width,height:r.height,fill:i.fill}),t(l,{text:"Cannot load the GIF...",fontSize:o,width:r.width,height:r.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});export const GifElement=o(({element:o,store:s})=>{var d,l;const[w,j]=i.useState(!1),M=o.isSelected,R=i.useRef(null),C=i.useRef(void 0),[T,z,O,D]=function(t){const[e,r]=i.useState([]),[o,a]=i.useState(0),[n,s]=i.useState("loading"),[h,d]=i.useState({width:0,height:0});return i.useEffect(()=>{(async()=>{try{const e=await fetch(t),i=await e.arrayBuffer(),o=m(i),n=f(o,!0),h=o.lsd.width,l=o.lsd.height;d({width:h,height:l});const c=n.map(t=>({patch:new Uint8ClampedArray(t.patch),delay:t.delay,width:t.dims.width,height:t.dims.height,left:t.dims.left,top:t.dims.top,disposalType:t.disposalType})),g=c.reduce((t,e)=>t+e.delay,0);r(c),a(g),s("loaded")}catch(e){console.error("Failed to load GIF:",e),s("failed")}})()},[t]),[e,o,h,n]}(o.src);p(D,o.src,o.id),i.useEffect(()=>(C.current=document.createElement("canvas"),()=>{C.current&&g.Util.releaseCanvas(C.current)}),[]),i.useEffect(()=>{if("loaded"===D&&C.current&&(C.current.width=O.width,C.current.height=O.height,T.length>0)){const t=C.current.getContext("2d");if(t){t.clearRect(0,0,O.width,O.height);const e=document.createElement("canvas");b(T[0],C.current,e)}}},[O,D,T]),i.useEffect(()=>{var t;if(!T.length||!C.current){return}const e=C.current;e.width=O.width,e.height=O.height;const r=document.createElement("canvas"),i=e.getContext("2d");i&&i.clearRect(0,0,e.width,e.height);let n=-1;b(T[0],e,r),U(),n=0;const h=t=>{const i=(t=>{const e=t%z;let r=0;for(let i=0;i<T.length;i++){if(r+=T[i].delay,r>e){return i}}return 0})(t);i!==n&&(b(T[i],e,r),U(),R.current.getLayer().draw(),n=i)};if(s.isPlaying||(null===(t=o.page)||void 0===t?void 0:t._exportingOrRendering)){return a(o,()=>{h(s.currentTime-o.page.startTime)})}{const t=window.setInterval(()=>{h(s.currentTime||performance.now())},16);return()=>{clearInterval(t)}}},[s.isPlaying,T,z,null===(d=o.page)||void 0===d?void 0:d._exportingOrRendering]),i.useEffect(()=>{z&&s.history.ignore(()=>{o.set({duration:z})})},[z]);let{cropX:X,cropY:Y,cropWidth:k,cropHeight:F}=o;"loaded"!==D&&(X=Y=0,k=F=1);const A={x:O.width*X,y:O.height*Y,width:O.width*k,height:O.height*F},_=null!==(l=o.cornerRadius)&&void 0!==l?l:0,[B,G]=x(o,C.current),[L,P]=u(o,B,A,s._elementsPixelRatio,_,w||o._cropModeEnabled),U=v(()=>{G(),P()}),W="loading"===D,H="failed"===D,N=W||H?0:o.a.opacity;y(R,N);const q=o.selectable||s.role===c.ADMIN,J=E();return e(r,{children:[W&&t(S,{element:o}),H&&t(I,{element:o}),t(n,{ref:R,name:"element",id:o.id,image:L,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:N,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:A,listening:q,draggable:J?o.draggable&&M:o.draggable,preventDefault:!J||M,hideInExport:!o.showInExport,onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{o.set({x:t.target.x(),y:t.target.y()})},onTransformStart:()=>j(!0),onTransform:t=>{const e=t.currentTarget,r=Math.abs(e.scaleX()-1)<1e-7?1:e.scaleX(),i=Math.abs(e.scaleY()-1)<1e-7?1:e.scaleY();e.scaleX(1),e.scaleY(1),o.set({x:e.x(),y:e.y(),width:e.width()*r,height:e.height()*i,rotation:e.rotation()})},onTransformEnd:()=>j(!1)}),t(h,{x:o.a.x,y:o.a.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:N,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2,stroke:o.borderColor,strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,_-o.borderSize),hideInExport:!o.showInExport})]})});
|
package/canvas/image-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import a from"react";import{observer as o}from"mobx-react-lite";import{nodeAutorun as i}from"../utils/mobx.js";import{Arc as n,Group as h,Image as d,Rect as s,Text as c,Transformer as l}from"react-konva";import{ROLES as g}from"../model/store.js";import u from"use-image";import f from"konva";import{Portal as p}from"react-konva-utils";import{useWorkspaceStyle as m}from"./workspace-style.js";import{incrementLoader as w,triggerLoadError as x}from"../utils/loader.js";import*as y from"../utils/svg.js";import{flags as M}from"../utils/flags.js";import{trySetCanvasSize as v}from"../utils/canvas.js";import{applyFilter as b}from"./apply-filters.js";import{useFadeIn as E}from"./use-fadein.js";import{isTouchDevice as S}from"../utils/screen.js";import{useDelayer as I}from"./use-delayer.js";import{useColor as R}from"./use-color.js";function C(){return document.createElement("canvas")}const X=t=>t.indexOf("data:image/svg+xml")>=0||t.indexOf(".svg")>=0;export const useSizeFixer=t=>{const[e,r]=a.useState(t);return a.useEffect(()=>{(async()=>{const a=await async function(t){if(!X(t)){return t}const e=await y.urlToString(t),r=y.fixSize(e);return y.svgToURL(r)}(t);a!==e&&r(a)})()},[t]),e};function Y(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}const O=(t,e)=>e.width<5||e.height<5?t:e,T={keepRatio:!1,rotateEnabled:!1,boundBoxFunc:O},D={enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],rotateEnabled:!1,borderEnabled:!1,boundBoxFunc:O};const A=(t,e,r)=>Math.max(e,Math.min(r,t));export const useCornerRadiusAndCrop=(t,e,r,o,i=0,n=!1,h=!0)=>{var d,s;const c=Math.floor(A(t.a.width*o,1,1e4)),l=Math.floor(A(t.a.height*o,1,1e4)),g=Math.min(i*o,c/2,l/2),u=Math.max(t.a.width/r.width,t.a.height/r.height)*o,p=(null===(d=t.page)||void 0===d?void 0:d._exportingOrRendering)&&M.imageDownScalingEnabled&&u<1&&!n,m=0===r.x&&0===r.y&&r.width===(null==e?void 0:e.width)&&r.height===(null==e?void 0:e.height),w=a.useMemo(()=>{if(e&&e.width&&e.height){return m&&0===g&&!p?void 0:C()}},[e,g,p,m]);return a.useLayoutEffect(()=>{if(!w||!e){return}v(w,c,l);const t=w.getContext("2d");if(!t){return}g&&(t.beginPath(),t.moveTo(g,0),t.lineTo(c-g,0),t.arc(c-g,g,g,3*Math.PI/2,0,!1),t.lineTo(c,l-g),t.arc(c-g,l-g,g,0,Math.PI/2,!1),t.lineTo(g,l),t.arc(g,l-g,g,Math.PI/2,Math.PI,!1),t.lineTo(0,g),t.arc(g,g,g,Math.PI,3*Math.PI/2,!1),t.clip());const a=p?function(t,e){var r,a;const o=C();o.width=t.width,o.height=t.height;const i=Math.max(1,Math.floor(o.width*e)),n=Math.max(1,Math.floor(o.height*e));null===(r=o.getContext("2d"))||void 0===r||r.drawImage(t,0,0,o.width,o.height);const h=function(t,e,r,a,o,i,n){for(var h=new ImageData(e,r),d=new Int32Array(t.data.buffer),s=t.width,c=new Int32Array(h.data.buffer),l=h.width,g=e/i,u=r/n,f=Math.round(1/g),p=Math.round(1/u),m=f*p,w=0;w<h.height;w++){for(var x=0;x<l;x++){for(var y=0+Math.round(x/g)+(0+Math.round(w/u))*s,M=0,v=0,b=0,E=0,S=0;S<p;S++){for(var I=0;I<f;I++){var R=d[y+I+S*s];M+=R<<24>>>24,v+=R<<16>>>24,b+=R<<8>>>24,E+=R>>>24}}M=Math.round(M/m),v=Math.round(v/m),b=Math.round(b/m),E=Math.round(E/m),c[x+w*l]=E<<24|b<<16|v<<8|M}}return h}(o.getContext("2d").getImageData(0,0,o.width,o.height),i,n,0,0,o.width,o.height);return o.width=i,o.height=n,null===(a=o.getContext("2d"))||void 0===a||a.putImageData(h,0,0),o}(e,u):e,o=p?{x:Math.floor(r.x*u),y:Math.floor(r.y*u),width:Math.floor(r.width*u),height:Math.floor(r.height*u)}:r;t.drawImage(a,o.x,o.y,o.width,o.height,0,0,w.width,w.height)},[w,t.a.width,t.a.height,r.x,r.y,r.width,r.height,i,o,n,null===(s=t.page)||void 0===s?void 0:s._exportingOrRendering,p]),a.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&f.Util.releaseCanvas(w)},[w]),w||e};const L=C(),W=o(({element:r})=>{const o=Math.min(30,r.a.width/4,r.a.height/4),i=a.useRef(null);a.useEffect(()=>{const t=i.current;if(!t){return}const e=new f.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}});const{mediaLoadingStyle:d}=m();return e(h,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:d.fill}),t(n,{ref:i,x:r.a.width/2,y:r.a.height/2,fill:d.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),_=o(({element:r})=>{const{mediaErrorStyle:a}=m(),o=Math.max(10,Math.min(30,r.a.width/25));return e(h,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:a.fill}),t(c,{text:"Can not load the image...",fontSize:o,width:r.a.width,height:r.a.height,align:"center",fill:a.textFill,verticalAlign:"middle",padding:5})]})});let j=u;export const setImageLoaderHook=t=>{j=t};export const useImageLoader=(t,e="",r="")=>{const o=a.useRef(void 0),i=()=>{var t;null===(t=o.current)||void 0===t||t.call(o),o.current=void 0};a.useEffect(()=>i,[]),a.useLayoutEffect(()=>{const a=e.slice(0,200),n=`image with id ${r} url: ${a}`;"loading"!==t||o.current||(o.current=w(n)),"loading"!==t&&i(),"failed"===t&&x(n)},[t])};export const ImageElement=o(({element:o,store:n})=>{var c,u,w,x;const M=m(),[O,A]=a.useState(!1),k=a.useRef(null),H=a.useRef(null),z=o.isSelected,[P,F]=(t=>{const[e,r]=a.useReducer(t=>t+1,0),o=a.useRef("loading"),i=a.useRef(t.src),n=a.useRef(t.src);n.current!==t.src&&(n.current=t.src,o.current="loading");const h=a.useMemo(()=>X(t.src)||"svg"===t.type,[t.src,t.type]);return a.useEffect(()=>{if(!h){return}if(!t.src){return}let e=!1;return(async()=>{o.current="loading",r();const a=await y.urlToString(t.src),n=y.fixSize(a);let h;h=t.colorsReplace?y.replaceColors(n,t.colorsReplace||new Map):y.svgToURL(n),e||(i.current=h,o.current="loaded",r())})(),()=>{e=!0}},[t.src,JSON.stringify(t.colorsReplace)]),h?[i.current,o.current]:[t.src,"loaded"]})(o),[B,N]=j(P,"anonymous"),U="svg"!==o.type||"loaded"===F?N:"loading";useImageLoader(U,o.src,o.id);const V=(null===(c=o.page)||void 0===c?void 0:c._exportingOrRendering)?1:Math.max(1,n.scale),$=n._elementsPixelRatio*V,q=(({image:t,status:e,type:r})=>{const o=a.useRef(void 0);return a.useEffect(()=>{o.current=t||o.current},[t]),"failed"!==e||"failed"!==e&&"svg"===r?o.current:void 0})({image:B,status:N,type:o.type}),J=((t,e,r)=>{const o=a.useMemo(()=>{var a,o;const{flipX:i,flipY:n}=t,h="svg"===t.type||t.src.indexOf("data:image/svg+xml")>=0||t.src.indexOf(".svg")>=0,d=navigator.userAgent.toLowerCase().indexOf("firefox")>-1,s=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||d)&&h||t.maskSrc;if(!i&&!n&&!s){return e}if(!e||!e.width||!e.height){return null}const c=C();let l=1;"svg"===t.type&&(l=Math.max(t.a.width/e.width*r,t.a.height/e.height*r)),v(c,Math.max(e.width*l,1),Math.max(e.height*l,1));let g=i?-c.width:0,u=n?-c.height:0;return null===(a=c.getContext("2d"))||void 0===a||a.scale(i?-1:1,n?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(e,g,u,c.width,c.height),c},[t.maskSrc,t.flipX,t.flipY,e,t.a.width,t.a.height,r]);return a.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&f.Util.releaseCanvas(o)},[o]),o})(o,B||q,$),G=((t,e)=>{const r=useSizeFixer(t.maskSrc||""),[o,i]=j(r,"anonymous");return useImageLoader(r?i:"loaded",r||"",t.id),a.useMemo(()=>{if(!o){return e}if(!e||!e.width||!e.height){return e}const r=C();r.width=Math.max(e.width,1),r.height=Math.max(e.height,1);const a=r.getContext("2d");if(!a){return e}a.drawImage(e,0,0),a.globalCompositeOperation="source-in";const i=function(t,e){const r=e.width/e.height;let a,o;return r>=t.width/t.height?(a=t.width,o=t.width/r):(a=t.height*r,o=t.height),{x:(t.width-a)/2,y:(t.height-o)/2,width:a,height:o}}(o,t);return a.drawImage(o,i.x,i.y,i.width,i.height,0,0,e.width,e.height),r},[e,o,t.a.width,t.a.height])})(o,J)||L;let{cropX:K,cropY:Q,cropWidth:Z,cropHeight:tt}=o.a;"loaded"!==N&&(K=Q=0,Z=tt=1);const et=G.width*Z,rt=G.height*tt,at=o.a.width/o.a.height;let ot,it;const nt=et/rt,ht=o.stretchEnabled;ht?(ot=et,it=rt):at>=nt?(ot=et,it=et/at):(ot=rt*at,it=rt);const dt={x:G.width*K,y:G.height*Q,width:ot,height:it},st=null!==(u=o.cornerRadius)&&void 0!==u?u:0,ct=(null===(w=o.page)||void 0===w?void 0:w._exportingOrRendering)?1:Math.min(2,n.scale),lt=n._elementsPixelRatio*ct;let gt=((t,e,r,o)=>{const i=useSizeFixer(t.clipSrc||""),[n,h]=j(i,"anonymous"),d=t.clipSrc?h:"loaded";useImageLoader(d,t.clipSrc,t.id);const s=a.useMemo(()=>{if(e&&n){return C()}},[e,n]);return a.useLayoutEffect(()=>{var a;if(!n){return}if(!e||!e.width||!e.height){return}if(!n||!n.width||!n.height){return}if(!s){return}const o=C(),i=Math.max(t.a.width/n.width*r,t.a.height/n.height*r);o.width=Math.max(n.width*i,1),o.height=Math.max(n.height*i,1),null===(a=o.getContext("2d"))||void 0===a||a.drawImage(n,0,0,o.width,o.height),s.width=Math.max(e.width,1),s.height=Math.max(e.height,1);const h=s.getContext("2d");h&&(h.save(),h.drawImage(o,0,0,e.width,e.height),f.Util.releaseCanvas(o),h.globalCompositeOperation="source-in",h.drawImage(e,0,0,s.width,s.height),h.restore())},[s,e,n,t.a.width,t.a.height,r,...o]),t.clipSrc&&n?s:e})(o,useCornerRadiusAndCrop(o,G,dt,lt,st,O||o._cropModeEnabled||"svg"===o.type,!0),lt,[dt,st,lt]);const ut=Math.max(o.a.width/ot,o.a.height/it);a.useEffect(()=>{var t;if(!o._cropModeEnabled){return}const e=null===(t=k.current)||void 0===t?void 0:t.getStage();function r(t){o._cropModeEnabled&&t.target!==H.current&&o.toggleCropMode(!1)}function a(t){o._cropModeEnabled&&t.target.parentNode!==(null==e?void 0:e.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",a),null==e||e.on("click",r),null==e||e.on("tap",r),()=>{document.body.removeEventListener("click",a),document.body.removeEventListener("touchstart",a),null==e||e.off("click",r),null==e||e.off("click",r)}},[o._cropModeEnabled]),a.useLayoutEffect(()=>{if(!O&&!o._cropModeEnabled){return b(k.current,o),i(o,()=>{b(k.current,o)},{delay:100})}},[gt,null===(x=o.page)||void 0===x?void 0:x._exportingOrRendering,O,Z,tt,o._cropModeEnabled]),a.useLayoutEffect(()=>{var t;O||o._cropModeEnabled?null===(t=k.current)||void 0===t||t.clearCache():b(k.current,o)},[O,o.a.width,o.a.height,o._cropModeEnabled]),a.useEffect(()=>{b(k.current,o)},[o.shadowEnabled,o.shadowBlur,o.cornerRadius,o.shadowColor,o.shadowOffsetX,o.shadowOffsetY,o.shadowOpacity]);const ft=a.useRef(null),pt=a.useRef(null),mt=a.useRef(null);a.useLayoutEffect(()=>{o._cropModeEnabled&&(pt.current.nodes([ft.current]),mt.current.nodes([H.current]))},[o._cropModeEnabled]);var wt=a.useRef(null),xt=a.useRef(0),yt=a.useRef(!1);const Mt=t=>{var e;(null===(e=t.evt.touches)||void 0===e?void 0:e.length)>2&&t.target.stopDrag(),Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const r=t.target.width()*t.target.scaleX(),a=t.target.height()*t.target.scaleY(),i=Math.min(1,ot/r),n=Math.min(1,it/a),h=1-i,d=Math.min(h,Math.max(0,Math.round(-t.target.x())/r)),s=1-n,c=Math.min(s,Math.max(0,Math.round(-t.target.y())/a));t.target.setAttrs({x:-d*G.width,y:-c*G.height,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:c,cropWidth:i,cropHeight:n})},vt=()=>{"svg"!==o.type&&o.contentEditable&&(o.stretchEnabled||setTimeout(()=>{o.toggleCropMode(!0)}))},bt="svg"===o.type&&q,Et="loading"===N&&!bt,[St]=I(Et,100,!1,!1),It="failed"===N,Rt=!St&&!It,Ct=a.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Xt=Rt?o.a.opacity:0;E(k,Xt);const Yt=o.selectable||n.role===g.ADMIN,Ot=S(),Tt=R(o,o.borderColor,"stroke");return e(r,{children:[St&&t(W,{element:o}),It&&t(_,{element:o}),t(d,{ref:k,name:"element",id:o.id,image:gt,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:Xt,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:dt,listening:Yt,draggable:Ot?o.draggable&&z:o.draggable,preventDefault:!Ot||z,hideInExport:!o.showInExport,onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDblClick:vt,onDblTap:vt,onTransformStart:()=>{A(!0),Ct.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:t=>{var e;const r=t.currentTarget,a=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),i=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const n=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer"),h=1-ot/G.width,d=Math.min(h,Math.max(0,o.cropX)),s=1-it/G.height,c=Math.min(s,Math.max(0,o.cropY)),l=n.getActiveAnchor(),g=!(l.indexOf("middle")>=0||l.indexOf("center")>=0),u=!g&&a<1&&Ct.current.cropHeight>it/G.height;let f=g?o.cropWidth:o.cropWidth*a;u&&(f=o.cropWidth);const p=!g&&i<1&&Ct.current.cropWidth>ot/G.width;let m=g?o.cropHeight:o.cropHeight*i;p&&(m=o.cropHeight),ht&&(f=o.cropWidth,m=o.cropHeight),o.set({cropX:d,cropY:c,x:r.x(),y:r.y(),width:r.width()*a,height:r.height()*i,rotation:t.target.rotation(),cropWidth:Math.min(f,1-d),cropHeight:Math.min(m,1-c)})},onTransformEnd:t=>{const e=t.currentTarget;o.set({width:e.width(),height:e.height(),x:e.x(),y:e.y(),rotation:t.target.rotation(),cropWidth:ot/G.width,cropHeight:it/G.height}),A(!1)}}),t(s,Object.assign({x:o.x,y:o.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:Xt,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2},Tt,{strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,st-o.borderSize),hideInExport:!o.showInExport})),o._cropModeEnabled&&e(p,{selector:".page-abs-container",enabled:!0,children:[t(s,{x:-window.innerWidth/n.scale,y:-window.innerWidth/n.scale,width:window.innerWidth/n.scale*3,height:window.innerWidth/n.scale*3,fill:M.cropOverlayFill}),t(d,{listening:!1,image:gt,x:o.x,y:o.y,width:o.a.width,height:o.a.height,rotation:o.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),e(h,{x:o.x,y:o.y,rotation:o.rotation,scaleX:ut,scaleY:ut,children:[t(d,{image:G,ref:H,opacity:.4,draggable:!0,x:-o.cropX*G.width,y:-o.cropY*G.height,onDragMove:Mt,onTransform:Mt,onTouchMove:t=>{t.evt.preventDefault();const e=t.target.getStage().getPointersPositions();var r=e[0],a=e[1];const o=t.target;if(r&&!a&&!o.isDragging()&&yt.current&&(o.startDrag(),yt.current=!1),r&&a){f.hitOnDragEnabled=!0,o.isDragging()&&(yt.current=!0,o.stopDrag());const e=t.target.getAbsoluteTransform().copy();e.invert();var i={x:r.x,y:r.y},n={x:a.x,y:a.y};if(!wt.current){return void(wt.current=Y(i,n))}var h=Y(i,n),d=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}(i,n);xt.current||(xt.current=d);const p=o.position();var s={x:h.x-p.x,y:h.y-p.y},c=d/xt.current;o.scaleX(c),o.scaleY(c);const m=e.point(h),w=e.point(wt.current);var l=m.x-w.x,g=m.y-w.y,u={x:Math.min(0,h.x-s.x*c+l),y:Math.min(0,h.y-s.y*c+g)};o.position(u),xt.current=d,wt.current=h,Mt(t)}},onTouchEnd:t=>{xt.current=0,wt.current=null,f.hitOnDragEnabled=!1}}),t(l,Object.assign({ref:mt},D,M.outerImageCropTransformerStyle)),t(s,{width:ot,height:it,ref:ft,listening:!1,onTransform:t=>{if(o.cropX<Math.abs(t.target.x()/G.width)&&t.target.x()<0&&o.cropX>0){const e=(o.cropWidth+o.cropX)*G.width;t.target.scaleX(1),t.target.width(e)}if(o.cropY<Math.abs(t.target.y()/G.height)&&t.target.y()<0&&o.cropY>0){const e=(o.cropHeight+o.cropY)*G.height;t.target.scaleY(1),t.target.height(e)}t.target.x()<-o.cropX*G.width-1e-9&&(t.target.x(-o.cropX*G.width),t.target.scaleX(1)),t.target.y()<-o.cropY*G.height-1e-9&&(t.target.y(-o.cropY*G.height),t.target.scaleY(1));const e=Math.min(1,Math.max(0,o.cropX+t.target.x()/G.width)),r=Math.min(1,Math.max(0,t.target.y()/G.height+o.cropY)),a=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),n=Math.min(1-e,a/G.width),h=Math.min(1-r,i/G.height),d=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),o.set({x:d.x,y:d.y,cropX:e,cropY:r,cropWidth:n,cropHeight:h,width:Math.min(a*ut,G.width*(1-e)*ut),height:Math.min(i*ut,G.height*(1-r)*ut)})}}),t(l,Object.assign({ref:pt},T,M.innerImageCropTransformerStyle,{visible:o.resizable}))]})]})]})});
|
|
1
|
+
import{jsx as t,jsxs as e,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as a}from"mobx-react-lite";import{Arc as o,Group as n,Image as h,Rect as s,Text as d,Transformer as c}from"react-konva";import{ROLES as g}from"../model/store.js";import l from"use-image";import u from"konva";import{Portal as p}from"react-konva-utils";import{useWorkspaceStyle as m}from"./workspace-style.js";import{incrementLoader as f,triggerLoadError as w}from"../utils/loader.js";import{polotnoError as x}from"../utils/errors.js";import*as y from"../utils/svg.js";import{flags as M}from"../utils/flags.js";import{trySetCanvasSize as v}from"../utils/canvas.js";import{useFilteredSource as b}from"./use-filtered-source.js";import{useFadeIn as E}from"./use-fadein.js";import{isTouchDevice as I}from"../utils/screen.js";import{useDelayer as S}from"./use-delayer.js";import{useColor as R}from"./use-color.js";function C(){return document.createElement("canvas")}const X=t=>t.indexOf("data:image/svg+xml")>=0||t.indexOf(".svg")>=0;export const useSizeFixer=t=>{const[e,r]=i.useState(t);return i.useEffect(()=>{(async()=>{const i=await async function(t){if(!X(t)){return t}const e=await y.urlToString(t),r=y.fixSize(e);return y.svgToURL(r)}(t);i!==e&&r(i)})()},[t]),e};function Y(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}const O=(t,e)=>e.width<5||e.height<5?t:e,T={keepRatio:!1,rotateEnabled:!1,boundBoxFunc:O},A={enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],rotateEnabled:!1,borderEnabled:!1,boundBoxFunc:O};const D=(t,e,r)=>Math.max(e,Math.min(r,t));export const useCornerRadiusAndCrop=(t,e,r,a,o=0,n=!1,h=!0)=>{var s,d;const c=Math.floor(D(t.a.width*a,1,1e4)),g=Math.floor(D(t.a.height*a,1,1e4)),l=Math.min(o*a,c/2,g/2),p=Math.max(t.a.width/r.width,t.a.height/r.height)*a,m=(null===(s=t.page)||void 0===s?void 0:s._exportingOrRendering)&&M.imageDownScalingEnabled&&p<1&&!n,f=0===r.x&&0===r.y&&r.width===(null==e?void 0:e.width)&&r.height===(null==e?void 0:e.height),w=i.useMemo(()=>{if(e&&e.width&&e.height){return f&&0===l&&!m?void 0:C()}},[e,l,m,f]);return i.useLayoutEffect(()=>{if(!w||!e){return}v(w,c,g);const t=w.getContext("2d");if(!t){return}l&&(t.beginPath(),t.moveTo(l,0),t.lineTo(c-l,0),t.arc(c-l,l,l,3*Math.PI/2,0,!1),t.lineTo(c,g-l),t.arc(c-l,g-l,l,0,Math.PI/2,!1),t.lineTo(l,g),t.arc(l,g-l,l,Math.PI/2,Math.PI,!1),t.lineTo(0,l),t.arc(l,l,l,Math.PI,3*Math.PI/2,!1),t.clip());const i=m?function(t,e){var r,i;const a=C();a.width=t.width,a.height=t.height;const o=Math.max(1,Math.floor(a.width*e)),n=Math.max(1,Math.floor(a.height*e));null===(r=a.getContext("2d"))||void 0===r||r.drawImage(t,0,0,a.width,a.height);const h=function(t,e,r,i,a,o,n){for(var h=new ImageData(e,r),s=new Int32Array(t.data.buffer),d=t.width,c=new Int32Array(h.data.buffer),g=h.width,l=e/o,u=r/n,p=Math.round(1/l),m=Math.round(1/u),f=p*m,w=0;w<h.height;w++){for(var x=0;x<g;x++){for(var y=0+Math.round(x/l)+(0+Math.round(w/u))*d,M=0,v=0,b=0,E=0,I=0;I<m;I++){for(var S=0;S<p;S++){var R=s[y+S+I*d];M+=R<<24>>>24,v+=R<<16>>>24,b+=R<<8>>>24,E+=R>>>24}}M=Math.round(M/f),v=Math.round(v/f),b=Math.round(b/f),E=Math.round(E/f),c[x+w*g]=E<<24|b<<16|v<<8|M}}return h}(a.getContext("2d").getImageData(0,0,a.width,a.height),o,n,0,0,a.width,a.height);return a.width=o,a.height=n,null===(i=a.getContext("2d"))||void 0===i||i.putImageData(h,0,0),a}(e,p):e,a=m?{x:Math.floor(r.x*p),y:Math.floor(r.y*p),width:Math.floor(r.width*p),height:Math.floor(r.height*p)}:r;t.drawImage(i,a.x,a.y,a.width,a.height,0,0,w.width,w.height)},[w,t.a.width,t.a.height,r.x,r.y,r.width,r.height,o,a,n,null===(d=t.page)||void 0===d?void 0:d._exportingOrRendering,m]),i.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&u.Util.releaseCanvas(w)},[w]),w||e};const W=C(),j=a(({element:r})=>{const a=Math.min(30,r.a.width/4,r.a.height/4),h=i.useRef(null);i.useEffect(()=>{const t=h.current;if(!t){return}const e=new u.Animation(e=>{t.rotate(((null==e?void 0:e.timeDiff)||0)/2)},t.getLayer());return e.start(),()=>{e.stop()}});const{mediaLoadingStyle:d}=m();return e(n,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:d.fill}),t(o,{ref:h,x:r.a.width/2,y:r.a.height/2,fill:d.textFill,outerRadius:Math.abs(a),innerRadius:Math.max(1,a-5),angle:270})]})}),L=a(({element:r})=>{const{mediaErrorStyle:i}=m(),a=Math.max(10,Math.min(30,r.a.width/25));return e(n,{x:r.x,y:r.y,rotation:r.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[t(s,{width:r.a.width,height:r.a.height,fill:i.fill}),t(d,{text:"Can not load the image...",fontSize:a,width:r.a.width,height:r.a.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});let k=l;export const setImageLoaderHook=t=>{k=t};export const useImageLoader=(t,e="",r="")=>{const a=i.useRef(void 0),o=()=>{var t;null===(t=a.current)||void 0===t||t.call(a),a.current=void 0};i.useEffect(()=>o,[]),i.useLayoutEffect(()=>{const i=e.slice(0,200),n=`image with id ${r} url: ${i}`;"loading"!==t||a.current||(a.current=f(n)),"loading"!==t&&o(),"failed"===t&&w(x("IMAGE_FAILED",n,{src:i,elementId:r,reason:"load"}))},[t])};export const ImageElement=a(({element:a,store:o})=>{var d,l,f;const w=m(),[x,M]=i.useState(!1),O=i.useRef(null),D=i.useRef(null),H=a.isSelected,[_,z]=(t=>{const[e,r]=i.useReducer(t=>t+1,0),a=i.useRef("loading"),o=i.useRef(t.src),n=i.useRef(t.src);n.current!==t.src&&(n.current=t.src,a.current="loading");const h=i.useMemo(()=>X(t.src)||"svg"===t.type,[t.src,t.type]);return i.useEffect(()=>{if(!h){return}if(!t.src){return}let e=!1;return(async()=>{a.current="loading",r();const i=await y.urlToString(t.src),n=y.fixSize(i);let h;h=t.colorsReplace?y.replaceColors(n,t.colorsReplace||new Map):y.svgToURL(n),e||(o.current=h,a.current="loaded",r())})(),()=>{e=!0}},[t.src,JSON.stringify(t.colorsReplace)]),h?[o.current,a.current]:[t.src,"loaded"]})(a),[P,F]=k(_,"anonymous"),N="svg"!==a.type||"loaded"===z?F:"loading";useImageLoader(N,a.src,a.id);const B=(null===(d=a.page)||void 0===d?void 0:d._exportingOrRendering)?1:Math.max(1,o.scale),U=o._elementsPixelRatio*B,V=(({image:t,status:e,type:r})=>{const a=i.useRef(void 0);return i.useEffect(()=>{a.current=t||a.current},[t]),"failed"!==e||"failed"!==e&&"svg"===r?a.current:void 0})({image:P,status:F,type:a.type}),$=((t,e,r)=>{const a=i.useMemo(()=>{var i,a;const{flipX:o,flipY:n}=t,h="svg"===t.type||t.src.indexOf("data:image/svg+xml")>=0||t.src.indexOf(".svg")>=0,s=navigator.userAgent.toLowerCase().indexOf("firefox")>-1,d=(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||s)&&h||t.maskSrc;if(!o&&!n&&!d){return e}if(!e||!e.width||!e.height){return null}const c=C();let g=1;"svg"===t.type&&(g=Math.max(t.a.width/e.width*r,t.a.height/e.height*r)),v(c,Math.max(e.width*g,1),Math.max(e.height*g,1));let l=o?-c.width:0,u=n?-c.height:0;return null===(i=c.getContext("2d"))||void 0===i||i.scale(o?-1:1,n?-1:1),null===(a=c.getContext("2d"))||void 0===a||a.drawImage(e,l,u,c.width,c.height),c},[t.maskSrc,t.flipX,t.flipY,e,t.a.width,t.a.height,r]);return i.useEffect(()=>()=>{a&&"CANVAS"===a.nodeName&&u.Util.releaseCanvas(a)},[a]),a})(a,P||V,U),q=((t,e)=>{const r=useSizeFixer(t.maskSrc||""),[a,o]=k(r,"anonymous");return useImageLoader(r?o:"loaded",r||"",t.id),i.useMemo(()=>{if(!a){return e}if(!e||!e.width||!e.height){return e}const r=C();r.width=Math.max(e.width,1),r.height=Math.max(e.height,1);const i=r.getContext("2d");if(!i){return e}i.drawImage(e,0,0),i.globalCompositeOperation="source-in";const o=function(t,e){const r=e.width/e.height;let i,a;return r>=t.width/t.height?(i=t.width,a=t.width/r):(i=t.height*r,a=t.height),{x:(t.width-i)/2,y:(t.height-a)/2,width:i,height:a}}(a,t);return i.drawImage(a,o.x,o.y,o.width,o.height,0,0,e.width,e.height),r},[e,a,t.a.width,t.a.height])})(a,$)||W,[G=W]=b(a,q);let{cropX:J,cropY:K,cropWidth:Q,cropHeight:Z}=a.a;"loaded"!==F&&(J=K=0,Q=Z=1);const tt=G.width*Q,et=G.height*Z,rt=a.a.width/a.a.height;let it,at;const ot=tt/et,nt=a.stretchEnabled;nt?(it=tt,at=et):rt>=ot?(it=tt,at=tt/rt):(it=et*rt,at=et);const ht={x:G.width*J,y:G.height*K,width:it,height:at},st=null!==(l=a.cornerRadius)&&void 0!==l?l:0,dt=(null===(f=a.page)||void 0===f?void 0:f._exportingOrRendering)?1:Math.min(2,o.scale),ct=o._elementsPixelRatio*dt;let gt=((t,e,r,a)=>{const o=useSizeFixer(t.clipSrc||""),[n,h]=k(o,"anonymous"),s=t.clipSrc?h:"loaded";useImageLoader(s,t.clipSrc,t.id);const d=i.useMemo(()=>{if(e&&n){return C()}},[e,n]);return i.useLayoutEffect(()=>{var i;if(!n){return}if(!e||!e.width||!e.height){return}if(!n||!n.width||!n.height){return}if(!d){return}const a=C(),o=Math.max(t.a.width/n.width*r,t.a.height/n.height*r);a.width=Math.max(n.width*o,1),a.height=Math.max(n.height*o,1),null===(i=a.getContext("2d"))||void 0===i||i.drawImage(n,0,0,a.width,a.height),d.width=Math.max(e.width,1),d.height=Math.max(e.height,1);const h=d.getContext("2d");h&&(h.save(),h.drawImage(a,0,0,e.width,e.height),u.Util.releaseCanvas(a),h.globalCompositeOperation="source-in",h.drawImage(e,0,0,d.width,d.height),h.restore())},[d,e,n,t.a.width,t.a.height,r,...a]),t.clipSrc&&n?d:e})(a,useCornerRadiusAndCrop(a,G,ht,ct,st,x||a._cropModeEnabled||"svg"===a.type,!0),ct,[ht,st,ct]);const lt=Math.max(a.a.width/it,a.a.height/at);i.useEffect(()=>{var t;if(!a._cropModeEnabled){return}const e=null===(t=O.current)||void 0===t?void 0:t.getStage();function r(t){a._cropModeEnabled&&t.target!==D.current&&a.toggleCropMode(!1)}function i(t){a._cropModeEnabled&&t.target.parentNode!==(null==e?void 0:e.content)&&a.toggleCropMode(!1)}return document.body.addEventListener("click",i),null==e||e.on("click",r),null==e||e.on("tap",r),()=>{document.body.removeEventListener("click",i),document.body.removeEventListener("touchstart",i),null==e||e.off("click",r),null==e||e.off("click",r)}},[a._cropModeEnabled]);const ut=i.useRef(null),pt=i.useRef(null),mt=i.useRef(null);i.useLayoutEffect(()=>{a._cropModeEnabled&&(pt.current.nodes([ut.current]),mt.current.nodes([D.current]))},[a._cropModeEnabled]);var ft=i.useRef(null),wt=i.useRef(0),xt=i.useRef(!1);const yt=t=>{var e;(null===(e=t.evt.touches)||void 0===e?void 0:e.length)>2&&t.target.stopDrag(),Math.round(t.target.x())>0&&(t.target.x(0),t.target.scaleX(1)),Math.round(t.target.y())>0&&(t.target.y(0),t.target.scaleY(1));const r=t.target.width()*t.target.scaleX(),i=t.target.height()*t.target.scaleY(),o=Math.min(1,it/r),n=Math.min(1,at/i),h=1-o,s=Math.min(h,Math.max(0,Math.round(-t.target.x())/r)),d=1-n,c=Math.min(d,Math.max(0,Math.round(-t.target.y())/i));t.target.setAttrs({x:-s*G.width,y:-c*G.height,scaleX:1,scaleY:1}),a.set({cropX:s,cropY:c,cropWidth:o,cropHeight:n})},Mt=()=>{"svg"!==a.type&&a.contentEditable&&(a.stretchEnabled||setTimeout(()=>{a.toggleCropMode(!0)}))},vt="svg"===a.type&&V,bt="loading"===F&&!vt,[Et]=S(bt,100,!1,!1),It="failed"===F,St=!Et&&!It,Rt=i.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Ct=St?a.a.opacity:0;E(O,Ct);const Xt=a.selectable||o.role===g.ADMIN,Yt=I(),Ot=R(a,a.borderColor,"stroke");return e(r,{children:[Et&&t(j,{element:a}),It&&t(L,{element:a}),t(h,{ref:O,name:"element",id:a.id,image:gt,x:a.a.x,y:a.a.y,width:a.a.width||1,height:a.a.height||1,rotation:a.a.rotation,opacity:Ct,shadowEnabled:a.shadowEnabled,shadowBlur:a.shadowBlur,shadowOffsetX:a.shadowOffsetX,shadowOffsetY:a.shadowOffsetY,shadowColor:a.shadowColor,shadowOpacity:a.shadowOpacity,customCrop:ht,listening:Xt,draggable:Yt?a.draggable&&H:a.draggable,preventDefault:!Yt||H,hideInExport:!a.showInExport,onDragMove:t=>{a.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{a.set({x:t.target.x(),y:t.target.y()})},onDblClick:Mt,onDblTap:Mt,onTransformStart:()=>{M(!0),Rt.current={cropX:a.cropX,cropY:a.cropY,cropWidth:a.cropWidth,cropHeight:a.cropHeight}},onTransform:t=>{var e;const r=t.currentTarget,i=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),o=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const n=null===(e=t.target.getStage())||void 0===e?void 0:e.findOne("Transformer"),h=1-it/G.width,s=Math.min(h,Math.max(0,a.cropX)),d=1-at/G.height,c=Math.min(d,Math.max(0,a.cropY)),g=n.getActiveAnchor(),l=!(g.indexOf("middle")>=0||g.indexOf("center")>=0),u=!l&&i<1&&Rt.current.cropHeight>at/G.height;let p=l?a.cropWidth:a.cropWidth*i;u&&(p=a.cropWidth);const m=!l&&o<1&&Rt.current.cropWidth>it/G.width;let f=l?a.cropHeight:a.cropHeight*o;m&&(f=a.cropHeight),nt&&(p=a.cropWidth,f=a.cropHeight),a.set({cropX:s,cropY:c,x:r.x(),y:r.y(),width:r.width()*i,height:r.height()*o,rotation:t.target.rotation(),cropWidth:Math.min(p,1-s),cropHeight:Math.min(f,1-c)})},onTransformEnd:t=>{const e=t.currentTarget;a.set({width:e.width(),height:e.height(),x:e.x(),y:e.y(),rotation:t.target.rotation(),cropWidth:it/G.width,cropHeight:at/G.height}),M(!1)}}),t(s,Object.assign({x:a.x,y:a.y,width:Math.max(a.a.width-a.borderSize,0),height:Math.max(a.a.height-a.borderSize,0),opacity:Ct,offsetX:-a.borderSize/2,offsetY:-a.borderSize/2},Ot,{strokeWidth:a.borderSize,listening:!1,visible:!!a.borderSize,rotation:a.rotation,cornerRadius:Math.max(0,st-a.borderSize),hideInExport:!a.showInExport})),a._cropModeEnabled&&e(p,{selector:".page-abs-container",enabled:!0,children:[t(s,{x:-window.innerWidth/o.scale,y:-window.innerWidth/o.scale,width:window.innerWidth/o.scale*3,height:window.innerWidth/o.scale*3,fill:w.cropOverlayFill}),t(h,{listening:!1,image:gt,x:a.x,y:a.y,width:a.a.width,height:a.a.height,rotation:a.rotation,shadowEnabled:a.shadowEnabled,shadowBlur:a.shadowBlur}),e(n,{x:a.x,y:a.y,rotation:a.rotation,scaleX:lt,scaleY:lt,children:[t(h,{image:G,ref:D,opacity:.4,draggable:!0,x:-a.cropX*G.width,y:-a.cropY*G.height,onDragMove:yt,onTransform:yt,onTouchMove:t=>{t.evt.preventDefault();const e=t.target.getStage().getPointersPositions();var r=e[0],i=e[1];const a=t.target;if(r&&!i&&!a.isDragging()&&xt.current&&(a.startDrag(),xt.current=!1),r&&i){u.hitOnDragEnabled=!0,a.isDragging()&&(xt.current=!0,a.stopDrag());const e=t.target.getAbsoluteTransform().copy();e.invert();var o={x:r.x,y:r.y},n={x:i.x,y:i.y};if(!ft.current){return void(ft.current=Y(o,n))}var h=Y(o,n),s=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}(o,n);wt.current||(wt.current=s);const m=a.position();var d={x:h.x-m.x,y:h.y-m.y},c=s/wt.current;a.scaleX(c),a.scaleY(c);const f=e.point(h),w=e.point(ft.current);var g=f.x-w.x,l=f.y-w.y,p={x:Math.min(0,h.x-d.x*c+g),y:Math.min(0,h.y-d.y*c+l)};a.position(p),wt.current=s,ft.current=h,yt(t)}},onTouchEnd:t=>{wt.current=0,ft.current=null,u.hitOnDragEnabled=!1}}),t(c,Object.assign({ref:mt},A,w.outerImageCropTransformerStyle)),t(s,{width:it,height:at,ref:ut,listening:!1,onTransform:t=>{if(a.cropX<Math.abs(t.target.x()/G.width)&&t.target.x()<0&&a.cropX>0){const e=(a.cropWidth+a.cropX)*G.width;t.target.scaleX(1),t.target.width(e)}if(a.cropY<Math.abs(t.target.y()/G.height)&&t.target.y()<0&&a.cropY>0){const e=(a.cropHeight+a.cropY)*G.height;t.target.scaleY(1),t.target.height(e)}t.target.x()<-a.cropX*G.width-1e-9&&(t.target.x(-a.cropX*G.width),t.target.scaleX(1)),t.target.y()<-a.cropY*G.height-1e-9&&(t.target.y(-a.cropY*G.height),t.target.scaleY(1));const e=Math.min(1,Math.max(0,a.cropX+t.target.x()/G.width)),r=Math.min(1,Math.max(0,t.target.y()/G.height+a.cropY)),i=t.target.width()*t.target.scaleX(),o=t.target.height()*t.target.scaleY(),n=Math.min(1-e,i/G.width),h=Math.min(1-r,o/G.height),s=t.target.getAbsolutePosition(t.target.getParent().getParent());t.target.scale({x:1,y:1}),t.target.position({x:0,y:0}),a.set({x:s.x,y:s.y,cropX:e,cropY:r,cropWidth:n,cropHeight:h,width:Math.min(i*lt,G.width*(1-e)*lt),height:Math.min(o*lt,G.height*(1-r)*lt)})}}),t(c,Object.assign({ref:pt},T,w.innerImageCropTransformerStyle,{visible:a.resizable}))]})]})]})});
|
package/canvas/text-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,Fragment as e,jsxs as r}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Group as i,Path as a,Text as s,TextPath as l}from"react-konva";import{Html as c}from"react-konva-utils";import{nodeAutorun as u}from"../utils/mobx.js";import d from"konva";import{parsePath as f,roundCommands as h}from"svg-round-corners/lib/index.js";import{generateBackgroundShapeFromRects as g,textLinesToRects as m}from"../utils/background-shape.js";import{useColor as p}from"./use-color.js";import{useWorkspaceStyle as x}from"./workspace-style.js";import{ROLES as w}from"../model/store.js";import{incrementLoader as v}from"../utils/loader.js";import{isFontLoaded as y}from"../utils/fonts.js";import{flags as S}from"../utils/flags.js";import{removeTags as b}from"../utils/text.js";import{getDir as E,getCurvePath as z,resolveLineHeight as k}from"../utils/text-html.js";import{applyFilter as O}from"./apply-filters.js";import{useFadeIn as R}from"./use-fadein.js";import{isTouchDevice as A}from"../utils/screen.js";import{isAlive as F,getParent as M}from"mobx-state-tree";import{getLimitedFontSize as j}from"./text-element/max-font-size.js";import{getOptimalCaretColor as L}from"./text-element/caret-color.js";let T;function C(){return T||(T=document.getElementById("polotno-text-style"),T||(T=document.createElement("style"),T.id="polotno-text-style",document.head.appendChild(T)),T)}d._fixTextRendering=!0;const H={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const X=o(({textNodeRef:e,element:r,onBlur:o,selectAll:i,cursorPosition:a})=>{const[s,l]=n.useState(H),c=e.current;n.useLayoutEffect(()=>{if(!c){return}const t={};t.width=c.width()-2*c.padding()+"px",t.height=c.height()-2*c.padding()+c.fontSize()*c.lineHeight()+"px",t.fontSize=c.fontSize()+"px",t.lineHeight=c.lineHeight()+.01,t.fontFamily=c.fontFamily(),t.textAlign=c.align(),t.color=c.fill(),t.fontWeight=r.fontWeight,t.fontStyle=r.fontStyle,t.letterSpacing=r.letterSpacing+"em",t.opacity=Math.max(r.a.opacity,.2),t.textTransform=r.textTransform,t.caretColor=L(r);const e=`\n .polotno-input::placeholder {\n color: ${s.color};\n opacity: 0.6;\n }\n `,n=C();n.innerHTML="",n.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(s)&&l(t)});const u=n.useRef(null);if(n.useLayoutEffect(()=>{var t;const e=u.current;if(!e){return}null===(t=u.current)||void 0===t||t.focus({preventScroll:!0});const r=a||e.value.length;e.selectionStart=e.selectionEnd=r,i&&(null==e||e.select(),document.execCommand("selectAll",!1,void 0))},[]),n.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=u.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!c){return null}let d=0;const f=c.textArr.length*c.lineHeight()*c.fontSize();"middle"===r.verticalAlign&&(d=(r.a.height-f)/2),"bottom"===r.verticalAlign&&(d=r.a.height-f);const h=b(r.text);return t("textarea",{className:"polotno-input",ref:u,dir:E(h),style:Object.assign(Object.assign(Object.assign({},H),s),{paddingTop:d+"px"}),value:h,onChange:t=>{const e=j({oldText:r.text,newText:t.target.value,element:r});r.set({text:t.target.value,fontSize:e})},placeholder:r.placeholder,onBlur:o})}),Y=e=>t(c,{children:t(X,Object.assign({},e))});export const useFontLoader=(t,e,r,o,i)=>{const[a,s]=n.useReducer(t=>t+1,0),l=n.useRef(y(e,r,o)),c=n.useRef(null);return n.useLayoutEffect(()=>{if(l.current=y(e,r,o),l.current){return}let n=!0;return(async()=>{l.current=!1,s();const a=v(`text ${e}`);await t.loadFont(e,r,o,i),n?(c.current=a,l.current=!0,s()):a()})(),()=>{c.current&&(c.current(),c.current=null),n=!1}},[e,r,o]),n.useEffect(()=>{l.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[l.current]),[l.current]};export const useFontFamiliesLoader=(t,e,r,o,i)=>{const[a,s]=n.useReducer(t=>t+1,0),l=e.join("\0"),c=n.useRef(e.every(t=>y(t,r,o))),u=n.useRef(null);return n.useLayoutEffect(()=>{if(c.current=e.every(t=>y(t,r,o)),c.current){return}let n=!0;return(async()=>{c.current=!1,s();const a=v(`text fonts ${l}`);await Promise.all(e.map(e=>t.loadFont(e,r,o,i))),n?(u.current=a,c.current=!0,s()):a()})(),()=>{u.current&&(u.current(),u.current=null),n=!1}},[l,r,o]),n.useEffect(()=>{c.current&&setTimeout(()=>{u.current&&(u.current(),u.current=null)})},[c.current]),[c.current]};export const getLineHeight=({fontLoaded:t,fontFamily:e,fontSize:r,lineHeight:o})=>n.useMemo(()=>k({fontFamily:e,fontSize:r,lineHeight:o}),[t,e,r,o]);export function usePrevious(t){const e=n.useRef(t),r=n.useRef(t);return n.useMemo(()=>{r.current=e.current,e.current=t},[t]),r.current}function P(t,e,r=!1){const n=t.fontSize(),o=t.height(),i=b(e.text);let a=e.a.fontSize;t.height(void 0);const s=Math.round(2*e.a.fontSize)-1;for(let l=1;l<s;l++){const n=e.a.height&&t.height()>e.a.height;let o=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>(e=e.toLowerCase(),/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e)),[]),s=t.textArr.map(t=>t.text.toLowerCase()).join(";");const l=o.find(t=>!s.includes(t)||(s=s.replace(t,""),!1));if(!(n||l&&!r)){break}a-=.5,t.fontSize(a)}return t.fontSize(n),t.height(o),a}export{getCurvePath}from"../utils/text-html.js";export const TextElement=o(({element:o,store:c})=>{const{textOverflowIndicatorStyle:d}=x(),y=n.useRef(null),k=n.useRef(null),j=n.useRef(null),L=n.useRef([]),T=n.useRef(!0),[,C]=n.useReducer(t=>t+1,0),{editorEnabled:H,selectAll:X}=(t=>{const[e,r]=n.useState(!1),o=n.useRef(!1);return n.useEffect(()=>{var e=!0;return setTimeout(()=>{e&&(t._editModeEnabled&&(o.current=!0),r(!0),setTimeout(()=>{o.current=!1},50))},50),()=>{e=!1}},[]),{editorEnabled:e&&t._editModeEnabled,selectAll:o.current}})(o),[W,B]=n.useState(!1),[D,$]=n.useState(!1),I=n.useRef(o.a.height),N=n.useRef(0),J=n.useRef(""),_=n.useRef(0),V=o.isSelected,q=usePrevious(V),{textVerticalResizeEnabled:U}=S,Z=S.autoDeleteEmptyText,G=usePrevious(o.fontFamily),[K,Q]=n.useState([]);n.useEffect(()=>{var t,e;const r=null!==(e=null===(t=y.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(r)!==JSON.stringify(K)&&Q(r)}),n.useEffect(()=>{if(o.a.width||"tablecell"===o.type){return}const t=y.current;t.width(600),o.set({width:1.4*t.getTextWidth()})},[]),n.useEffect(()=>{q&&!V&&Z&&""===o.text&&o.removable&&!o.placeholder&&c.deleteElements([o.id])},[Z,o.placeholder,o.removable,o.text,V,q]);const tt=()=>{if(o.curveEnabled){const t=y.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const e=k.current;e&&O(e,o)}else{const t=y.current;t&&O(t,o)}};n.useLayoutEffect(()=>{if(!D){return u(o,()=>{tt()})}}),n.useEffect(()=>{const t=L.current;t.length>0&&(L.current=[],t.forEach(t=>t()))}),n.useEffect(()=>()=>{T.current=!1;const t=L.current;t.length>0&&(L.current=[],t.forEach(t=>t()))},[]);let et=b(o.text);"uppercase"===o.textTransform&&(et=et.toUpperCase());const[rt]=useFontLoader(c,o.fontFamily,o.fontStyle,o.fontWeight,o.text||o.placeholder),nt=()=>{if(o.curveEnabled){const t=k.current;return t.getSelfRect().height||t.fontSize()}const t=y.current.clone({height:void 0}),e=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),e};n.useLayoutEffect(()=>{if(!rt){return}if("tablecell"===o.type){const{textOverflow:t}=S;if("resize"===t){const t=nt(),e=F(o)?M(o,2):null;(null==e?void 0:e.setCellContentHeight)&&e.setCellContentHeight(o.id,t)}else if("change-font-size"===t){const t=y.current;if(t){const e=P(t,o,S.textSplitAllowed);e!==o.fontSize&&c.history.ignore(()=>{o.set({fontSize:e})})}}return}const{textOverflow:t,textSplitAllowed:e}=S,r=(t,e,r,n)=>{const i=v(`text ${o.id}`),a=()=>{c.history.ignore(t,e,r).then(()=>{T.current?(L.current.push(i),C()):i()})};n?queueMicrotask(a):a()};if(!o.height){const t=nt();return void r(()=>{o.height||o.set({height:t})},void 0,void 0,!0)}if(!c.isPlaying){if("change-font-size"!==t||W){if("resize"===t){const t=nt();U&&o.height<t&&!W&&r(()=>{var e;F(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0),U||o.height===t||W||r(()=>{var e;F(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0)}}else{const t=y.current,n=o.curveEnabled?o.fontSize:P(t,o,e);if(n!==o.fontSize){return void r(()=>{o.set({fontSize:n})},!1,!0)}const i=nt();o.height===i||U||r(()=>{o.set({height:i})},!1,!0)}}}),n.useLayoutEffect(()=>{var t;if(rt&&o.curveEnabled){const e=null===(t=k.current)||void 0===t?void 0:t.getSelfRect().width;if(e){const t=e-o.a.width,r=o.a.rotation*Math.PI/180,n=-t/2*Math.cos(r),i=-t/2*Math.sin(r);o.set({width:e,x:o.a.x+n,y:o.a.y+i})}}},[rt,o.curveEnabled,o.curvePower,o.text,o.fontSize,o.fontFamily,o.fontWeight,o.fontStyle,o.letterSpacing]),n.useLayoutEffect(()=>{const t=y.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),tt())},[rt]);const ot=n.useRef(null),it=n.useRef(0),at=t=>{t.evt.preventDefault();const e=c.selectedShapes.find(t=>t===o);e&&o.contentEditable&&(it.current=function(t){var e;const r=t.target,n=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var r=t.getStage().getPointerPosition();return e.point(r)}(r),o=r.textArr,i=Math.floor(n.y/(r.fontSize()*r.lineHeight())),a=o.slice(0,i).reduce((t,e)=>t+e.text.length,i),s=null!==(e=o[i])&&void 0!==e?e:o[0];let l=0;return"right"===r.align()?l=r.width()-s.width:"center"===r.align()&&(l=r.width()/2-s.width/2),a+Math.round((n.x-l)/s.width*s.text.length)}(t),o.toggleEditMode())},st=!et&&o.placeholder?.6:o.a.opacity;R(y,st);const lt=getLineHeight({fontLoaded:rt,fontFamily:o.fontFamily,fontSize:o.a.fontSize,lineHeight:o.lineHeight}),ct=o.selectable||c.role===w.ADMIN,ut=p(o),dt=p(o,o.stroke,"stroke"),ft=n.useMemo(()=>o.backgroundEnabled?o.curveEnabled?function({width:t,height:e,padding:r=0,cornerRadius:n=0}){const o=-r,i=-r,a=t+r,s=e+r,l=f(`M ${o} ${i} L ${a} ${i} L ${a} ${s} L ${o} ${s} Z`);return h(l,n).path}({width:o.a.width,height:o.a.height,cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*lt*.5),padding:o.backgroundPadding*(o.a.fontSize*lt*.5)}):function({lines:t,lineHeight:e,width:r,align:n="left",padding:o=0,cornerRadius:i=0}){const a=m({lines:t,lineHeight:e,width:r,align:n});return g({rects:a,padding:o,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(K)),cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*lt*.5),lineHeight:lt*o.a.fontSize,padding:o.backgroundPadding*(o.a.fontSize*lt*.5),width:o.a.width,align:o.align}):"",[o.backgroundEnabled,o.curveEnabled,o.backgroundCornerRadius,o.a.fontSize,o.a.height,lt,o.backgroundPadding,o.a.width,o.align,K]),ht=A();let gt=0;o.curveEnabled||("middle"===o.verticalAlign?gt=(o.a.height-K.length*lt*o.a.fontSize)/2:"bottom"===o.verticalAlign&&(gt=o.a.height-K.length*lt*o.a.fontSize));const mt=o.curveEnabled?z(o.a.width,o.a.height,o.curvePower,o.a.fontSize):"",pt=rt?'"'+o.fontFamily+'"':G===o.fontFamily?"Arial":'"'+G+'"',xt=E(et);return r(e,{children:[t(a,{ref:j,x:o.a.x,y:o.a.y,rotation:o.a.rotation,hideInExport:!o.showInExport,listening:!1,visible:o.backgroundEnabled,opacity:o.backgroundOpacity*st,data:ft,fill:o.backgroundColor,offsetY:-gt}),t(a,{data:mt,stroke:d.stroke,strokeWidth:1,x:o.a.x,y:o.a.y,rotation:o.a.rotation,visible:!1}),t(l,Object.assign({ref:k,visible:o.curveEnabled,data:mt,text:et||o.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:xt},ut,dt,{strokeWidth:o.strokeWidth,lineJoin:"round",fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:`"${o.fontFamily}", "${G}"`,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration.trim(),letterSpacing:o.letterSpacing*o.a.fontSize,x:o.a.x,y:o.a.y,rotation:o.a.rotation,opacity:o._editModeEnabled?.3:st,hideInExport:!o.showInExport,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity})),t(s,Object.assign({ref:y,id:o.selectable?o.id:void 0,name:o.selectable?"element":"",hideInExport:!o.showInExport,editModeEnabled:o._editModeEnabled,x:o.a.x,y:o.a.y,rotation:o.a.rotation,width:o.a.width,height:o.a.height,text:et||o.placeholder,direction:xt},ut,dt,{lineJoin:"round",strokeWidth:o.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:pt,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration,align:o.align,verticalAlign:o.verticalAlign,draggable:ht?o.draggable&&V:o.draggable,preventDefault:!ht||V,opacity:o.curveEnabled?0:st,visible:!o._editModeEnabled,ellipsis:"ellipsis"===S.textOverflow,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,lineHeight:lt,letterSpacing:o.letterSpacing*o.a.fontSize,listening:!!o.selectable&&ct,onDragStart:()=>{$(!0)},onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{$(!1),o.set({x:t.target.x(),y:t.target.y()})},onClick:at,onTap:at,onTransformStart:()=>{var t,e;B(!0);const r=y.current;I.current=r.height(),N.current=r.rotation(),_.current=r.height();const n=null===(t=r.getStage())||void 0===t?void 0:t.findOne("Transformer");J.current=null!==(e=null==n?void 0:n.getActiveAnchor())&&void 0!==e?e:""},onTransform:t=>{var e,r,n;const i=t.target;null===(e=j.current)||void 0===e||e.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(r=i.getStage())||void 0===r?void 0:r.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),e=i.width()*t,r=o.a.fontSize;let n=e;e<r&&(n=r,ot.current&&i.position(ot.current)),i.width(n),i.scaleX(1),i.scaleY(1);let a=nt();if("ellipsis"===S.textOverflow){a=I.current}else{const t=Math.max(a,I.current);i.height(t),o.set({height:i.height()})}const s=S.textVerticalResizeEnabled?Math.max(a,I.current):nt();o.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:s}),i.skewX(0),i.skewY(0),tt()}if("top-center"===a||"bottom-center"===a){const e="resize"===S.textOverflow?nt():lt*o.a.fontSize,r=t.target.height()*t.target.scaleY();if(r<e){if(t.target.height(e),ot.current){if("top-center"===J.current){const r=N.current*Math.PI/180,n=_.current-e;t.target.x(ot.current.x-n*Math.sin(r)),t.target.y(ot.current.y+n*Math.cos(r))}else{t.target.position(ot.current)}}}else{t.target.height(r)}t.target.scaleY(1),t.target.scaleX(1),t.target.rotation(N.current),t.target.skewX(0),t.target.skewY(0),_.current=Math.max(e,r)}ot.current=t.target.position();const s=t.target.scaleX();null===(n=j.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:o.a.fontSize*s,width:t.target.width()*s,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*s,shadowBlur:o.shadowBlur*s,shadowOffsetX:o.shadowOffsetX*s,shadowOffsetY:o.shadowOffsetY*s,strokeWidth:o.strokeWidth*s})},onTransformEnd:t=>{var e;const r=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:Math.round(o.a.fontSize*r),width:Math.ceil(t.target.width()*r),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*r,shadowBlur:o.shadowBlur*r,shadowOffsetX:o.shadowOffsetX*r,shadowOffsetY:o.shadowOffsetY*r,strokeWidth:o.strokeWidth*r}),null===(e=j.current)||void 0===e||e.setAttrs({scaleX:1,scaleY:1}),B(!1)}})),H&&o.contentEditable&&t(i,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,children:t(Y,{textNodeRef:y,element:o,selectAll:X,cursorPosition:it.current,onBlur:()=>{o.toggleEditMode(!1)}})})]})});
|
|
1
|
+
import{jsx as t,Fragment as e,jsxs as r}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Group as i,Path as a,Text as s,TextPath as l}from"react-konva";import{Html as c}from"react-konva-utils";import{nodeAutorun as u}from"../utils/mobx.js";import d from"konva";import{parsePath as f,roundCommands as h}from"svg-round-corners/lib/index.js";import{generateBackgroundShapeFromRects as g,textLinesToRects as m}from"../utils/background-shape.js";import{useColor as p}from"./use-color.js";import{useWorkspaceStyle as x}from"./workspace-style.js";import{ROLES as w}from"../model/store.js";import{incrementLoader as v}from"../utils/loader.js";import{isFontLoaded as y}from"../utils/fonts.js";import{flags as S}from"../utils/flags.js";import{removeTags as b}from"../utils/text.js";import{getDir as E,getCurvePath as z,resolveLineHeight as k,normalizeStrokeLineJoin as O}from"../utils/text-html.js";import{applyFilter as R}from"./apply-filters.js";import{useFadeIn as A}from"./use-fadein.js";import{isTouchDevice as F}from"../utils/screen.js";import{isAlive as M,getParent as j}from"mobx-state-tree";import{getLimitedFontSize as L}from"./text-element/max-font-size.js";import{getOptimalCaretColor as T}from"./text-element/caret-color.js";let C;function H(){return C||(C=document.getElementById("polotno-text-style"),C||(C=document.createElement("style"),C.id="polotno-text-style",document.head.appendChild(C)),C)}d._fixTextRendering=!0;const X={border:"none",padding:"0px",overflow:"hidden",background:"none",outline:"none",resize:"none",overflowWrap:"break-word",whiteSpace:"pre-wrap",userSelect:"text",wordBreak:"normal",textTransform:"none"};export{getDir}from"../utils/text-html.js";const Y=o(({textNodeRef:e,element:r,onBlur:o,selectAll:i,cursorPosition:a})=>{const[s,l]=n.useState(X),c=e.current;n.useLayoutEffect(()=>{if(!c){return}const t={};t.width=c.width()-2*c.padding()+"px",t.height=c.height()-2*c.padding()+c.fontSize()*c.lineHeight()+"px",t.fontSize=c.fontSize()+"px",t.lineHeight=c.lineHeight()+.01,t.fontFamily=c.fontFamily(),t.textAlign=c.align(),t.color=c.fill(),t.fontWeight=r.fontWeight,t.fontStyle=r.fontStyle,t.letterSpacing=r.letterSpacing+"em",t.opacity=Math.max(r.a.opacity,.2),t.textTransform=r.textTransform,t.caretColor=T(r);const e=`\n .polotno-input::placeholder {\n color: ${s.color};\n opacity: 0.6;\n }\n `,n=H();n.innerHTML="",n.appendChild(document.createTextNode(e)),JSON.stringify(t)!==JSON.stringify(s)&&l(t)});const u=n.useRef(null);if(n.useLayoutEffect(()=>{var t;const e=u.current;if(!e){return}null===(t=u.current)||void 0===t||t.focus({preventScroll:!0});const r=a||e.value.length;e.selectionStart=e.selectionEnd=r,i&&(null==e||e.select(),document.execCommand("selectAll",!1,void 0))},[]),n.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=u.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]),!c){return null}let d=0;const f=c.textArr.length*c.lineHeight()*c.fontSize();"middle"===r.verticalAlign&&(d=(r.a.height-f)/2),"bottom"===r.verticalAlign&&(d=r.a.height-f);const h=b(r.text);return t("textarea",{className:"polotno-input",ref:u,dir:E(h),style:Object.assign(Object.assign(Object.assign({},X),s),{paddingTop:d+"px"}),value:h,onChange:t=>{const e=L({oldText:r.text,newText:t.target.value,element:r});r.set({text:t.target.value,fontSize:e})},placeholder:r.placeholder,onBlur:o})}),P=e=>t(c,{children:t(Y,Object.assign({},e))});export const useFontLoader=(t,e,r,o,i)=>{const[a,s]=n.useReducer(t=>t+1,0),l=n.useRef(y(e,r,o)),c=n.useRef(null);return n.useLayoutEffect(()=>{if(l.current=y(e,r,o),l.current){return}let n=!0;return(async()=>{l.current=!1,s();const a=v(`text ${e}`);await t.loadFont(e,r,o,i),n?(c.current=a,l.current=!0,s()):a()})(),()=>{c.current&&(c.current(),c.current=null),n=!1}},[e,r,o]),n.useEffect(()=>{l.current&&setTimeout(()=>{c.current&&(c.current(),c.current=null)})},[l.current]),[l.current]};export const useFontFamiliesLoader=(t,e,r,o,i)=>{const[a,s]=n.useReducer(t=>t+1,0),l=e.join("\0"),c=n.useRef(e.every(t=>y(t,r,o))),u=n.useRef(null);return n.useLayoutEffect(()=>{if(c.current=e.every(t=>y(t,r,o)),c.current){return}let n=!0;return(async()=>{c.current=!1,s();const a=v(`text fonts ${l}`);await Promise.all(e.map(e=>t.loadFont(e,r,o,i))),n?(u.current=a,c.current=!0,s()):a()})(),()=>{u.current&&(u.current(),u.current=null),n=!1}},[l,r,o]),n.useEffect(()=>{c.current&&setTimeout(()=>{u.current&&(u.current(),u.current=null)})},[c.current]),[c.current]};export const getLineHeight=({fontLoaded:t,fontFamily:e,fontSize:r,lineHeight:o})=>n.useMemo(()=>k({fontFamily:e,fontSize:r,lineHeight:o}),[t,e,r,o]);export function usePrevious(t){const e=n.useRef(t),r=n.useRef(t);return n.useMemo(()=>{r.current=e.current,e.current=t},[t]),r.current}function W(t,e,r=!1){const n=t.fontSize(),o=t.height(),i=b(e.text);let a=e.a.fontSize;t.height(void 0);const s=Math.round(2*e.a.fontSize)-1;for(let l=1;l<s;l++){const n=e.a.height&&t.height()>e.a.height;let o=i.split("\n").join(" ").split(/[\s-]+/).reduce((t,e)=>(e=e.toLowerCase(),/[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF\uAC00-\uD7AF]/.test(e)?t.concat(e.split("")):t.concat(e)),[]),s=t.textArr.map(t=>t.text.toLowerCase()).join(";");const l=o.find(t=>!s.includes(t)||(s=s.replace(t,""),!1));if(!(n||l&&!r)){break}a-=.5,t.fontSize(a)}return t.fontSize(n),t.height(o),a}export{getCurvePath}from"../utils/text-html.js";export const TextElement=o(({element:o,store:c})=>{const{textOverflowIndicatorStyle:d}=x(),y=n.useRef(null),k=n.useRef(null),L=n.useRef(null),T=n.useRef([]),C=n.useRef(!0),[,H]=n.useReducer(t=>t+1,0),{editorEnabled:X,selectAll:Y}=(t=>{const[e,r]=n.useState(!1),o=n.useRef(!1);return n.useEffect(()=>{var e=!0;return setTimeout(()=>{e&&(t._editModeEnabled&&(o.current=!0),r(!0),setTimeout(()=>{o.current=!1},50))},50),()=>{e=!1}},[]),{editorEnabled:e&&t._editModeEnabled,selectAll:o.current}})(o),[B,D]=n.useState(!1),[$,I]=n.useState(!1),N=n.useRef(o.a.height),J=n.useRef(0),_=n.useRef(""),V=n.useRef(0),q=o.isSelected,U=usePrevious(q),{textVerticalResizeEnabled:Z}=S,G=S.autoDeleteEmptyText,K=usePrevious(o.fontFamily),[Q,tt]=n.useState([]);n.useEffect(()=>{var t,e;const r=null!==(e=null===(t=y.current)||void 0===t?void 0:t.textArr)&&void 0!==e?e:[];JSON.stringify(r)!==JSON.stringify(Q)&&tt(r)}),n.useEffect(()=>{if(o.a.width||"tablecell"===o.type){return}const t=y.current;t.width(600),o.set({width:1.4*t.getTextWidth()})},[]),n.useEffect(()=>{U&&!q&&G&&""===o.text&&o.removable&&!o.placeholder&&c.deleteElements([o.id])},[G,o.placeholder,o.removable,o.text,q,U]);const et=()=>{if(o.curveEnabled){const t=y.current;null==t||t.clearCache(),null==t||t.setAttrs({filters:[]});const e=k.current;e&&R(e,o)}else{const t=y.current;t&&R(t,o)}};n.useLayoutEffect(()=>{if(!$){return u(o,()=>{et()})}}),n.useEffect(()=>{const t=T.current;t.length>0&&(T.current=[],t.forEach(t=>t()))}),n.useEffect(()=>()=>{C.current=!1;const t=T.current;t.length>0&&(T.current=[],t.forEach(t=>t()))},[]);let rt=b(o.text);"uppercase"===o.textTransform&&(rt=rt.toUpperCase());const[nt]=useFontLoader(c,o.fontFamily,o.fontStyle,o.fontWeight,o.text||o.placeholder),ot=()=>{if(o.curveEnabled){const t=k.current;return t.getSelfRect().height||t.fontSize()}const t=y.current.clone({height:void 0}),e=Math.ceil(t.fontSize()*t.lineHeight()*t.textArr.length+1);return t.destroy(),e};n.useLayoutEffect(()=>{if(!nt){return}if("tablecell"===o.type){const{textOverflow:t}=S;if("resize"===t){const t=ot(),e=M(o)?j(o,2):null;(null==e?void 0:e.setCellContentHeight)&&e.setCellContentHeight(o.id,t)}else if("change-font-size"===t){const t=y.current;if(t){const e=W(t,o,S.textSplitAllowed);e!==o.fontSize&&c.history.ignore(()=>{o.set({fontSize:e})})}}return}const{textOverflow:t,textSplitAllowed:e}=S,r=(t,e,r,n)=>{const i=v(`text ${o.id}`),a=()=>{c.history.ignore(t,e,r).then(()=>{C.current?(T.current.push(i),H()):i()})};n?queueMicrotask(a):a()};if(!o.height){const t=ot();return void r(()=>{o.height||o.set({height:t})},void 0,void 0,!0)}if(!c.isPlaying){if("change-font-size"!==t||B){if("resize"===t){const t=ot();Z&&o.height<t&&!B&&r(()=>{var e;M(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0),Z||o.height===t||B||r(()=>{var e;M(o)&&o.set({height:t}),null===(e=y.current)||void 0===e||e.height(t)},!1,!0)}}else{const t=y.current,n=o.curveEnabled?o.fontSize:W(t,o,e);if(n!==o.fontSize){return void r(()=>{o.set({fontSize:n})},!1,!0)}const i=ot();o.height===i||Z||r(()=>{o.set({height:i})},!1,!0)}}}),n.useLayoutEffect(()=>{var t;if(nt&&o.curveEnabled){const e=null===(t=k.current)||void 0===t?void 0:t.getSelfRect().width;if(e){const t=e-o.a.width,r=o.a.rotation*Math.PI/180,n=-t/2*Math.cos(r),i=-t/2*Math.sin(r);o.set({width:e,x:o.a.x+n,y:o.a.y+i})}}},[nt,o.curveEnabled,o.curvePower,o.text,o.fontSize,o.fontFamily,o.fontWeight,o.fontStyle,o.letterSpacing]),n.useLayoutEffect(()=>{const t=y.current;t&&(t.width(t.width()+1e-8),t.width(t.width()-1e-8),t._setTextData(),et())},[nt]);const it=n.useRef(null),at=n.useRef(0),st=t=>{t.evt.preventDefault();const e=c.selectedShapes.find(t=>t===o);e&&o.contentEditable&&(at.current=function(t){var e;const r=t.target,n=function(t){var e=t.getAbsoluteTransform().copy();e.invert();var r=t.getStage().getPointerPosition();return e.point(r)}(r),o=r.textArr,i=Math.floor(n.y/(r.fontSize()*r.lineHeight())),a=o.slice(0,i).reduce((t,e)=>t+e.text.length,i),s=null!==(e=o[i])&&void 0!==e?e:o[0];let l=0;return"right"===r.align()?l=r.width()-s.width:"center"===r.align()&&(l=r.width()/2-s.width/2),a+Math.round((n.x-l)/s.width*s.text.length)}(t),o.toggleEditMode())},lt=!rt&&o.placeholder?.6:o.a.opacity;A(y,lt);const ct=getLineHeight({fontLoaded:nt,fontFamily:o.fontFamily,fontSize:o.a.fontSize,lineHeight:o.lineHeight}),ut=o.selectable||c.role===w.ADMIN,dt=p(o),ft=p(o,o.stroke,"stroke"),ht=n.useMemo(()=>o.backgroundEnabled?o.curveEnabled?function({width:t,height:e,padding:r=0,cornerRadius:n=0}){const o=-r,i=-r,a=t+r,s=e+r,l=f(`M ${o} ${i} L ${a} ${i} L ${a} ${s} L ${o} ${s} Z`);return h(l,n).path}({width:o.a.width,height:o.a.height,cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*ct*.5),padding:o.backgroundPadding*(o.a.fontSize*ct*.5)}):function({lines:t,lineHeight:e,width:r,align:n="left",padding:o=0,cornerRadius:i=0}){const a=m({lines:t,lineHeight:e,width:r,align:n});return g({rects:a,padding:o,cornerRadius:i})}({lines:JSON.parse(JSON.stringify(Q)),cornerRadius:o.backgroundCornerRadius*(o.a.fontSize*ct*.5),lineHeight:ct*o.a.fontSize,padding:o.backgroundPadding*(o.a.fontSize*ct*.5),width:o.a.width,align:o.align}):"",[o.backgroundEnabled,o.curveEnabled,o.backgroundCornerRadius,o.a.fontSize,o.a.height,ct,o.backgroundPadding,o.a.width,o.align,Q]),gt=F();let mt=0;o.curveEnabled||("middle"===o.verticalAlign?mt=(o.a.height-Q.length*ct*o.a.fontSize)/2:"bottom"===o.verticalAlign&&(mt=o.a.height-Q.length*ct*o.a.fontSize));const pt=o.curveEnabled?z(o.a.width,o.a.height,o.curvePower,o.a.fontSize):"",xt=nt?'"'+o.fontFamily+'"':K===o.fontFamily?"Arial":'"'+K+'"',wt=E(rt);return r(e,{children:[t(a,{ref:L,x:o.a.x,y:o.a.y,rotation:o.a.rotation,hideInExport:!o.showInExport,listening:!1,visible:o.backgroundEnabled,opacity:o.backgroundOpacity*lt,data:ht,fill:o.backgroundColor,offsetY:-mt}),t(a,{data:pt,stroke:d.stroke,strokeWidth:1,x:o.a.x,y:o.a.y,rotation:o.a.rotation,visible:!1}),t(l,Object.assign({ref:k,visible:o.curveEnabled,data:pt,text:rt||o.placeholder,listening:!1,align:"center",textBaseline:"middle",direction:wt},dt,ft,{strokeWidth:o.strokeWidth,lineJoin:O(o.strokeLineJoin),fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:`"${o.fontFamily}", "${K}"`,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration.trim(),letterSpacing:o.letterSpacing*o.a.fontSize,x:o.a.x,y:o.a.y,rotation:o.a.rotation,opacity:o._editModeEnabled?.3:lt,hideInExport:!o.showInExport,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity})),t(s,Object.assign({ref:y,id:o.selectable?o.id:void 0,name:o.selectable?"element":"",hideInExport:!o.showInExport,editModeEnabled:o._editModeEnabled,x:o.a.x,y:o.a.y,rotation:o.a.rotation,width:o.a.width,height:o.a.height,text:rt||o.placeholder,direction:wt},dt,ft,{lineJoin:O(o.strokeLineJoin),strokeWidth:o.strokeWidth,fillAfterStrokeEnabled:!0,fontSize:o.a.fontSize,fontFamily:xt,fontStyle:o.fontStyle+" "+o.fontWeight,textDecoration:o.textDecoration,align:o.align,verticalAlign:o.verticalAlign,draggable:gt?o.draggable&&q:o.draggable,preventDefault:!gt||q,opacity:o.curveEnabled?0:lt,visible:!o._editModeEnabled,ellipsis:"ellipsis"===S.textOverflow,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,lineHeight:ct,letterSpacing:o.letterSpacing*o.a.fontSize,listening:!!o.selectable&&ut,onDragStart:()=>{I(!0)},onDragMove:t=>{o.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{I(!1),o.set({x:t.target.x(),y:t.target.y()})},onClick:st,onTap:st,onTransformStart:()=>{var t,e;D(!0);const r=y.current;N.current=r.height(),J.current=r.rotation(),V.current=r.height();const n=null===(t=r.getStage())||void 0===t?void 0:t.findOne("Transformer");_.current=null!==(e=null==n?void 0:n.getActiveAnchor())&&void 0!==e?e:""},onTransform:t=>{var e,r,n;const i=t.target;null===(e=L.current)||void 0===e||e.setAttrs({x:i.x(),y:i.y(),rotation:i.rotation(),scale:i.scale()});const a=(null===(r=i.getStage())||void 0===r?void 0:r.findOne("Transformer")).getActiveAnchor();if("middle-left"===a||"middle-right"===a){const t=i.scaleX(),e=i.width()*t,r=o.a.fontSize;let n=e;e<r&&(n=r,it.current&&i.position(it.current)),i.width(n),i.scaleX(1),i.scaleY(1);let a=ot();if("ellipsis"===S.textOverflow){a=N.current}else{const t=Math.max(a,N.current);i.height(t),o.set({height:i.height()})}const s=S.textVerticalResizeEnabled?Math.max(a,N.current):ot();o.set({x:i.x(),width:i.width(),rotation:i.rotation(),height:s}),i.skewX(0),i.skewY(0),et()}if("top-center"===a||"bottom-center"===a){const e="resize"===S.textOverflow?ot():ct*o.a.fontSize,r=t.target.height()*t.target.scaleY();if(r<e){if(t.target.height(e),it.current){if("top-center"===_.current){const r=J.current*Math.PI/180,n=V.current-e;t.target.x(it.current.x-n*Math.sin(r)),t.target.y(it.current.y+n*Math.cos(r))}else{t.target.position(it.current)}}}else{t.target.height(r)}t.target.scaleY(1),t.target.scaleX(1),t.target.rotation(J.current),t.target.skewX(0),t.target.skewY(0),V.current=Math.max(e,r)}it.current=t.target.position();const s=t.target.scaleX();null===(n=L.current)||void 0===n||n.setAttrs({scaleX:1,scaleY:1}),t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:o.a.fontSize*s,width:t.target.width()*s,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*s,shadowBlur:o.shadowBlur*s,shadowOffsetX:o.shadowOffsetX*s,shadowOffsetY:o.shadowOffsetY*s,strokeWidth:o.strokeWidth*s})},onTransformEnd:t=>{var e;const r=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),o.set({fontSize:Math.round(o.a.fontSize*r),width:Math.ceil(t.target.width()*r),x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),height:t.target.height()*r,shadowBlur:o.shadowBlur*r,shadowOffsetX:o.shadowOffsetX*r,shadowOffsetY:o.shadowOffsetY*r,strokeWidth:o.strokeWidth*r}),null===(e=L.current)||void 0===e||e.setAttrs({scaleX:1,scaleY:1}),D(!1)}})),X&&o.contentEditable&&t(i,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,children:t(P,{textNodeRef:y,element:o,selectAll:Y,cursorPosition:at.current,onBlur:()=>{o.toggleEditMode(!1)}})})]})});
|
package/canvas/tooltip.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Html as l}from"react-konva-utils";import{getTotalClientRect as r}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{flags as a}from"../utils/flags.js";import{DuplicateButton as u}from"../toolbar/duplicate-button.js";import{RemoveButton as c}from"../toolbar/remove-button.js";import{PositionPicker as d}from"../toolbar/position-picker.js";import{GroupButton as m}from"../toolbar/group-button.js";import{Navbar as p}from"../primitives/navbar.js";function f(t,e){return t.classList.contains(e)?t:t.parentElement?f(t.parentElement,e):null}const v=()=>null;export const Tooltip=o(({store:o,page:h,components:g,stageRef:b,tooltipSafeArea:y})=>{var E;const x=o.selectedShapes.every(t=>t.page===h),C=n.useRef(null),[k,j]=n.useState(!1),w=o._hasCroppedImages;n.useEffect(()=>{var t,e,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(t=null==b?void 0:b.current)||void 0===t||t.on("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.on("dragend",l);const r=null===(n=null==b?void 0:b.current)||void 0===n?void 0:n.findOne("Transformer");return null==r||r.on("transformstart",o),null==r||r.on("transformend",l),()=>{var t,e;null===(t=null==b?void 0:b.current)||void 0===t||t.off("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,I]=n.useState({fit:!0,needCalculate:!1,token:Math.random()});function R(){if(!C.current){return}if(!N.needCalculate){return}const
|
|
1
|
+
import{jsx as t,jsxs as e}from"react/jsx-runtime";import n from"react";import{observer as o}from"mobx-react-lite";import{Html as l}from"react-konva-utils";import{getTotalClientRect as r}from"../utils/math.js";import{extendToolbar as i}from"../toolbar/element-container.js";import{TextAiWrite as s}from"../toolbar/text-ai-write.js";import{flags as a}from"../utils/flags.js";import{DuplicateButton as u}from"../toolbar/duplicate-button.js";import{RemoveButton as c}from"../toolbar/remove-button.js";import{PositionPicker as d}from"../toolbar/position-picker.js";import{GroupButton as m}from"../toolbar/group-button.js";import{Navbar as p}from"../primitives/navbar.js";function f(t,e){return t.classList.contains(e)?t:t.parentElement?f(t.parentElement,e):null}const v=()=>null;export const Tooltip=o(({store:o,page:h,components:g,stageRef:b,tooltipSafeArea:y})=>{var E;const x=o.selectedShapes.every(t=>t.page===h),C=n.useRef(null),[k,j]=n.useState(!1),w=o._hasCroppedImages;n.useEffect(()=>{var t,e,n;const o=()=>{j(!0)},l=()=>{j(!1)};null===(t=null==b?void 0:b.current)||void 0===t||t.on("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.on("dragend",l);const r=null===(n=null==b?void 0:b.current)||void 0===n?void 0:n.findOne("Transformer");return null==r||r.on("transformstart",o),null==r||r.on("transformend",l),()=>{var t,e;null===(t=null==b?void 0:b.current)||void 0===t||t.off("dragstart",o),null===(e=null==b?void 0:b.current)||void 0===e||e.off("dragend",l),null==r||r.off("transformstart",o),null==r||r.off("transformend",l)}},[]);const[N,I]=n.useState({fit:!0,needCalculate:!1,token:Math.random()});function R(){var t;if(!C.current){return}if(!N.needCalculate){return}const e=f(C.current,"polotno-workspace-container");if(!e){return}const n=e.getBoundingClientRect(),o=C.current.getBoundingClientRect(),l=o.top-n.top,r=o.bottom-n.top,i=(null==y?void 0:y.top)||0,s=null!==(t=null==y?void 0:y.bottom)&&void 0!==t?t:45,a=null==b?void 0:b.current;let u=-1/0,c=1/0;if(a){const t=a.container().getBoundingClientRect(),e=a.scaleY();u=t.top+a.y()+S.y*e-n.top,c=t.top+a.y()+(S.y+S.height)*e-n.top}const d=l>=20+i&&u-r>=48,m=r-n.height<=-20-s&&l-c>=48;I(d?{fit:!0,needCalculate:!1,token:N.token}:m?{fit:!1,needCalculate:!1,token:N.token}:{fit:N.fit,needCalculate:!1,token:N.token})}if(n.useEffect(()=>{0!==o.selectedElements.length&&I({fit:!0,needCalculate:!0,token:Math.random()})},[o.selectedElements,k,o.scale]),n.useLayoutEffect(()=>{const t=setTimeout(()=>{R()},100);return()=>{clearTimeout(t)}},[N.needCalculate,C.current,N.token]),n.useEffect(()=>{if(!(null==b?void 0:b.current)){return}const t=f(b.current.content,"polotno-workspace-inner");if(!t){return}const e=()=>{o.selectedElements.length&&I({fit:!0,needCalculate:!0,token:Math.random()})};return null==t||t.addEventListener("scroll",e),()=>{null==t||t.removeEventListener("scroll",e)}},[]),0===o.selectedShapes.length){return null}if(k){return null}if(!x){return null}if(o.activePage!==h){return null}if(w){return null}const S=r(o.selectedShapes),T=(null==g?void 0:g.Position)||d,M=(null==g?void 0:g.Duplicate)||u,O=(null==g?void 0:g.Remove)||c,B=(null==g?void 0:g.Group)||m,Y=(null==g?void 0:g.Lock)||v,F=null===(E=o.selectedElements[0])||void 0===E?void 0:E.type,L=Object.assign(Object.assign({},a.aiTextEnabled?{TextAiWrite:s}:{}),g||{}),P=i({components:L,type:F,usedItems:[]});return t(l,{parentNodeFunc:({stage:t})=>{var e,n;return(null===(e=null==t?void 0:t.container())||void 0===e?void 0:e.closest(".polotno-workspace-container"))||(null===(n=null==t?void 0:t.container())||void 0===n?void 0:n.parentNode)},transformFunc:t=>{var e,n;const o=S.x+S.width/2,l=null===(e=null==b?void 0:b.current)||void 0===e?void 0:e.container(),r=(null==l?void 0:l.getBoundingClientRect())||{left:0,top:0,width:0,height:0,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},i=null==l?void 0:l.closest(".polotno-workspace-container"),s=(null==i?void 0:i.getBoundingClientRect())||{left:0,top:0,width:Number.POSITIVE_INFINITY,height:Number.POSITIVE_INFINITY,right:0,bottom:0,x:0,y:0,toJSON:()=>({})},a=r.left-s.left,u=r.top-s.top,c=C.current?C.current.getBoundingClientRect().height:34,d=((null==y?void 0:y.top)||0)+8,m=u+t.y+S.y*t.scaleY;let p=N.fit;if(p){const t=m-80,e=d+c/2;Math.max(e,t)+c/2>m-48&&(p=!1)}const f=p?S.y*t.scaleY-80:S.y*t.scaleY+S.height*t.scaleY+80;let v=a+t.x+o*t.scaleX,h=v-S.width*t.scaleX/2,g=v+S.width*t.scaleX/2;const E=Math.min(50,S.width/2*t.scaleX),x=g>=E&&h<=s.width-E,k=C.current?C.current.getBoundingClientRect().width:0,j=(null==y?void 0:y.left)||0,w=(null==y?void 0:y.right)||0;if(Number.isFinite(s.width)&&k>0&&x){const t=8+k/2+j,e=s.width-8-k/2-w;e>=t&&(v=Math.max(t,Math.min(v,e)))}g<E&&(v-=k+8),h>s.width-E&&(v+=k+8);let I=u+t.y+f;const R=C.current?C.current.getBoundingClientRect().height:34,T=((null==y?void 0:y.top)||0)+8,M=(null!==(n=null==y?void 0:y.bottom)&&void 0!==n?n:45)+8;return Number.isFinite(s.height)&&(I=Math.max(T+R/2,I),I=Math.min(s.height-M-R/2,I)),Object.assign(Object.assign({},t),{x:v,y:I,scaleX:1,scaleY:1})},divProps:{style:{pointerEvents:"none",position:"absolute",visibility:N.needCalculate?"hidden":"visible",zIndex:9}},children:t("div",{ref:t=>{C.current=t,!C.current&&t&&R()},className:"polotno-selection-tooltip",style:{pointerEvents:"none"},children:e(p,{floating:!0,height:34,className:"pn:gap-0.5 pn:bg-popover pn:px-0.5",style:{transform:"translate(-50%, -50%)",pointerEvents:"auto"},children:[P.map(e=>{const n=L[e];return t(n,{elements:o.selectedElements,element:o.selectedElements[0],store:o},e)}),t(B,{store:o}),t(Y,{store:o}),t(M,{store:o}),t(O,{store:o}),t(T,{store:o})]})})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"react";import t from"konva";import{isAlive as o}from"mobx-state-tree";import{applyFiltersToCanvas as r,hasActiveFilters as i,getFiltersDepsKey as n}from"./apply-filters.js";import{trySetCanvasSize as s}from"../utils/canvas.js";export const useFilteredSource=(m,a)=>{const c=n(m),f=o(m)&&i(m),d=e=>{if(!a||!o(m)){return}const t=a instanceof HTMLVideoElement?a.videoWidth:a.width,i=a instanceof HTMLVideoElement?a.videoHeight:a.height;if(!t||!i){return}s(e,t,i);const n=e.getContext("2d");n&&(n.drawImage(a,0,0),r(e,m))},u=e.useMemo(()=>{if(!f||!a){return}const e=document.createElement("canvas");return d(e),e},[a,f,c]);return e.useEffect(()=>()=>{u&&t.Util.releaseCanvas(u)},[u]),[u||a||void 0,()=>{u&&d(u)}]};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"react";import{nodeAutorun as r}from"../utils/mobx.js";import{Input as t,UrlSource as n,BufferSource as u,CanvasSink as
|
|
1
|
+
import e from"react";import{nodeAutorun as r}from"../utils/mobx.js";import{Input as t,UrlSource as n,BufferSource as u,CanvasSink as a,ALL_FORMATS as i}from"mediabunny";import{incrementLoader as c,triggerLoadError as s}from"../utils/loader.js";import{polotnoError as o}from"../utils/errors.js";import{getElementTimeRange as l,getVideoRestMs as d}from"../utils/timeline.js";const f=.05;export const useMediabunnyVideo=(m,p,g)=>{const[h,v]=e.useState({input:null,videoSink:null,duration:0,isReady:!1,error:null});e.useRef(h).current=h;const w=e.useRef(0),b=e.useRef(null),y=e.useRef(null),T=e.useRef(null),R=e.useRef(null),k=e.useRef(null),E=e.useRef(null),S=e.useRef(!1),$=e.useRef(null),x=e.useRef([]),O=e.useRef(null),I=e.useRef(!1),[,j]=e.useReducer(e=>e+1,0);return e.useEffect(()=>{if(!g){return}let e=!0;const r=++w.current;let l=null;return(async()=>{try{if(!e||r!==w.current){return}l=c(`mediabunny init ${m.id}`);const s=await async function(e){if(function(e){return e.startsWith("data:")}(e)){const r=function(e){const r=e.indexOf(",");if(-1===r){throw new Error("Invalid data URL format")}const t=e.slice(r+1),n=atob(t),u=new Uint8Array(n.length);for(let a=0;a<n.length;a++){u[a]=n.charCodeAt(a)}return u.buffer}(e);return new u(r)}if(function(e){return e.startsWith("file://")}(e)){try{const r=await fetch(e),t=await r.arrayBuffer();return new u(t)}catch(r){throw new Error(`Failed to load file URL: ${e}. File URLs may not be supported in this environment. Error: ${r}`)}}return new n(e)}(m.src);if(!e||r!==w.current){return void(l&&(l(),l=null))}const d=new t({source:s,formats:i}),f=await d.computeDuration(),p=await d.getPrimaryVideoTrack();if(!p){throw o("VIDEO_FAILED","No video track found",{reason:"no-video-track"})}if(null===p.codec){throw o("VIDEO_FAILED","Unsupported video codec",{reason:"unsupported-codec"})}if(!await p.canDecode()){throw o("VIDEO_FAILED","Unable to decode the video track",{reason:"cannot-decode"})}const g=await p.canBeTransparent(),h=new a(p,{poolSize:5,fit:"contain",alpha:g});if(!e||r!==w.current){return d.dispose(),void(l&&(l(),l=null))}l&&(l(),l=null),v(e=>Object.assign(Object.assign({},e),{input:d,videoSink:h,duration:f,isReady:!0,error:null}))}catch(d){if(console.error("Failed to initialize mediabunny:",d),l&&(l(),l=null),e&&r===w.current){const e=`Failed to initialize mediabunny for video ${m.id}: ${d}`;s(o("VIDEO_FAILED",e,Object.assign({reason:"load"},null==d?void 0:d.details),d)),v(e=>Object.assign(Object.assign({},e),{error:String(d),isReady:!1}))}}})(),()=>{e=!1,l&&(l(),l=null)}},[m.src,g]),e.useEffect(()=>()=>{y.current&&(y.current.return(),y.current=null),b.current&&(b.current(),b.current=null),T.current=null,R.current=null,k.current=null,S.current=!1,$.current=null,x.current=[],O.current=null,I.current=!1,v({input:null,videoSink:null,duration:0,isReady:!1,error:null})},[g]),e.useEffect(()=>{if(!g||!h.isReady||!h.videoSink){return}const e=++w.current,t="string"==typeof m.src?m.src.slice(0,120):String(m.src),n=(e,r={},n="debug")=>{let u="";try{u=JSON.stringify(Object.assign(Object.assign({},r),{timeCalc:E.current}))}catch(i){u=`[unserializable extras: ${String(i)}]`}const a=`mediabunny event=${e} elementId=${m.id} targetTime=${k.current} duration=${h.duration} lastFrameTimestamp=${R.current} hasIterator=${Boolean(y.current)} prefetchSize=${x.current.length} srcHint=${t} extras=${u}`;"error"===n?console.error(a):"warn"===n?console.warn(a):console.debug(a)},u=e=>{const r=h.duration||0;if(!r||!Number.isFinite(r)){return e}const t=r>f?r-f:r;return Math.max(0,Math.min(e,t))},a=e=>{const r=h.duration||0;return!(!r||!Number.isFinite(r))&&r-e<=.050001000000000004},i=e=>{let r=T.current;r&&r.width===e.canvas.width&&r.height===e.canvas.height||(r||(r=document.createElement("canvas"),T.current=r),r.width=e.canvas.width,r.height=e.canvas.height);const t=r.getContext("2d");t&&(t.clearRect(0,0,r.width,r.height),t.drawImage(e.canvas,0,0)),R.current=e.timestamp},s=e=>{const r=y.current;r&&(I.current||(I.current=!0,O.current=(async()=>{try{for(;x.current.length<4&&e===w.current;){const t=await r.next();if(e!==w.current){return}if(t.done||!t.value){break}x.current.push({timestamp:t.value.timestamp,frame:t.value})}}catch(t){}finally{I.current=!1,O.current=null}})()))},o=e=>{const r=x.current;for(let t=0;t<r.length;t++){if(Math.abs(r[t].timestamp-e)<f){const e=r[t];return x.current=r.slice(t+1),e}}return null},v=()=>{x.current=[]},D=async(e,r,t=0)=>{const c=u(e),l=(e=>{const r=R.current;return null===r||e<r-f||e>r+.5})(c)?"seek":"iterate";try{const t=h.videoSink,u=R.current;if(null!==u&&Math.abs(u-c)<f){return void(k.current=e)}const m=o(c);if(m){return i(m.frame),k.current=e,s(r),void j()}if(O.current){await O.current;const t=o(c);if(t){return i(t.frame),k.current=e,s(r),void j()}}if(v(),"seek"===l){y.current&&(await y.current.return(),y.current=null);const u=t.canvases(c);y.current=u;const o=await u.next();if(r!==w.current){return void(y.current&&(await y.current.return(),y.current=null))}if(o.done||!o.value){if(a(c)||n("iterator_exhausted",{mode:l,requestedTargetTime:e,clampedTargetTime:c},"warn"),r===w.current&&!a(c)){try{y.current&&(await y.current.return(),y.current=null),v();const n=t.canvases(c);y.current=n;const u=await n.next();!u.done&&u.value&&(i(u.value),s(r),k.current=e,j())}catch(d){}}return}i(o.value),s(r)}else{const u=y.current;if(!u){return}let o=!1;for(;r===w.current;){const m=await u.next();if(r!==w.current){break}if(m.done||!m.value){if(a(c)||n("iterator_exhausted",{mode:l,requestedTargetTime:e,clampedTargetTime:c},"warn"),!o&&!a(c)){o=!0;try{y.current&&(await y.current.return(),y.current=null),v();const e=t.canvases(c);y.current=e;const n=await e.next();if(r!==w.current){break}if(n.done||!n.value){break}i(n.value),s(r);break}catch(d){break}}break}const p=m.value;if(i(p),Math.abs(p.timestamp-c)<f){s(r);break}if(p.timestamp>c){s(r);break}}}k.current=e,j()}catch(m){const u=m instanceof Error?{name:m.name,message:m.message,stack:m.stack}:{message:String(m)},a=m instanceof Error?`${m.name}: ${m.message}`:String(m),i=a.includes("Unsupported configuration")||a.includes("isConfigSupported")||a.includes("OperationError");if(n("frame_process_failed",{mode:l,requestedTargetTime:e,clampedTargetTime:c,unsupportedConfigAttempt:t,isUnsupportedConfig:i,error:u},"error"),i&&t<1){try{y.current&&(await y.current.return(),y.current=null),v(),O.current=null,I.current=!1,R.current=null,await D(e,r,t+1)}catch(d){}}}},F=r(m,()=>{const r=h.videoSink,t=h.duration;if(!r||!t){return}const n=m.startTime*t*1e3,a=t*(m.endTime-m.startTime)*1e3,{start:i}=l(m.animations,m.page.duration),s=d(p.currentTime,m.page.startTime,i,a,n,m.speed),o=s/1e3,f=u(o);E.current={pageStartTime:m.page.startTime,storeCurrentTime:p.currentTime,offsetMs:n,durationMs:a,restMs:s,targetTime:o,clampedTargetTime:f,startTime:m.startTime,endTime:m.endTime,videoDuration:t},((e,r)=>{S.current?$.current=e:(S.current=!0,b.current||(b.current=c(`mediabunny video frame ${m.id}`)),(async()=>{let t=e;for(;null!==t&&r===w.current;){await D(t,r),t=$.current,$.current=null}b.current&&(b.current(),b.current=null),S.current=!1})())})(f,e)});return()=>{F(),w.current++,b.current&&(b.current(),b.current=null)}},[g,h.isReady,h.videoSink,h.duration,p,m]),g&&h.isReady?T.current:null};
|
|
@@ -6,7 +6,7 @@ export declare const useCornerRadiusAndCrop: (element: VideoElementType, image:
|
|
|
6
6
|
y: number;
|
|
7
7
|
width: number;
|
|
8
8
|
height: number;
|
|
9
|
-
}, pixelRatio: number, cornerRadius?: number, skipDownscale?: boolean) => readonly [
|
|
9
|
+
}, pixelRatio: number, cornerRadius?: number, skipDownscale?: boolean) => readonly [HTMLVideoElement | HTMLCanvasElement | undefined, () => void];
|
|
10
10
|
type Props = {
|
|
11
11
|
store: StoreType;
|
|
12
12
|
element: VideoElementType;
|
package/canvas/video-element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{nodeAutorun as n}from"../utils/mobx.js";import{Arc as a,Group as d,Image as h,Rect as s,Text as l,Transformer as c}from"react-konva";import{ROLES as u}from"../model/store.js";import g from"use-image";import f from"konva";import{Portal as m}from"react-konva-utils";import{useWorkspaceStyle as p}from"./workspace-style.js";import{incrementLoader as v,triggerLoadError as w}from"../utils/loader.js";import*as x from"../utils/svg.js";import{flags as M}from"../utils/flags.js";import{applyFilter as y}from"./apply-filters.js";import{useFadeIn as E}from"./use-fadein.js";import{isTouchDevice as b}from"../utils/screen.js";import{useMediabunnyVideo as L}from"./use-mediabunny-video.js";import{getElementTimeRange as T,getVideoRestMs as C}from"../utils/timeline.js";function R(){return document.createElement("canvas")}const S=new window.Image;S.src=x.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" fill="white"/>\n <path d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');const I=new window.Image;I.src=x.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" fill="white"/>\n <path opacity="0.6" d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" fill="white"/>\n <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');export const useCornerRadiusAndCrop=(e,t,r,o,n=0,a=!1)=>{var d,h;const s=Math.floor(Math.max(e.width*o,1)),l=Math.floor(Math.max(e.height*o,1)),c=Math.min(n*o,s/2,l/2),u=Math.max(e.width/r.width,e.height/r.height)*o,g=(null===(d=e.page)||void 0===d?void 0:d._exportingOrRendering)&&M.imageDownScalingEnabled&&u<1&&!a,m=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,p=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height,v=0===r.x&&0===r.y&&r.width===m&&r.height===p,w=i.useMemo(()=>{if(t&&m&&p){return v&&0===c&&!g?void 0:R()}},[t,c,g,v,m,p]),x=()=>{if(!w||!t){return}w.width=s,w.height=l;const e=w.getContext("2d");if(!e){return}c&&(e.beginPath(),e.moveTo(c,0),e.lineTo(s-c,0),e.arc(s-c,c,c,3*Math.PI/2,0,!1),e.lineTo(s,l-c),e.arc(s-c,l-c,c,0,Math.PI/2,!1),e.lineTo(c,l),e.arc(c,l-c,c,Math.PI/2,Math.PI,!1),e.lineTo(0,c),e.arc(c,c,c,Math.PI,3*Math.PI/2,!1),e.clip());const i=g?function(e,t){var r,i;const o=R(),n=e instanceof HTMLVideoElement?e.videoWidth:e.width,a=e instanceof HTMLVideoElement?e.videoHeight:e.height;o.width=n,o.height=a,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(e,0,0,o.width,o.height);const d=function(e,t,r,i,o,n,a){for(var d=new ImageData(t,r),h=new Int32Array(e.data.buffer),s=e.width,l=new Int32Array(d.data.buffer),c=d.width,u=t/n,g=r/a,f=Math.round(1/u),m=Math.round(1/g),p=f*m,v=0;v<d.height;v++){for(var w=0;w<c;w++){for(var x=0+Math.round(w/u)+(0+Math.round(v/g))*s,M=0,y=0,E=0,b=0,L=0;L<m;L++){for(var T=0;T<f;T++){var C=h[x+T+L*s];M+=C<<24>>>24,y+=C<<16>>>24,E+=C<<8>>>24,b+=C>>>24}}M=Math.round(M/p),y=Math.round(y/p),E=Math.round(E/p),b=Math.round(b/p),l[w+v*c]=b<<24|E<<16|y<<8|M}}return d}(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(i=o.getContext("2d"))||void 0===i||i.putImageData(d,0,0),o}(t,u):t,o=g?{x:Math.floor(r.x*u),y:Math.floor(r.y*u),width:Math.floor(r.width*u),height:Math.floor(r.height*u)}:r;e.drawImage(i,o.x,o.y,o.width,o.height,0,0,w.width,w.height)};return i.useLayoutEffect(()=>{x()},[w,e.width,e.height,r.x,r.y,r.width,r.height,n,o,a,null===(h=e.page)||void 0===h?void 0:h._exportingOrRendering,g]),i.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&f.Util.releaseCanvas(w)},[w]),[w||t,x]};const k=R(),H=o(({element:r})=>{const o=Math.min(30,r.width/4,r.height/4),n=i.useRef(null);i.useEffect(()=>{const e=n.current;if(!e){return}const t=new f.Animation(t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)},e.getLayer());return t.start(),()=>{t.stop()}});const{mediaLoadingStyle:h}=p();return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:h.fill}),e(a,{ref:n,x:r.width/2,y:r.height/2,fill:h.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),X=o(({element:r})=>{const{mediaErrorStyle:i}=p(),o=Math.max(10,Math.min(30,r.width/25));return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:i.fill}),e(l,{text:"Can not load the video...",fontSize:o,width:r.width,height:r.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});let Y=function(e,t,r){const o=i.useRef("loading"),n=i.useRef(void 0),[a,d]=i.useState(0),h=i.useRef(void 0),s=i.useRef(void 0),l=i.useRef(void 0);return h.current===e&&s.current===t&&l.current===r||(o.current="loading",n.current=void 0,h.current=e,s.current=t,l.current=r),i.useLayoutEffect(function(){if(e){var i=document.createElement("video");return i.addEventListener("canplay",a),i.addEventListener("error",h),t&&(i.crossOrigin=t),r&&(i.referrerPolicy=r),i.src=e,i.load(),function(){i.removeEventListener("canplay",a),i.removeEventListener("error",h)}}function a(){o.current="loaded",n.current=i,n.current.currentTime=0,d(Math.random()),n.current.removeEventListener("canplay",a)}function h(e){var t;const r=4===i.readyState,a=i.buffered&&i.buffered.length>0&&i.buffered.end(i.buffered.length-1)/i.duration*100>=100;if(r&&a){return}const h=e.message||(null===(t=i.error)||void 0===t?void 0:t.message)||"Unknown error",s=new Error("Video failed to load: "+h);console.error(s),o.current="failed",n.current=void 0,d(Math.random())}},[e,t,r]),[n.current,o.current]};export const setVideoLoaderHook=e=>{Y=e};function W(e){return e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}export const useLoader=(e,t,r)=>{const o=i.useRef(void 0),n=()=>{var e;null===(e=o.current)||void 0===e||e.call(o),o.current=void 0};i.useEffect(()=>n,[]),i.useLayoutEffect(()=>{const i=t.slice(0,200),a=`video with id ${r} url: ${i}`;"loading"!==e||o.current||(o.current=v(a)),"loading"!==e&&n(),"failed"===e&&w(a)},[e])};export const VideoElement=o(({element:o,store:a})=>{var l,p,w;const[M,O]=i.useState(!1),P=i.useRef(null),_=i.useRef(null),A=o.isSelected,[V,j]=i.useState(!1),[D,z]=Y(o.src,"anonymous"),[B,U]=i.useState(!1),N=a.activePage===o.page,F=(null===(l=o.page)||void 0===l?void 0:l._exportingOrRendering)&&"loaded"===z,Z=L(o,a,F);useLoader(z,o.src,o.id),D&&(D.playsInline=!0);const $=((e,t,r)=>{const o=i.useMemo(()=>{var i,o;const{flipX:n,flipY:a}=e,d="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,h=navigator.userAgent.toLowerCase().indexOf("firefox")>-1;if(!(n||a||h&&d)){return t}if(!t){return null}const s=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,l=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!s||!l){return null}const c=R();let u=1;"svg"===e.type&&(u=Math.max(e.width/s*r,e.height/l*r)),c.width=Math.max(s*u,1),c.height=Math.max(l*u,1);let g=n?-c.width:0,f=a?-c.height:0;return null===(i=c.getContext("2d"))||void 0===i||i.scale(n?-1:1,a?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(t,g,f,c.width,c.height),c},[e.flipX,e.flipY,t,e.width,e.height,r]);return i.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&f.Util.releaseCanvas(o)},[o]),o})(o,D,a._elementsPixelRatio),q=F&&Z||$||k;i.useEffect(()=>{D&&a.history.ignore(()=>{o.set({duration:1e3*D.duration})})},[D]),i.useEffect(()=>{var e;if(!D){return}const t=a.animatedElementsIds,r=(!t.length||t.includes(o.id))&&a.isPlaying;if(!N||!r&&!V){return void D.pause()}V&&(D.muted=!1,D.currentTime=o.startTime*D.duration,D.play());const i=new f.Animation(()=>{we.current()},null===(e=P.current)||void 0===e?void 0:e.getLayer());i.start();const n=()=>{j(!1),D.currentTime=o.startTime*D.duration},d=()=>{D.currentTime>=o.endTime*D.duration&&(D.pause(),D.currentTime=o.startTime*D.duration,j(!1))};return D.addEventListener("ended",n),D.addEventListener("timeupdate",d),()=>{D.pause(),i.stop(),D.removeEventListener("ended",n),D.removeEventListener("timeupdate",d)}},[D,V,a.isPlaying,N]),i.useEffect(()=>{D&&(D.volume=o.volume)},[D,o.volume]),i.useEffect(()=>{D&&(D.playbackRate=o.speed,D.preservesPitch=!1)},[D,o.speed]);const G=i.useRef(null);i.useEffect(()=>{const e=n(o,()=>{var e,t;if(D){if(F&&Z){return ve(),void a.currentTime}const r=a.animatedElementsIds;if(r.length&&!r.includes(o.id)){return}const i=a.activePage===o.page,n=a.currentTime>=o.page.startTime&&a.currentTime<o.page.startTime+o.page.duration,d=o.startTime*D.duration*1e3,h=D.duration*(o.endTime-o.startTime)*1e3,{start:s,end:l}=T(o.animations,o.page.duration),c=(a.currentTime||o.page.startTime)-o.page.startTime,u=n?C(a.currentTime,o.page.startTime,s,h,d,o.speed):0,g=u/1e3,f=n&&c>=s&&c<l;V||(D.muted=!f,f&&a.isPlaying&&i?D.paused?(D.currentTime=g,D.play()):Math.abs(1e3*D.currentTime-u)>500&&(D.currentTime=g):(D.paused||D.pause(),g!==D.currentTime&&(D.currentTime=g),!W(D)&&!a.isPlaying&&!G.current&&(G.current=v(`video ${o.id}`)))),we.current(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}});return()=>{e(),G.current&&(G.current(),G.current=null)}},[a,D,F,Z,V]),i.useEffect(()=>{var e,t;if(!D){return}if(F){return null===(e=G.current)||void 0===e||e.call(G),void(G.current=null)}const r=()=>{var e,t,r;!W(D)&&(null===(e=o.page)||void 0===e?void 0:e._exportingOrRendering)||G.current&&(we.current(),null===(r=null===(t=P.current)||void 0===t?void 0:t.getLayer())||void 0===r||r.batchDraw(),G.current(),G.current=null)};let i;return(null===(t=o.page)||void 0===t?void 0:t._exportingOrRendering)&&(i=setInterval(r,20)),D.addEventListener("timeupdate",r),D.addEventListener("canplay",r),()=>{clearInterval(i),D.removeEventListener("timeupdate",r),D.removeEventListener("canplay",r)}},[null===(p=o.page)||void 0===p?void 0:p._exportingOrRendering,D,o.id,v,F]);let{cropX:J,cropY:K,cropWidth:Q,cropHeight:ee}=o;"loaded"!==z&&(J=K=0,Q=ee=1);const te=(re=q)instanceof HTMLVideoElement?re.videoWidth:(null==re?void 0:re.width)||0;var re;const ie=(e=>e instanceof HTMLVideoElement?e.videoHeight:(null==e?void 0:e.height)||0)(q),oe=te*Q,ne=ie*ee,ae=o.width/o.height;let de,he;const se=oe/ne,le="svg"===o.type;le?(de=oe,he=ne):ae>=se?(de=oe,he=oe/ae):(de=ne*ae,he=ne);const ce={x:te*J,y:ie*K,width:de,height:he},ue=null!==(w=o.cornerRadius)&&void 0!==w?w:0,[ge,fe]=useCornerRadiusAndCrop(o,q,ce,a._elementsPixelRatio,ue,!0);let[me,pe]=((e,t,r,o)=>{const n=(e=>{const[t,r]=i.useState(e);return i.useEffect(()=>{(async()=>{const i=await async function(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0)){return e}const t=await x.urlToString(e),r=x.fixSize(t);return x.svgToURL(r)}(e);i!==t&&r(i)})()},[e]),t})(e.clipSrc||""),[a,d]=g(n,"anonymous"),h=e.clipSrc?d:"loaded";useLoader(h,e.clipSrc,e.id);const s=i.useMemo(()=>{if(t&&a){return R()}},[t,a]);function l(){var i;if(!a){return}const o=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,n=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!t||!o||!n){return}if(!a||!a.width||!a.height){return}if(!s){return}const d=R(),h=Math.max(e.width/a.width*r,e.height/a.height*r);d.width=a.width*h,d.height=a.height*h,null===(i=d.getContext("2d"))||void 0===i||i.drawImage(a,0,0,d.width,d.height),s.width=Math.max(o,1),s.height=Math.max(n,1);const l=s.getContext("2d");l&&(l.save(),l.drawImage(d,0,0,o,n),f.Util.releaseCanvas(d),l.globalCompositeOperation="source-in",l.drawImage(t,0,0,s.width,s.height),l.restore())}return i.useLayoutEffect(()=>{l()},[s,t,a,e.width,e.height,r,...o]),[e.clipSrc&&a?s:t,l]})(o,ge,a._elementsPixelRatio,[ce,ue,a._elementsPixelRatio]);function ve(){var e,t;fe(),pe(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}i.useEffect(()=>{ve()});const we=i.useRef(ve);we.current=ve;const xe=Math.max(o.width/de,o.height/he);i.useEffect(()=>{var e;if(!o._cropModeEnabled){return}const t=null===(e=P.current)||void 0===e?void 0:e.getStage();function r(e){o._cropModeEnabled&&e.target!==_.current&&o.toggleCropMode(!1)}function i(e){o._cropModeEnabled&&e.target.parentNode!==(null==t?void 0:t.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",i),null==t||t.on("click",r),null==t||t.on("tap",r),()=>{document.body.removeEventListener("click",i),document.body.removeEventListener("touchstart",i),null==t||t.off("click",r),null==t||t.off("click",r)}},[o._cropModeEnabled]),i.useLayoutEffect(()=>{if(!M&&!o._cropModeEnabled){return y(P.current,o),n(o,()=>{y(P.current,o)},{delay:100})}},[q,M,Q,ee,o._cropModeEnabled]),i.useLayoutEffect(()=>{var e;M||o._cropModeEnabled?null===(e=P.current)||void 0===e||e.clearCache():y(P.current,o)},[M,o.width,o.height,o._cropModeEnabled]),i.useEffect(()=>{y(P.current,o)},[o.shadowEnabled,o.shadowBlur,o.cornerRadius,o.shadowColor,o.shadowOffsetX,o.shadowOffsetY,o.shadowOpacity]);const Me=i.useRef(null),ye=i.useRef(null),Ee=i.useRef(null);i.useLayoutEffect(()=>{o._cropModeEnabled&&(ye.current.nodes([Me.current]),Ee.current.nodes([_.current]))},[o._cropModeEnabled]);const be=e=>{Math.round(e.target.x())>0&&(e.target.x(0),e.target.scaleX(1)),Math.round(e.target.y())>0&&(e.target.y(0),e.target.scaleY(1));const t=e.target.width()*e.target.scaleX(),r=e.target.height()*e.target.scaleY(),i=Math.min(1,de/t),n=Math.min(1,he/r),a=1-i,d=Math.min(a,Math.max(0,Math.round(-e.target.x())/t)),h=1-n,s=Math.min(h,Math.max(0,Math.round(-e.target.y())/r));e.target.setAttrs({x:-d*te,y:-s*ie,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:s,cropWidth:i,cropHeight:n})},Le=()=>{"svg"!==o.type&&o.contentEditable&&setTimeout(()=>{o.toggleCropMode(!0)})},Te="loading"===z,Ce="failed"===z,Re=!Te&&!Ce,Se=i.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Ie=Re?o.a.opacity:0;E(P,Ie);const ke=o.selectable||a.role===u.ADMIN,He=b();return e(r,{children:t(d,{onMouseEnter:()=>U(!0),onMouseLeave:()=>U(!1),children:[Te&&e(H,{element:o}),Ce&&e(X,{element:o}),e(h,{ref:P,name:"element",id:o.id,image:me,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:Ie,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:ce,listening:ke,draggable:He?o.draggable&&A:o.draggable,preventDefault:!He||A,hideInExport:!o.showInExport,onDragMove:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDblClick:Le,onDblTap:Le,onTransformStart:()=>{O(!0),Se.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:e=>{var t;const r=e.currentTarget,i=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),n=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const a=null===(t=e.target.getStage())||void 0===t?void 0:t.findOne("Transformer"),d=1-de/te,h=Math.min(d,Math.max(0,o.cropX)),s=1-he/ie,l=Math.min(s,Math.max(0,o.cropY)),c=a.getActiveAnchor(),u=!(c.indexOf("middle")>=0||c.indexOf("center")>=0),g=!u&&i<1&&Se.current.cropHeight>he/ie;let f=u?o.cropWidth:o.cropWidth*i;g&&(f=o.cropWidth);const m=!u&&n<1&&Se.current.cropWidth>de/te;let p=u?o.cropHeight:o.cropHeight*n;m&&(p=o.cropHeight),le&&(f=o.cropWidth,p=o.cropHeight),o.set({cropX:h,cropY:l,x:r.x(),y:r.y(),width:r.width()*i,height:r.height()*n,rotation:e.target.rotation(),cropWidth:Math.min(f,1-h),cropHeight:Math.min(p,1-l)})},onTransformEnd:e=>{const t=e.currentTarget;o.set({width:t.width(),height:t.height(),x:t.x(),y:t.y(),rotation:e.target.rotation(),cropWidth:de/te,cropHeight:he/ie}),O(!1)}}),e(s,{x:o.a.x,y:o.a.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:Ie,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2,stroke:o.borderColor,strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,ue-o.borderSize),hideInExport:!o.showInExport}),!a.isPlaying&&e(h,{image:V?B||He?I:void 0:S,x:o.a.x,y:o.a.y,offsetX:-o.a.width/2+15/a.scale,offsetY:-o.a.height/2+15/a.scale,rotation:o.a.rotation,width:30/a.scale,height:30/a.scale,hideInExport:!0,onClick:()=>j(!V),onTap:()=>j(!V)}),o._cropModeEnabled&&t(m,{selector:".page-abs-container",enabled:!0,children:[e(s,{x:-window.innerWidth/a.scale,y:-window.innerWidth/a.scale,width:window.innerWidth/a.scale*3,height:window.innerWidth/a.scale*3,fill:"rgba(0,0,0,0.3)"}),e(h,{listening:!1,image:me,x:o.a.x,y:o.a.y,width:o.a.width,height:o.a.height,rotation:o.a.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),t(d,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,scaleX:xe,scaleY:xe,children:[e(h,{image:q,ref:_,width:te,height:ie,opacity:.4,draggable:!0,x:-o.cropX*te,y:-o.cropY*ie,onDragMove:be,onTransform:be}),e(c,{ref:Ee,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),e(s,{width:de,height:he,ref:Me,listening:!1,onTransform:e=>{e.target.x()<-o.cropX*te-1e-9&&(e.target.x(-o.cropX*te),e.target.scaleX(1)),e.target.y()<-o.cropY*ie-1e-9&&(e.target.y(-o.cropY*ie),e.target.scaleY(1));const t=Math.min(1,Math.max(0,o.cropX+e.target.x()/te)),r=Math.min(1,Math.max(0,e.target.y()/ie+o.cropY)),i=e.target.width()*e.target.scaleX(),n=e.target.height()*e.target.scaleY(),a=Math.min(1-t,i/te),d=Math.min(1-r,n/ie),h=e.target.getAbsolutePosition(e.target.getParent().getParent());e.target.scale({x:1,y:1}),e.target.position({x:0,y:0}),o.set({x:h.x,y:h.y,cropX:t,cropY:r,cropWidth:a,cropHeight:d,width:Math.min(i*xe,te*(1-t)*xe),height:Math.min(n*xe,ie*(1-r)*xe)})}}),e(c,{ref:ye,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2,visible:o.resizable})]})]})]})})});
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{nodeAutorun as n}from"../utils/mobx.js";import{Arc as a,Group as d,Image as h,Rect as s,Text as l,Transformer as c}from"react-konva";import{ROLES as u}from"../model/store.js";import g from"use-image";import m from"konva";import{Portal as f}from"react-konva-utils";import{useWorkspaceStyle as p}from"./workspace-style.js";import{incrementLoader as v,triggerLoadError as w}from"../utils/loader.js";import{polotnoError as x}from"../utils/errors.js";import*as M from"../utils/svg.js";import{flags as y}from"../utils/flags.js";import{useFilteredSource as E}from"./use-filtered-source.js";import{useEvent as b}from"../hooks/use-event.js";import{useFadeIn as L}from"./use-fadein.js";import{isTouchDevice as T}from"../utils/screen.js";import{useMediabunnyVideo as C}from"./use-mediabunny-video.js";import{getElementTimeRange as R,getVideoRestMs as I}from"../utils/timeline.js";function S(){return document.createElement("canvas")}const k=new window.Image;k.src=M.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" fill="white"/>\n <path d="M4 5.49683V18.5032C4 20.05 5.68077 21.0113 7.01404 20.227L18.0694 13.7239C19.384 12.9506 19.384 11.0494 18.0694 10.2761L7.01404 3.77296C5.68077 2.98869 4 3.95 4 5.49683Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');const H=new window.Image;H.src=M.svgToURL('\n <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path opacity="0.6" d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" fill="white"/>\n <path opacity="0.6" d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" fill="white"/>\n <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n');export const useCornerRadiusAndCrop=(e,t,r,o,n=0,a=!1)=>{var d,h;const s=Math.floor(Math.max(e.width*o,1)),l=Math.floor(Math.max(e.height*o,1)),c=Math.min(n*o,s/2,l/2),u=Math.max(e.width/r.width,e.height/r.height)*o,g=(null===(d=e.page)||void 0===d?void 0:d._exportingOrRendering)&&y.imageDownScalingEnabled&&u<1&&!a,f=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,p=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height,v=0===r.x&&0===r.y&&r.width===f&&r.height===p,w=i.useMemo(()=>{if(t&&f&&p){return v&&0===c&&!g?void 0:S()}},[t,c,g,v,f,p]),x=()=>{if(!w||!t){return}w.width=s,w.height=l;const e=w.getContext("2d");if(!e){return}c&&(e.beginPath(),e.moveTo(c,0),e.lineTo(s-c,0),e.arc(s-c,c,c,3*Math.PI/2,0,!1),e.lineTo(s,l-c),e.arc(s-c,l-c,c,0,Math.PI/2,!1),e.lineTo(c,l),e.arc(c,l-c,c,Math.PI/2,Math.PI,!1),e.lineTo(0,c),e.arc(c,c,c,Math.PI,3*Math.PI/2,!1),e.clip());const i=g?function(e,t){var r,i;const o=S(),n=e instanceof HTMLVideoElement?e.videoWidth:e.width,a=e instanceof HTMLVideoElement?e.videoHeight:e.height;o.width=n,o.height=a,null===(r=o.getContext("2d"))||void 0===r||r.drawImage(e,0,0,o.width,o.height);const d=function(e,t,r,i,o,n,a){for(var d=new ImageData(t,r),h=new Int32Array(e.data.buffer),s=e.width,l=new Int32Array(d.data.buffer),c=d.width,u=t/n,g=r/a,m=Math.round(1/u),f=Math.round(1/g),p=m*f,v=0;v<d.height;v++){for(var w=0;w<c;w++){for(var x=0+Math.round(w/u)+(0+Math.round(v/g))*s,M=0,y=0,E=0,b=0,L=0;L<f;L++){for(var T=0;T<m;T++){var C=h[x+T+L*s];M+=C<<24>>>24,y+=C<<16>>>24,E+=C<<8>>>24,b+=C>>>24}}M=Math.round(M/p),y=Math.round(y/p),E=Math.round(E/p),b=Math.round(b/p),l[w+v*c]=b<<24|E<<16|y<<8|M}}return d}(o.getContext("2d").getImageData(0,0,o.width,o.height),Math.floor(o.width*t),Math.floor(o.height*t),0,0,o.width,o.height);return o.width=Math.floor(o.width*t),o.height=Math.floor(o.height*t),null===(i=o.getContext("2d"))||void 0===i||i.putImageData(d,0,0),o}(t,u):t,o=g?{x:Math.floor(r.x*u),y:Math.floor(r.y*u),width:Math.floor(r.width*u),height:Math.floor(r.height*u)}:r;e.drawImage(i,o.x,o.y,o.width,o.height,0,0,w.width,w.height)};return i.useLayoutEffect(()=>{x()},[w,e.width,e.height,r.x,r.y,r.width,r.height,n,o,a,null===(h=e.page)||void 0===h?void 0:h._exportingOrRendering,g]),i.useEffect(()=>()=>{w&&"CANVAS"===w.nodeName&&m.Util.releaseCanvas(w)},[w]),[w||t,x]};const W=S(),X=o(({element:r})=>{const o=Math.min(30,r.width/4,r.height/4),n=i.useRef(null);i.useEffect(()=>{const e=n.current;if(!e){return}const t=new m.Animation(t=>{e.rotate(((null==t?void 0:t.timeDiff)||0)/2)},e.getLayer());return t.start(),()=>{t.stop()}});const{mediaLoadingStyle:h}=p();return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:h.fill}),e(a,{ref:n,x:r.width/2,y:r.height/2,fill:h.textFill,outerRadius:Math.abs(o),innerRadius:Math.max(1,o-5),angle:270})]})}),Y=o(({element:r})=>{const{mediaErrorStyle:i}=p(),o=Math.max(10,Math.min(30,r.width/25));return t(d,{x:r.a.x,y:r.a.y,rotation:r.a.rotation,listening:!1,opacity:r.a.opacity,hideInExport:!r.showInExport,children:[e(s,{width:r.width,height:r.height,fill:i.fill}),e(l,{text:"Can not load the video...",fontSize:o,width:r.width,height:r.height,align:"center",fill:i.textFill,verticalAlign:"middle",padding:5})]})});let A=function(e,t,r){const o=i.useRef("loading"),n=i.useRef(void 0),[a,d]=i.useState(0),h=i.useRef(void 0),s=i.useRef(void 0),l=i.useRef(void 0);return h.current===e&&s.current===t&&l.current===r||(o.current="loading",n.current=void 0,h.current=e,s.current=t,l.current=r),i.useLayoutEffect(function(){if(e){var i=document.createElement("video");return i.addEventListener("canplay",a),i.addEventListener("error",h),t&&(i.crossOrigin=t),r&&(i.referrerPolicy=r),i.src=e,i.load(),function(){i.removeEventListener("canplay",a),i.removeEventListener("error",h)}}function a(){o.current="loaded",n.current=i,n.current.currentTime=0,d(Math.random()),n.current.removeEventListener("canplay",a)}function h(e){var t;const r=4===i.readyState,a=i.buffered&&i.buffered.length>0&&i.buffered.end(i.buffered.length-1)/i.duration*100>=100;if(r&&a){return}const h=e.message||(null===(t=i.error)||void 0===t?void 0:t.message)||"Unknown error",s=new Error("Video failed to load: "+h);console.error(s),o.current="failed",n.current=void 0,d(Math.random())}},[e,t,r]),[n.current,o.current]};export const setVideoLoaderHook=e=>{A=e};function O(e){return e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA}export const useLoader=(e,t,r)=>{const o=i.useRef(void 0),n=()=>{var e;null===(e=o.current)||void 0===e||e.call(o),o.current=void 0};i.useEffect(()=>n,[]),i.useLayoutEffect(()=>{const i=t.slice(0,200),a=`video with id ${r} url: ${i}`;"loading"!==e||o.current||(o.current=v(a)),"loading"!==e&&n(),"failed"===e&&w(x("VIDEO_FAILED",a,{src:i,elementId:r,reason:"load"}))},[e])};export const VideoElement=o(({element:o,store:a})=>{var l,p,w;const[x,y]=i.useState(!1),P=i.useRef(null),_=i.useRef(null),j=o.isSelected,[V,D]=i.useState(!1),[z,B]=A(o.src,"anonymous"),[U,F]=i.useState(!1),N=a.activePage===o.page,Z=(null===(l=o.page)||void 0===l?void 0:l._exportingOrRendering)&&"loaded"===B,$=C(o,a,Z);useLoader(B,o.src,o.id),z&&(z.playsInline=!0);const q=((e,t,r)=>{const o=i.useMemo(()=>{var i,o;const{flipX:n,flipY:a}=e,d="svg"===e.type||e.src.indexOf("data:image/svg+xml")>=0||e.src.indexOf(".svg")>=0,h=navigator.userAgent.toLowerCase().indexOf("firefox")>-1;if(!(n||a||h&&d)){return t}if(!t){return null}const s=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,l=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!s||!l){return null}const c=S();let u=1;"svg"===e.type&&(u=Math.max(e.width/s*r,e.height/l*r)),c.width=Math.max(s*u,1),c.height=Math.max(l*u,1);let g=n?-c.width:0,m=a?-c.height:0;return null===(i=c.getContext("2d"))||void 0===i||i.scale(n?-1:1,a?-1:1),null===(o=c.getContext("2d"))||void 0===o||o.drawImage(t,g,m,c.width,c.height),c},[e.flipX,e.flipY,t,e.width,e.height,r]);return i.useEffect(()=>()=>{o&&"CANVAS"===o.nodeName&&m.Util.releaseCanvas(o)},[o]),o})(o,z,a._elementsPixelRatio),G=Z&&$||q||W,[J=W,K]=E(o,G);i.useEffect(()=>{z&&a.history.ignore(()=>{o.set({duration:1e3*z.duration})})},[z]),i.useEffect(()=>{var e;if(!z){return}const t=a.animatedElementsIds,r=(!t.length||t.includes(o.id))&&a.isPlaying;if(!N||!r&&!V){return void z.pause()}V&&(z.muted=!1,z.currentTime=o.startTime*z.duration,z.play());const i=new m.Animation(()=>{Me()},null===(e=P.current)||void 0===e?void 0:e.getLayer());i.start();const n=()=>{D(!1),z.currentTime=o.startTime*z.duration},d=()=>{z.currentTime>=o.endTime*z.duration&&(z.pause(),z.currentTime=o.startTime*z.duration,D(!1))};return z.addEventListener("ended",n),z.addEventListener("timeupdate",d),()=>{z.pause(),i.stop(),z.removeEventListener("ended",n),z.removeEventListener("timeupdate",d)}},[z,V,a.isPlaying,N]),i.useEffect(()=>{z&&(z.volume=o.volume)},[z,o.volume]),i.useEffect(()=>{z&&(z.playbackRate=o.speed,z.preservesPitch=!1)},[z,o.speed]);const Q=i.useRef(null);i.useEffect(()=>{const e=n(o,()=>{var e,t;if(z){if(Z&&$){return Me(),void a.currentTime}const r=a.animatedElementsIds;if(r.length&&!r.includes(o.id)){return}const i=a.activePage===o.page,n=a.currentTime>=o.page.startTime&&a.currentTime<o.page.startTime+o.page.duration,d=o.startTime*z.duration*1e3,h=z.duration*(o.endTime-o.startTime)*1e3,{start:s,end:l}=R(o.animations,o.page.duration),c=(a.currentTime||o.page.startTime)-o.page.startTime,u=n?I(a.currentTime,o.page.startTime,s,h,d,o.speed):0,g=u/1e3,m=n&&c>=s&&c<l;V||(z.muted=!m,m&&a.isPlaying&&i?z.paused?(z.currentTime=g,z.play()):Math.abs(1e3*z.currentTime-u)>500&&(z.currentTime=g):(z.paused||z.pause(),g!==z.currentTime&&(z.currentTime=g),!O(z)&&!a.isPlaying&&!Q.current&&(Q.current=v(`video ${o.id}`)))),Me(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()}});return()=>{e(),Q.current&&(Q.current(),Q.current=null)}},[a,z,Z,$,V]),i.useEffect(()=>{var e,t;if(!z){return}if(Z){return null===(e=Q.current)||void 0===e||e.call(Q),void(Q.current=null)}const r=()=>{var e,t,r;!O(z)&&(null===(e=o.page)||void 0===e?void 0:e._exportingOrRendering)||Q.current&&(Me(),null===(r=null===(t=P.current)||void 0===t?void 0:t.getLayer())||void 0===r||r.batchDraw(),Q.current(),Q.current=null)};let i;return(null===(t=o.page)||void 0===t?void 0:t._exportingOrRendering)&&(i=setInterval(r,20)),z.addEventListener("timeupdate",r),z.addEventListener("canplay",r),()=>{clearInterval(i),z.removeEventListener("timeupdate",r),z.removeEventListener("canplay",r)}},[null===(p=o.page)||void 0===p?void 0:p._exportingOrRendering,z,o.id,v,Z]);let{cropX:ee,cropY:te,cropWidth:re,cropHeight:ie}=o;"loaded"!==B&&(ee=te=0,re=ie=1);const oe=(ne=J)instanceof HTMLVideoElement?ne.videoWidth:(null==ne?void 0:ne.width)||0;var ne;const ae=(e=>e instanceof HTMLVideoElement?e.videoHeight:(null==e?void 0:e.height)||0)(J),de=oe*re,he=ae*ie,se=o.width/o.height;let le,ce;const ue=de/he,ge="svg"===o.type;ge?(le=de,ce=he):se>=ue?(le=de,ce=de/se):(le=he*se,ce=he);const me={x:oe*ee,y:ae*te,width:le,height:ce},fe=null!==(w=o.cornerRadius)&&void 0!==w?w:0,[pe,ve]=useCornerRadiusAndCrop(o,J,me,a._elementsPixelRatio,fe,!0);let[we,xe]=((e,t,r,o)=>{const n=(e=>{const[t,r]=i.useState(e);return i.useEffect(()=>{(async()=>{const i=await async function(e){if(!(e.indexOf("data:image/svg+xml")>=0||e.indexOf(".svg")>=0)){return e}const t=await M.urlToString(e),r=M.fixSize(t);return M.svgToURL(r)}(e);i!==t&&r(i)})()},[e]),t})(e.clipSrc||""),[a,d]=g(n,"anonymous"),h=e.clipSrc?d:"loaded";useLoader(h,e.clipSrc,e.id);const s=i.useMemo(()=>{if(t&&a){return S()}},[t,a]);function l(){var i;if(!a){return}const o=t instanceof HTMLVideoElement?t.videoWidth:null==t?void 0:t.width,n=t instanceof HTMLVideoElement?t.videoHeight:null==t?void 0:t.height;if(!t||!o||!n){return}if(!a||!a.width||!a.height){return}if(!s){return}const d=S(),h=Math.max(e.width/a.width*r,e.height/a.height*r);d.width=a.width*h,d.height=a.height*h,null===(i=d.getContext("2d"))||void 0===i||i.drawImage(a,0,0,d.width,d.height),s.width=Math.max(o,1),s.height=Math.max(n,1);const l=s.getContext("2d");l&&(l.save(),l.drawImage(d,0,0,o,n),m.Util.releaseCanvas(d),l.globalCompositeOperation="source-in",l.drawImage(t,0,0,s.width,s.height),l.restore())}return i.useLayoutEffect(()=>{l()},[s,t,a,e.width,e.height,r,...o]),[e.clipSrc&&a?s:t,l]})(o,pe,a._elementsPixelRatio,[me,fe,a._elementsPixelRatio]);const Me=b(()=>{var e,t;K(),ve(),xe(),null===(t=null===(e=P.current)||void 0===e?void 0:e.getLayer())||void 0===t||t.batchDraw()});i.useEffect(()=>{Me()});const ye=Math.max(o.width/le,o.height/ce);i.useEffect(()=>{var e;if(!o._cropModeEnabled){return}const t=null===(e=P.current)||void 0===e?void 0:e.getStage();function r(e){o._cropModeEnabled&&e.target!==_.current&&o.toggleCropMode(!1)}function i(e){o._cropModeEnabled&&e.target.parentNode!==(null==t?void 0:t.content)&&o.toggleCropMode(!1)}return document.body.addEventListener("click",i),null==t||t.on("click",r),null==t||t.on("tap",r),()=>{document.body.removeEventListener("click",i),document.body.removeEventListener("touchstart",i),null==t||t.off("click",r),null==t||t.off("click",r)}},[o._cropModeEnabled]);const Ee=i.useRef(null),be=i.useRef(null),Le=i.useRef(null);i.useLayoutEffect(()=>{o._cropModeEnabled&&(be.current.nodes([Ee.current]),Le.current.nodes([_.current]))},[o._cropModeEnabled]);const Te=e=>{Math.round(e.target.x())>0&&(e.target.x(0),e.target.scaleX(1)),Math.round(e.target.y())>0&&(e.target.y(0),e.target.scaleY(1));const t=e.target.width()*e.target.scaleX(),r=e.target.height()*e.target.scaleY(),i=Math.min(1,le/t),n=Math.min(1,ce/r),a=1-i,d=Math.min(a,Math.max(0,Math.round(-e.target.x())/t)),h=1-n,s=Math.min(h,Math.max(0,Math.round(-e.target.y())/r));e.target.setAttrs({x:-d*oe,y:-s*ae,scaleX:1,scaleY:1}),o.set({cropX:d,cropY:s,cropWidth:i,cropHeight:n})},Ce=()=>{"svg"!==o.type&&o.contentEditable&&setTimeout(()=>{o.toggleCropMode(!0)})},Re="loading"===B,Ie="failed"===B,Se=!Re&&!Ie,ke=i.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),He=Se?o.a.opacity:0;L(P,He);const We=o.selectable||a.role===u.ADMIN,Xe=T();return e(r,{children:t(d,{onMouseEnter:()=>F(!0),onMouseLeave:()=>F(!1),children:[Re&&e(X,{element:o}),Ie&&e(Y,{element:o}),e(h,{ref:P,name:"element",id:o.id,image:we,x:o.a.x,y:o.a.y,width:o.a.width||1,height:o.a.height||1,rotation:o.a.rotation,opacity:He,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur,shadowOffsetX:o.shadowOffsetX,shadowOffsetY:o.shadowOffsetY,shadowColor:o.shadowColor,shadowOpacity:o.shadowOpacity,customCrop:me,listening:We,draggable:Xe?o.draggable&&j:o.draggable,preventDefault:!Xe||j,hideInExport:!o.showInExport,onDragMove:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDragEnd:e=>{o.set({x:e.target.x(),y:e.target.y()})},onDblClick:Ce,onDblTap:Ce,onTransformStart:()=>{y(!0),ke.current={cropX:o.cropX,cropY:o.cropY,cropWidth:o.cropWidth,cropHeight:o.cropHeight}},onTransform:e=>{var t;const r=e.currentTarget,i=Math.abs(r.scaleX()-1)<1e-7?1:r.scaleX(),n=Math.abs(r.scaleY()-1)<1e-7?1:r.scaleY();r.scaleX(1),r.scaleY(1);const a=null===(t=e.target.getStage())||void 0===t?void 0:t.findOne("Transformer"),d=1-le/oe,h=Math.min(d,Math.max(0,o.cropX)),s=1-ce/ae,l=Math.min(s,Math.max(0,o.cropY)),c=a.getActiveAnchor(),u=!(c.indexOf("middle")>=0||c.indexOf("center")>=0),g=!u&&i<1&&ke.current.cropHeight>ce/ae;let m=u?o.cropWidth:o.cropWidth*i;g&&(m=o.cropWidth);const f=!u&&n<1&&ke.current.cropWidth>le/oe;let p=u?o.cropHeight:o.cropHeight*n;f&&(p=o.cropHeight),ge&&(m=o.cropWidth,p=o.cropHeight),o.set({cropX:h,cropY:l,x:r.x(),y:r.y(),width:r.width()*i,height:r.height()*n,rotation:e.target.rotation(),cropWidth:Math.min(m,1-h),cropHeight:Math.min(p,1-l)})},onTransformEnd:e=>{const t=e.currentTarget;o.set({width:t.width(),height:t.height(),x:t.x(),y:t.y(),rotation:e.target.rotation(),cropWidth:le/oe,cropHeight:ce/ae}),y(!1)}}),e(s,{x:o.a.x,y:o.a.y,width:Math.max(o.a.width-o.borderSize,0),height:Math.max(o.a.height-o.borderSize,0),opacity:He,offsetX:-o.borderSize/2,offsetY:-o.borderSize/2,stroke:o.borderColor,strokeWidth:o.borderSize,listening:!1,visible:!!o.borderSize,rotation:o.rotation,cornerRadius:Math.max(0,fe-o.borderSize),hideInExport:!o.showInExport}),!a.isPlaying&&e(h,{image:V?U||Xe?H:void 0:k,x:o.a.x,y:o.a.y,offsetX:-o.a.width/2+15/a.scale,offsetY:-o.a.height/2+15/a.scale,rotation:o.a.rotation,width:30/a.scale,height:30/a.scale,hideInExport:!0,onClick:()=>D(!V),onTap:()=>D(!V)}),o._cropModeEnabled&&t(f,{selector:".page-abs-container",enabled:!0,children:[e(s,{x:-window.innerWidth/a.scale,y:-window.innerWidth/a.scale,width:window.innerWidth/a.scale*3,height:window.innerWidth/a.scale*3,fill:"rgba(0,0,0,0.3)"}),e(h,{listening:!1,image:we,x:o.a.x,y:o.a.y,width:o.a.width,height:o.a.height,rotation:o.a.rotation,shadowEnabled:o.shadowEnabled,shadowBlur:o.shadowBlur}),t(d,{x:o.a.x,y:o.a.y,rotation:o.a.rotation,scaleX:ye,scaleY:ye,children:[e(h,{image:J,ref:_,width:oe,height:ae,opacity:.4,draggable:!0,x:-o.cropX*oe,y:-o.cropY*ae,onDragMove:Te,onTransform:Te}),e(c,{ref:Le,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),e(s,{width:le,height:ce,ref:Ee,listening:!1,onTransform:e=>{e.target.x()<-o.cropX*oe-1e-9&&(e.target.x(-o.cropX*oe),e.target.scaleX(1)),e.target.y()<-o.cropY*ae-1e-9&&(e.target.y(-o.cropY*ae),e.target.scaleY(1));const t=Math.min(1,Math.max(0,o.cropX+e.target.x()/oe)),r=Math.min(1,Math.max(0,e.target.y()/ae+o.cropY)),i=e.target.width()*e.target.scaleX(),n=e.target.height()*e.target.scaleY(),a=Math.min(1-t,i/oe),d=Math.min(1-r,n/ae),h=e.target.getAbsolutePosition(e.target.getParent().getParent());e.target.scale({x:1,y:1}),e.target.position({x:0,y:0}),o.set({x:h.x,y:h.y,cropX:t,cropY:r,cropWidth:a,cropHeight:d,width:Math.min(i*ye,oe*(1-t)*ye),height:Math.min(n*ye,ae*(1-r)*ye)})}}),e(c,{ref:be,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(e,t)=>t.width<5||t.height<5?e:t,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2,visible:o.resizable})]})]})]})})});
|
package/model/group-model.d.ts
CHANGED
|
@@ -295,6 +295,7 @@ export declare const TYPES_MAP: {
|
|
|
295
295
|
verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
296
296
|
strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
297
297
|
stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
298
|
+
strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
298
299
|
lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
|
|
299
300
|
letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
300
301
|
_editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
package/model/group-model.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var o={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(o[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);r<i.length;r++){t.indexOf(i[r])<0&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(o[i[r]]=e[i[r]])}}return o};import{detach as t,isAlive as o,types as i}from"mobx-state-tree";import{nanoid as r}from"nanoid";import{Node as n}from"./node-model.js";import{Animation as
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var o={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(o[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(i=Object.getOwnPropertySymbols(e);r<i.length;r++){t.indexOf(i[r])<0&&Object.prototype.propertyIsEnumerable.call(e,i[r])&&(o[i[r]]=e[i[r]])}}return o};import{detach as t,isAlive as o,types as i}from"mobx-state-tree";import{nanoid as r}from"nanoid";import{Node as n}from"./node-model.js";import{Animation as s,Shape as l}from"./shape-model.js";import{animate as a}from"../utils/animations.js";import{polotnoError as d}from"../utils/errors.js";import{getPlayheadLocalTime as c}from"../utils/timeline.js";import{getCenter as p,getTotalClientRect as h}from"../utils/math.js";import{TextElement as y}from"./text-model.js";import{ImageElement as m}from"./image-model.js";import{VideoElement as f}from"./video-model.js";import{LineElement as u}from"./line-model.js";import{SVGElement as g}from"./svg-model.js";import{FigureElement as E}from"./figure-model.js";import{GifElement as b}from"./gif-model.js";import{TableElement as v}from"./table-model.js";export const forEveryChild=(e,t)=>{if(e.children){for(const o of e.children){if(!0===t(o)){break}forEveryChild(o,t)}}};export const forEveryNode=(e,t)=>{if(e.children){for(const o of e.children){if(!0===t(o)){break}forEveryNode(o,t)}}if(e.cells){for(const o of e.cells){if(!0===t(o)){break}}}};export function zIndexOps(e){const o=(t,o,i)=>{const r=t.map(t=>e.children.findIndex(e=>e.id===t)).filter(e=>-1!==e).sort((e,t)=>(t-e)*o);for(const n of r){const r=e.children[n+o];!r||t.indexOf(r.id)>=0||i(n)}},i=(e,t)=>{let i=!1;return o(e,t,()=>{i=!0}),i},r=(i,r)=>{o(i,r,o=>{const i=e.children[o];t(i),e.children.splice(o+r,0,i)})},n=(t,o)=>{const i=[],r=[];e.children.forEach(e=>{(t.indexOf(e.id)>=0?i:r).push(e)}),e.children.replace(o?r.concat(i):i.concat(r))};return{canMoveElementsUp:e=>i(e,1),canMoveElementsTop:e=>i(e,1),canMoveElementsDown:e=>i(e,-1),canMoveElementsBottom:e=>i(e,-1),moveElementsUp(e){r(e,1)},moveElementsDown(e){r(e,-1)},moveElementsTop(e){n(e,!0)},moveElementsBottom(e){n(e,!1)},setElementZIndex(o,i){const r=e.children.find(e=>e.id===o);r&&(t(r),e.children.remove(r),e.children.splice(i,0,r))}}}const x=[...new Array(20)].map((e,t)=>i.late(()=>S[t]));export const ElementTypes=i.union({dispatcher:e=>{const t=TYPES_MAP[e.type];if(!t){const t=`Unknown element type: "${e.type}"`;throw d("DESIGN_INVALID",t,{errors:[{path:"type",message:t}],knownTypes:Object.keys(TYPES_MAP)})}return t}},g,y,m,u,f,E,b,v,i.late(()=>GroupElement),...x);const w=Object.freeze({x:0,y:0,offsetX:0,offsetY:0,scaleX:1,scaleY:1,rotation:0,opacity:1});function j(e){return 1===e?w:Object.assign(Object.assign({},w),{opacity:e})}const O={x:0,y:0,width:0,height:0,rotation:0,opacity:1,fontSize:0,cropX:0,cropY:0,cropWidth:1,cropHeight:1},P=(e,t)=>"number"==typeof e&&isFinite(e)?e:t;function C(e,t,o,i){O.x=e.x,O.y=e.y,O.width=e.width,O.height=e.height,O.opacity=i;const r=a({element:O,animation:t,dTime:o})||{},n=P(r.width,e.width),s=P(r.height,e.height);return{x:P(r.x,e.x),y:P(r.y,e.y),width:n>0?n:e.width,height:s>0?s:e.height,rotation:P(r.rotation,0),opacity:P(r.opacity,i)}}export const GroupElement=n.named("Group").props({type:"group",children:i.array(ElementTypes),animations:i.array(s)}).views(e=>({get draggable(){let t=!0;return forEveryChild(e,e=>{e.draggable||(t=!1)}),t},get resizable(){let t=!0;return forEveryChild(e,e=>{e.resizable||(t=!1)}),t},get contentEditable(){let t=!0;return forEveryChild(e,e=>{e.contentEditable||(t=!1)}),t},get styleEditable(){let t=!0;return forEveryChild(e,e=>{e.styleEditable||(t=!1)}),t},get locked(){let t=!0;return forEveryChild(e,e=>{e.locked||(t=!1)}),t},get _restingBbox(){const t=[];if(forEveryChild(e,e=>{var o,i,r;if("group"===e.type){return}const n=e.width,s=e.height;!n||!s||n<=0||s<=0||t.push({x:null!==(o=e.x)&&void 0!==o?o:0,y:null!==(i=e.y)&&void 0!==i?i:0,width:n,height:s,rotation:null!==(r=e.rotation)&&void 0!==r?r:0})}),!t.length){return null}const o=h(t);return o.width<=0||o.height<=0?null:{x:o.x,y:o.y,width:o.width,height:o.height}},get a(){if(!o(e)){return w}const t=c(e);if(null===t){return j(e.opacity)}if(e.store.isEditingPaused&&this.isSelectedDirectly){return j(e.opacity)}const i=e.page,r=e.store.animatedElementsIds;if(r.length&&!r.includes(e.id)){return j(e.opacity)}let n,s,l;for(const o of e.animations){o.enabled&&("enter"===o.type?n=o:"exit"===o.type?s=o:"loop"===o.type&&(l=o))}const a=!!n&&t<n.delay,d=!!n&&t>=n.delay&&t<=n.delay+n.duration,h=!a&&!d&&!!s&&t>=i.duration-s.duration-s.delay&&t<=i.duration-s.delay,y=!!s&&t>=i.duration-s.delay;if(!(a||d||h||y||l)){return j(e.opacity)}const m=this._restingBbox;if(!m){return j(e.opacity)}let f={x:m.x,y:m.y,width:m.width,height:m.height,rotation:0,opacity:e.opacity};a&&(f.opacity=0),d&&(f=C(m,n,t-n.delay,e.opacity)),h&&(f=C(m,s,t-(i.duration-s.duration-s.delay),e.opacity)),y&&(f.opacity=0),l&&(f=C(f,l,t,f.opacity));const u=p(f);return{x:u.x,y:u.y,offsetX:m.x+m.width/2,offsetY:m.y+m.height/2,scaleX:f.width/m.width,scaleY:f.height/m.height,rotation:f.rotation,opacity:f.opacity}},get isSelectedDirectly(){return!!o(e)&&e.store.selectedElements.indexOf(e)>=0&&e.selectable},get active(){return!0}})).actions(t=>Object.assign(Object.assign({set(o){var{draggable:i,contentEditable:r,styleEditable:n,resizable:s}=o,l=e(o,["draggable","contentEditable","styleEditable","resizable"]);void 0!==i&&forEveryChild(t,e=>{e.set({draggable:i})}),void 0!==r&&forEveryChild(t,e=>{e.set({contentEditable:r})}),void 0!==n&&forEveryChild(t,e=>{e.set({styleEditable:n})}),void 0!==s&&forEveryChild(t,e=>{e.set({resizable:s})}),Object.assign(t,l)},addElement(e,{skipSelect:o=!1}={}){const i=TYPES_MAP[e.type];if(!i){return void console.error("Can not find model with type "+e.type)}e.children&&e.children.forEach(e=>{e.id=e.id||r(10)});const n=i.create(Object.assign({id:r(10)},e));return t.children.push(n),n.selectable&&!o&&t.store.selectElements([n.id]),n}},zIndexOps(t)),{setAnimation(e,o){const i=t.animations.find(t=>t.type===e);i?Object.assign(i,o):t.animations.push(Object.assign({type:e},o))}}));const S=[];export const TYPES_MAP={svg:g,text:y,image:m,group:GroupElement,line:u,video:f,figure:E,gif:b,table:v};export function registerShapeModel(e,t){const o=e.type;if(!o){throw new Error('You must pass "type" attribute to custom model.')}let i=l.named(o).props(e);t&&(i=t(i)),TYPES_MAP[o]=i,S.push(i)}
|
package/model/page-model.d.ts
CHANGED
|
@@ -238,6 +238,7 @@ export declare const Page: import("mobx-state-tree").IModelType<{
|
|
|
238
238
|
verticalAlign: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
239
239
|
strokeWidth: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
240
240
|
stroke: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
241
|
+
strokeLineJoin: import("mobx-state-tree").IType<string | undefined, string, string>;
|
|
241
242
|
lineHeight: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree/dist/internal").IUnionType<[import("mobx-state-tree").ISimpleType<number>, import("mobx-state-tree").ISimpleType<string>]>, [undefined]>;
|
|
242
243
|
letterSpacing: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
243
244
|
_editModeEnabled: import("mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|