@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 10.5 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import t from"../../Color.js";import has from"../../core/has.js";import{assertIsSome as e}from"../../core/maybe.js";import{create as i}from"../../core/libs/gl-matrix-2/factories/mat2df32.js";import{multiply as r,scale as n,identity as o,translate as a,rotate as s}from"../../core/libs/gl-matrix-2/math/mat2d.js";import{getDashArray as l}from"./gfxUtils.js";import{nextBloomId as h,nextPatternId as f,nextLinearGradientId as c}from"./svgGlobalState.js";import"../../widgets/support/widgetUtils.js";import{tsx as u}from"../../widgets/support/jsxFactory.js";const d="http://www.w3.org/2000/svg",y=has("android"),p=has("chrome")||y&&y>=4?"auto":"optimizeLegibility",g={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7,z:0},m=/([A-DF-Za-df-z])|([-+]?\d*[.]?\d+(?:[eE][-+]?\d+)?)/g;let x={},w={};const k=Math.PI;function b(t,e){const i=t*(k/180);return Math.abs(e*Math.sin(i))+Math.abs(e*Math.cos(i))}function j(t){return t.map((t=>`${t.command} ${t.values.join(" ")}`)).join(" ").trim()}function M(t,i,r,n,o){if(t){if("circle"===t.type)return u("circle",{cx:t.cx,cy:t.cy,fill:i,"fill-rule":"evenodd",r:t.r,stroke:r.color,"stroke-dasharray":r.dashArray,"stroke-dashoffset":r.dashOffset,"stroke-linecap":r.cap,"stroke-linejoin":r.join,"stroke-miterlimit":"4","stroke-width":r.width});if("ellipse"===t.type)return u("ellipse",{cx:t.cx,cy:t.cy,fill:i,"fill-rule":"evenodd",rx:t.rx,ry:t.ry,stroke:r.color,"stroke-dasharray":r.dashArray,"stroke-linecap":r.cap,"stroke-linejoin":r.join,"stroke-miterlimit":"4","stroke-width":r.width});if("rect"===t.type)return u("rect",{fill:i,"fill-rule":"evenodd",height:t.height,stroke:r.color,"stroke-dasharray":r.dashArray,"stroke-linecap":r.cap,"stroke-linejoin":r.join,"stroke-miterlimit":"4","stroke-width":r.width,width:t.width,x:t.x,y:t.y});if("image"===t.type)return u("image",{alt:o||"image",height:t.height,href:t.src,preserveAspectRatio:"none",width:t.width,x:t.x,y:t.y});if("path"===t.type){const e="string"!=typeof t.path?j(t.path):t.path;return u("path",{d:e,fill:i,"fill-rule":"evenodd",stroke:r.color,"stroke-dasharray":r.dashArray,"stroke-linecap":r.cap,"stroke-linejoin":r.join,"stroke-miterlimit":"4","stroke-width":r.width})}if("text"===t.type)return e(n),u("text",{"dominant-baseline":n.dominantBaseline,fill:i,"fill-rule":"evenodd","font-family":n.font.family,"font-size":n.font.size,"font-style":n.font.style,"font-variant":n.font.variant,"font-weight":n.font.weight,kerning:n.kerning,rotate:n.rotate,stroke:r.color,"stroke-dasharray":r.dashArray,"stroke-linecap":r.cap,"stroke-linejoin":r.join,"stroke-miterlimit":"4","stroke-width":r.width,"text-anchor":n.align,"text-decoration":n.decoration,"text-rendering":p,x:t.x,y:t.y},t.text)}return null}function v(e){if(!e)return{fill:"none",pattern:null,linearGradient:null};if(!("type"in e))return{fill:new t(e).toString(),pattern:null,linearGradient:null};if("pattern"===e.type){const t=`patternId-${f()}`;return{fill:`url(#${t})`,pattern:{id:t,x:e.x,y:e.y,width:e.width,height:e.height,image:{x:0,y:0,width:e.width,height:e.height,href:e.src}},linearGradient:null}}const i=`linearGradientId-${c()}`;return{fill:`url(#${i})`,pattern:null,linearGradient:{id:i,x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,stops:e.colors.map((e=>({offset:e.offset,color:e.color&&new t(e.color).toString()})))}}}function S(e){const i={color:"none",width:1,cap:"butt",join:"4",dashArray:"none",dashOffset:"0"};return e&&(null!=e.width&&(i.width=e.width),e.cap&&(i.cap=e.cap),e.join&&(i.join=e.join.toString()),e.color&&(i.color=new t(e.color).toString()),e.dashArray&&(i.dashArray=e.dashArray),e.dashoffset&&(i.dashOffset=e.dashoffset),e.style&&!e.dashArray&&(i.dashArray=l(e).join(",")||"none")),i}function $(t,i){const r={align:null,decoration:null,kerning:null,rotate:null,font:{style:null,variant:null,weight:null,size:null,family:null}};if(t){const n=t.alignBaseline,o="baseline"===n?"auto":"top"===n?"text-top":"bottom"===n?"hanging":n;r.align=t.align,r.dominantBaseline=o,r.decoration=t.decoration,r.kerning=t.kerning?"auto":"0",r.rotate=t.rotated?"90":"0",e(i),r.font.style=i.style||"normal",r.font.variant=i.variant||"normal",r.font.weight=i.weight||"normal",r.font.size=i.size&&i.size.toString()||"10pt",r.font.family=i.family||"serif"}return r}function A(t){const{pattern:e,linearGradient:i}=t;if(e)return u("pattern",{height:e.height,id:e.id,patternUnits:"userSpaceOnUse",width:e.width,x:e.x,y:e.y},u("image",{height:e.image.height,href:e.image.href,width:e.image.width,x:e.image.x,y:e.image.y}));if(i){const t=i.stops.map(((t,e)=>u("stop",{key:`${e}-stop`,offset:t.offset,"stop-color":t.color})));return u("linearGradient",{gradientUnits:"userSpaceOnUse",id:i.id,x1:i.x1,x2:i.x2,y1:i.y1,y2:i.y2},t)}return null}function G(t,e){if(!t||0===t.length)return null;const i=[];for(const r of t){const{shape:t,fill:e,stroke:n,font:o}=r,a=v(e),s=S(n),l="text"===t.type?$(t,o):null,h=M(t,a.fill,s,l);h&&i.push(h)}return u("mask",{id:e,maskUnits:"userSpaceOnUse"},u("g",null,i))}function N(t,e,i){return a(t,o(t),[e,i])}function z(t,e,i,r,a){return n(t,o(t),[e,i]),t[4]=t[4]*e-r*e+r,t[5]=t[5]*i-a*i+a,t}function B(t,e,i,r){const n=e%360*Math.PI/180;s(t,o(t),n);const a=Math.cos(n),l=Math.sin(n),h=t[4],f=t[5];return t[4]=h*a-f*l+r*l-i*a+i,t[5]=f*a+h*l-i*l-r*a+r,t}function I(t,e){x&&"left"in x?(null!=x.left&&x.left>t&&(x.left=t),(null==x.right||x.right<t)&&(x.right=t),(null==x.top||x.top>e)&&(x.top=e),(null==x.bottom||x.bottom<e)&&(x.bottom=e)):x={left:t,bottom:e,right:t,top:e}}function U(t){const e=t.args,i=e.length;let r;switch(t.action){case"M":case"L":case"C":case"S":case"Q":case"T":for(r=0;r<i;r+=2)I(e[r],e[r+1]);w.x=e[i-2],w.y=e[i-1];break;case"H":for(r=0;r<i;++r)I(e[r],w.y);w.x=e[i-1];break;case"V":for(r=0;r<i;++r)I(w.x,e[r]);w.y=e[i-1];break;case"m":{let t=0;"x"in w||(I(w.x=e[0],w.y=e[1]),t=2);for(r=t;r<i;r+=2)I(w.x+=e[r],w.y+=e[r+1]);break}case"l":case"t":for(r=0;r<i;r+=2)I(w.x+=e[r],w.y+=e[r+1]);break;case"h":for(r=0;r<i;++r)I(w.x+=e[r],w.y);break;case"v":for(r=0;r<i;++r)I(w.x,w.y+=e[r]);break;case"c":for(r=0;r<i;r+=6)I(w.x+e[r],w.y+e[r+1]),I(w.x+e[r+2],w.y+e[r+3]),I(w.x+=e[r+4],w.y+=e[r+5]);break;case"s":case"q":for(r=0;r<i;r+=4)I(w.x+e[r],w.y+e[r+1]),I(w.x+=e[r+2],w.y+=e[r+3]);break;case"A":for(r=0;r<i;r+=7)I(e[r+5],e[r+6]);w.x=e[i-2],w.y=e[i-1];break;case"a":for(r=0;r<i;r+=7)I(w.x+=e[r+5],w.y+=e[r+6])}}function F(t,e,i){const r=g[t.toLowerCase()];let n;"number"==typeof r&&(r?e.length>=r&&(n={action:t,args:e.slice(0,e.length-e.length%r)},i.push(n),U(n)):(n={action:t,args:[]},i.push(n),U(n)))}function O(t){const e=("string"!=typeof t.path?j(t.path):t.path).match(m),i=[];if(x={},w={},!e)return null;let r="",n=[];const o=e.length;for(let s=0;s<o;++s){const t=e[s],o=parseFloat(t);isNaN(o)?(r&&F(r,n,i),n=[],r=t):n.push(o)}F(r,n,i);const a={x:0,y:0,width:0,height:0};return x&&"left"in x&&(a.x=x.left,a.y=x.top,a.width=x.right-x.left,a.height=x.bottom-x.top),a}function E(t){const e={x:0,y:0,width:0,height:0};if("circle"===t.type)e.x=t.cx-t.r,e.y=t.cy-t.r,e.width=2*t.r,e.height=2*t.r;else if("ellipse"===t.type)e.x=t.cx-t.rx,e.y=t.cy-t.ry,e.width=2*t.rx,e.height=2*t.ry;else if("image"===t.type||"rect"===t.type)e.x=t.x,e.y=t.y,e.width=t.width,e.height=t.height;else if("path"===t.type){const i=O(t);e.x=i.x,e.y=i.y,e.width=i.width,e.height=i.height}return e}function T(t){const e={x:0,y:0,width:0,height:0};let i=null,r=Number.NEGATIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(const o of t)i?(i.x=Math.min(i.x,o.x),i.y=Math.min(i.y,o.y),r=Math.max(r,o.x+o.width),n=Math.max(n,o.y+o.height)):(i=e,i.x=o.x,i.y=o.y,r=o.x+o.width,n=o.y+o.height);return i&&(i.width=r-i.x,i.height=n-i.y),i}function L(t,e,n,o,a,s,l,h,f){let c=(l&&s?b(s,e):e)/2,u=(l&&s?b(s,n):n)/2;if(f){const t=f[0],e=f[1];c=(l&&s?b(s,t):t)/2,u=(l&&s?b(s,e):e)/2}const d=t.width+o,y=t.height+o,p=i(),g=i();let m=!1;if(a&&0!==d&&0!==y){const t=e!==n?e/n:d/y,i=e>n?e:n;let o=1,a=1;isNaN(i)||(t>1?(o=i/d,a=i/t/y):(a=i/y,o=i*t/d)),r(g,g,z(p,o,a,c,u)),m=!0}const x=t.x+(d-o)/2,w=t.y+(y-o)/2;if(r(g,g,N(p,c-x,u-w)),!m&&(d>e||y>n)){const t=d/e>y/n,i=(t?e:n)/(t?d:y);r(g,g,z(p,i,i,x,w))}return h&&r(g,g,N(p,h[0],h[1])),s&&r(g,g,B(p,s,x,w)),`matrix(${g[0]},${g[1]},${g[2]},${g[3]},${g[4]},${g[5]})`}function R(t,e,i){const r=t?.effects.find((t=>"bloom"===t.type));if(!r)return null;const{strength:n,radius:o}=r,a=n>0?o:0,s=(n+a)*e,l=4*n+1;return u("filter",{filterUnits:"userSpaceOnUse",height:"300%",id:`bloom${i}`,width:"300%",x:"-100%",y:"-100%"},u("feMorphology",{in:"SourceGraphic",operator:"dilate",radius:(n+.5*a)*(5**(e/100)*(.4+e/100)),result:"dilate"}),u("feGaussianBlur",{in:"dilate",result:"blur",stdDeviation:s/25}),u("feGaussianBlur",{in:"blur",result:"intensityBlur",stdDeviation:s/50}),u("feComponentTransfer",{in:"SourceGraphic",result:"intensityBrightness"},u("feFuncR",{slope:l,type:"linear"}),u("feFuncG",{slope:l,type:"linear"}),u("feFuncB",{slope:l,type:"linear"})),u("feMerge",null,u("feMergeNode",{in:"intensityBlur"}),u("feMergeNode",{in:"intensityBrightness"}),u("feGaussianBlur",{stdDeviation:n/10})))}function V(t,i,r,n={}){const o=[],a=[],s=h(),l=R(n.effectView,i,s);let f=null;if(l){const t=n.effectView?.effects.find((t=>"bloom"===t.type)),e=n.clipBloomEffect||!t.strength?0:(t.strength+t.radius/2)/3,o=i+i*e,a=r+r*e;f=[Math.max(o,10),Math.max(a,10)]}let c=i,y=r;if(n.useRotationSize)for(let e=0;e<t.length;e++){const t=n.rotations?.[e]??0;c=Math.max(b(t,i),c),y=Math.max(b(t,r),y)}for(let e=0;e<t.length;e++){const s=t[e],l=[],h=[];let d=0,p=0,g=0;for(const t of s){const{shape:e,fill:i,stroke:r,font:a,offset:s}=t;n.ignoreStrokeWidth||"text"===e.type||(d+=r?.width||0);const f=v(i),c=S(r),u="text"===e.type?$(e,a):null;o.push(A(f)),l.push(M(e,f.fill,c,u,n.ariaLabel)),h.push(E(e)),s&&(p+=s[0],g+=s[1])}const m=n.rotations?.[e]??0;n.useRotationSize&&(p+=(c-b(m,i))/2,g+=(y-b(m,r))/2);const x=L(T(h),i,r,d,n.scale??!1,m,n.useRotationSize??!1,[p,g],f);let w=null;if(n.masking){const t=`mask-${e}`,i=n.masking[e];o.push(G(i,t)),w=`url(#${t})`}a.push(w?u("g",{mask:w},u("g",{transform:x},l)):u("g",{transform:x},l))}l&&(e(f),c=f[0],y=f[1]);const p="display: block;";return u("svg",{"aria-label":n.ariaLabel,focusable:!1,height:y,role:"img",style:p,width:c,xmlns:d},l,u("defs",null,o),l?u("g",{filter:`url(#bloom${s})`},a):a)}export{T as computeBBox,v as generateFillAttributes,S as generateStrokeAttributes,$ as generateTextAttributes,E as getBoundingBox,L as getTransformMatrix,A as renderDef,V as renderSVG,M as renderShape};