@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 6.32 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{packFloatRGBA as o}from"../../core/floatRGBA.js";import t from"../../core/Logger.js";import{nextPowerOfTwo as e}from"../../core/mathUtils.js";import{dashSdfRasterizationScale as r,dashSdfDistanceNormalization as n,dashRadius as a}from"./constants.js";import{defaultCIMValues as s}from"./defaultCIMValues.js";import{gradientTextureExternalPadding as i}from"../../views/2d/engine/webgl/definitions.js";const l=()=>t.getLogger("esri.symbols.cim.rasterizingUtils"),c=32,h=o=>"vertical"===o||"horizontal"===o||"cross"===o||"esriSFSCross"===o||"esriSFSVertical"===o||"esriSFSHorizontal"===o;function f(o,t,r){const n=t.style,a=e(Math.ceil(r)),s=h(n)?8*a:16*a,i=2*a;o.width=s,o.height=s;const l=o.getContext("2d");l.strokeStyle="#ffffff",l.lineWidth=a,l.beginPath(),"vertical"!==n&&"cross"!==n&&"esriSFSCross"!==n&&"esriSFSVertical"!==n||(l.moveTo(s/2,-i),l.lineTo(s/2,s+i)),"horizontal"!==n&&"cross"!==n&&"esriSFSCross"!==n&&"esriSFSHorizontal"!==n||(l.moveTo(-i,s/2),l.lineTo(s+i,s/2)),"backward-diagonal"!==n&&"diagonal-cross"!==n&&"esriSFSDiagonalCross"!==n&&"esriSFSBackwardDiagonal"!==n||(l.moveTo(-i,-i),l.lineTo(s+i,s+i),l.moveTo(s-i,-i),l.lineTo(s+i,i),l.moveTo(-i,s-i),l.lineTo(i,s+i)),"forward-diagonal"!==n&&"diagonal-cross"!==n&&"esriSFSForwardDiagonal"!==n&&"esriSFSDiagonalCross"!==n||(l.moveTo(s+i,-i),l.lineTo(-i,s+i),l.moveTo(i,-i),l.lineTo(-i,i),l.moveTo(s+i,s-i),l.lineTo(s-i,s+i)),l.stroke();const c=l.getImageData(0,0,o.width,o.height),f=new Uint8Array(c.data);let m;for(let e=0;e<f.length;e+=4)m=f[e+3]/255,f[e]=f[e]*m,f[e+1]=f[e+1]*m,f[e+2]=f[e+2]*m;return[f,o.width,o.height,a]}function m(t){t.length%2==1&&(t=[...t,...t]);const e=t.reduce(((o,t)=>o+t),0),a=Math.round(e*r),s=1,i=new Float32Array(a*s);let l=0,c=0,h=.5,f=!0;for(const o of t){for(l=c,c+=o*r;h<=c;){const o=h-.5,t=Math.min(Math.abs(h-l),Math.abs(h-c));i[o]=f?-t:t,h++}f=!f}const m=i.length,u=new Uint8Array(4*m);for(let g=0;g<m;++g){const t=i[g]/r;o(t/n*.5+.5,u,4*g)}return[u,a,s]}function u(t,e){null==t&&(t=[]);const r="Butt"===e,n="Square"===e,s=!r&&!n;t.length%2==1&&(t=[...t,...t]);const i=a,l=2*i;let c=0;for(const o of t)c+=o;const h=Math.round(c*i),f=new Float32Array(h*l),m=.5*i;let u=0,g=0,d=.5,p=!0;for(const o of t){for(u=g,g+=o*i;d<=g;){let o=.5;for(;o<l;){const t=(o-.5)*h+d-.5,e=s?(o-i)*(o-i):Math.abs(o-i);f[t]=p?r?Math.max(Math.max(u+m-d,e),Math.max(d-g+m,e)):e:s?Math.min((d-u)*(d-u)+e,(d-g)*(d-g)+e):n?Math.min(Math.max(d-u,e),Math.max(g-d,e)):Math.min(Math.max(d-u+m,e),Math.max(g+m-d,e)),o++}d++}p=!p}const C=f.length,M=new Uint8Array(4*C);for(let a=0;a<C;++a){const t=(s?Math.sqrt(f[a]):f[a])/i;o(t,M,4*a)}return[M,h,l]}function g(o,t){const{colorRamp:e,gradientType:r}=t,n="CIMFixedColorRamp"===e.type,a=t.interval||s.CIMGradientFill.interval;let i=C(e);return n&&(i=M(i,a)),"Discrete"===r||n?w(o,i,a):x(o,i)}let d;function p(o,t){const{colorRamp:e,gradientType:r}=t,n=C(e),a="CIMFixedColorRamp"===e.type;if("Continuous"===r&&!a)return y(o,n);const i=t.interval??s.CIMGradientFill.interval;if(a){return y(o,M(n,i))}const l=[];d??=document.createElement("canvas"),S(d,n,i,1,0);const c=d.getContext("2d").getImageData(0,0,i,1).data;for(let s=0,h=0;s<i;s++,h=4*s){const o=[c[h+0],c[h+1],c[h+2],c[h+3]];l.push({offset:s/i,color:o}),l.push({offset:(s+1)/i,color:o})}return y(o,l)}function C(o){const t=[];switch(o.type){case"CIMPolarContinuousColorRamp":case"CIMLinearContinuousColorRamp":{"CIMPolarContinuousColorRamp"===o.type&&l().warnOnce("CIMPolarContinuousColorRamp is currently unsupported. Falling back to CIMLinearContinuousColorRamp.");const e=o;t.push({offset:0,color:[e.fromColor[0],e.fromColor[1],e.fromColor[2],e.fromColor[3]/255]}),t.push({offset:1,color:[e.toColor[0],e.toColor[1],e.toColor[2],e.toColor[3]/255]});break}case"CIMFixedColorRamp":{const e=o,r=1/(e.colors.length-1);let n=0;for(const o of e.colors)t.push({offset:n,color:[o[0],o[1],o[2],o[3]/255]}),n+=r;break}case"CIMMultipartColorRamp":{const e=o,r=e.weights.reduce(((o,t)=>o+t),0);let n=0;for(let o=0;o<e.colorRamps.length;o++){const a=e.colorRamps[o],s=e.weights[o],i=C(a);for(const o of i)t.push({offset:(n+o.offset*s)/r,color:o.color});n+=s}break}default:l().error(`Color ramp "${o.type}" currently unsupported.`)}return t}function M(o,t){const e=[],r=(o.length-1)/(t-1);for(let n=0;n<t;n++){const a=o[Math.round(n*r)].color;e.push({offset:n/t,color:a}),e.push({offset:(n+1)/t,color:a})}return e}function x(o,t){return S(o,t,c,1,i),F(o)}function w(o,t,e){return S(o,t,e,1,i),F(o)}function y(o,t,e=0){for(const{offset:r,color:n}of t)o.addColorStop(Math.min(Math.max(r,e),1-e),`rgba(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]})`)}function S(o,t,e,r,n){const a=e+2*n;o.width=a,o.height=r;const s=(n+1)/a,i=o.getContext("2d",{willReadFrequently:!0});if(t.length>0){const o=i.createLinearGradient(0,0,a,r);y(o,t,s),i.fillStyle=o}else i.fillStyle="rgba(128, 128, 128, 1)";i.fillRect(0,0,a,r)}function F(o){const{width:t,height:e}=o,r=o.getContext("2d").getImageData(0,0,t,e),n=new Uint8Array(r.data);for(let a=0;a<n.length;a+=4){const o=n[a+3]/255;n[a]*=o,n[a+1]*=o,n[a+2]*=o}return[n,t,e]}function v(o){const t=o[0]?.[0]?.[0]??0,e=o[0]?.[0]?.[1]??0,r={ymin:e,xmin:t,ymax:e,xmax:t,width:0,height:0};for(let n=0;n<o.length;n++){const t=o[n];for(let o=0;o<t.length;o++){const e=t[o][0],n=t[o][1];e<r.xmin&&(r.xmin=e),e>r.xmax&&(r.xmax=e),n<r.ymin&&(r.ymin=n),n>r.ymax&&(r.ymax=n)}}return r.width=Math.abs(r.xmax-r.xmin),r.height=Math.abs(r.ymax-r.ymin),r}function T(o,t){const e=v(o),r=0===e.width?1:e.width,n=0===e.height?1:e.height,a=[];for(let s=0;s<o.length;s++){const i=o[s],l=[];for(let o=0;o<i.length;o++){let a=Math.round(i[o][0]-e.xmin),s=Math.round(i[o][1]-e.ymin);if(a=t.xmin+a*t.width/r,s=t.ymin+s*t.height/n,isNaN(a)||isNaN(s))throw new Error("Scaled shape has NaN values");l.push([a,s])}a.push(l)}return a}function R(o,t,e){const r=[];for(let n=0;n<o.length;n++){const a=o[n],s=[];for(let o=0;o<a.length;o++){const r=a[o][0]+t,n=a[o][1]+e;if(isNaN(r)||isNaN(n))throw new Error("Scaled shape has NaN values");s.push([r,n])}r.push(s)}return r}export{p as addColorStops,u as rasterizeDash,m as rasterizeDash1D,f as rasterizeFillStyle,g as rasterizeGradient,T as scale,R as translate};