wired-lib
Version:
Core sketchy rendering lib used by wired components
2 lines (1 loc) • 8.57 kB
JavaScript
function t(t,n,e){if(t&&t.length){const[o,s]=n,r=Math.PI/180*e,i=Math.cos(r),a=Math.sin(r);t.forEach(t=>{const[n,e]=t;t[0]=(n-o)*i-(e-s)*a+o,t[1]=(n-o)*a+(e-s)*i+s})}}function n(t){const n=t[0],e=t[1];return Math.sqrt(Math.pow(n[0]-e[0],2)+Math.pow(n[1]-e[1],2))}function e(t,n,e,o){const s=n[1]-t[1],r=t[0]-n[0],i=s*t[0]+r*t[1],a=o[1]-e[1],c=e[0]-o[0],h=a*e[0]+c*e[1],u=s*c-a*r;return u?[(c*i-r*h)/u,(s*h-a*i)/u]:null}function o(t,n,e){const o=t.length;if(o<3)return!1;const a=[Number.MAX_SAFE_INTEGER,e],c=[n,e];let h=0;for(let n=0;n<o;n++){const e=t[n],u=t[(n+1)%o];if(i(e,u,c,a)){if(0===r(e,c,u))return s(e,c,u);h++}}return h%2==1}function s(t,n,e){return n[0]<=Math.max(t[0],e[0])&&n[0]>=Math.min(t[0],e[0])&&n[1]<=Math.max(t[1],e[1])&&n[1]>=Math.min(t[1],e[1])}function r(t,n,e){const o=(n[1]-t[1])*(e[0]-n[0])-(n[0]-t[0])*(e[1]-n[1]);return 0===o?0:o>0?1:2}function i(t,n,e,o){const i=r(t,n,e),a=r(t,n,o),c=r(e,o,t),h=r(e,o,n);return i!==a&&c!==h||(!(0!==i||!s(t,e,n))||(!(0!==a||!s(t,o,n))||(!(0!==c||!s(e,t,o))||!(0!==h||!s(e,n,o)))))}function a(n,e){const o=[0,0],s=Math.round(e.hachureAngle+90);s&&t(n,o,s);const r=function(t,n){const e=[...t];e[0].join(",")!==e[e.length-1].join(",")&&e.push([e[0][0],e[0][1]]);const o=[];if(e&&e.length>2){let t=n.hachureGap;t<0&&(t=4*n.strokeWidth),t=Math.max(t,.1);const s=[];for(let t=0;t<e.length-1;t++){const n=e[t],o=e[t+1];if(n[1]!==o[1]){const t=Math.min(n[1],o[1]);s.push({ymin:t,ymax:Math.max(n[1],o[1]),x:t===n[1]?n[0]:o[0],islope:(o[0]-n[0])/(o[1]-n[1])})}}if(s.sort((t,n)=>t.ymin<n.ymin?-1:t.ymin>n.ymin?1:t.x<n.x?-1:t.x>n.x?1:t.ymax===n.ymax?0:(t.ymax-n.ymax)/Math.abs(t.ymax-n.ymax)),!s.length)return o;let r=[],i=s[0].ymin;for(;r.length||s.length;){if(s.length){let t=-1;for(let n=0;n<s.length&&!(s[n].ymin>i);n++)t=n;s.splice(0,t+1).forEach(t=>{r.push({s:i,edge:t})})}if(r=r.filter(t=>!(t.edge.ymax<=i)),r.sort((t,n)=>t.edge.x===n.edge.x?0:(t.edge.x-n.edge.x)/Math.abs(t.edge.x-n.edge.x)),r.length>1)for(let t=0;t<r.length;t+=2){const n=t+1;if(n>=r.length)break;const e=r[t].edge,s=r[n].edge;o.push([[Math.round(e.x),i],[Math.round(s.x),i]])}i+=t,r.forEach(n=>{n.edge.x=n.edge.x+t*n.edge.islope})}}return o}(n,e);return s&&(t(n,o,-s),function(n,e,o){const s=[];n.forEach(t=>s.push(...t)),t(s,e,o)}(r,o,-s)),r}class c extends class{constructor(t){this.helper=t}fillPolygon(t,n){return this._fillPolygon(t,n)}_fillPolygon(t,n,e=!1){let o=a(t,n);if(e){const n=this.connectingLines(t,o);o=o.concat(n)}return{type:"fillSketch",ops:this.renderLines(o,n)}}renderLines(t,n){const e=[];for(const o of t)e.push(...this.helper.doubleLineOps(o[0][0],o[0][1],o[1][0],o[1][1],n));return e}connectingLines(t,e){const o=[];if(e.length>1)for(let s=1;s<e.length;s++){const r=e[s-1];if(n(r)<3)continue;const i=[e[s][0],r[1]];if(n(i)>3){const n=this.splitOnIntersections(t,i);o.push(...n)}}return o}midPointInPolygon(t,n){return o(t,(n[0][0]+n[1][0])/2,(n[0][1]+n[1][1])/2)}splitOnIntersections(t,s){const r=Math.max(5,.1*n(s)),a=[];for(let o=0;o<t.length;o++){const c=t[o],h=t[(o+1)%t.length];if(i(c,h,...s)){const t=e(c,h,s[0],s[1]);if(t){const e=n([t,s[0]]),o=n([t,s[1]]);e>r&&o>r&&a.push({point:t,distance:e})}}}if(a.length>1){const n=a.sort((t,n)=>t.distance-n.distance).map(t=>t.point);if(o(t,...s[0])||n.shift(),o(t,...s[1])||n.pop(),n.length<=1)return this.midPointInPolygon(t,s)?[s]:[];const e=[s[0],...n,s[1]],r=[];for(let n=0;n<e.length-1;n+=2){const o=[e[n],e[n+1]];this.midPointInPolygon(t,o)&&r.push(o)}return r}return this.midPointInPolygon(t,s)?[s]:[]}}{fillPolygon(t,n){return this._fillPolygon(t,n,!0)}}class h{constructor(t){this.seed=t}next(){return this.seed?(2**31-1&(this.seed=Math.imul(48271,this.seed)))/2**31:Math.random()}}function u(t,n,e,o,s){return{type:"path",ops:M(t,n,e,o,s)}}function l(t,n){return function(t,n,e){const o=(t||[]).length;if(o>2){const s=[];for(let n=0;n<o-1;n++)s.push(...M(t[n][0],t[n][1],t[n+1][0],t[n+1][1],e));return n&&s.push(...M(t[o-1][0],t[o-1][1],t[0][0],t[0][1],e)),{type:"path",ops:s}}return 2===o?u(t[0][0],t[0][1],t[1][0],t[1][1],e):{type:"path",ops:[]}}(t,!0,n)}function f(t,n,e,o,s){return function(t,n,e,o){const[s,r]=b(o.increment,t,n,o.rx,o.ry,1,o.increment*g(.1,g(.4,1,e),e),e);let i=y(s,null,e);if(!e.disableMultiStroke){const[s]=b(o.increment,t,n,o.rx,o.ry,1.5,0,e),r=y(s,null,e);i=i.concat(r)}return{estimatedPoints:r,opset:{type:"path",ops:i}}}(t,n,s,p(e,o,s)).opset}function p(t,n,e){const o=Math.sqrt(2*Math.PI*Math.sqrt((Math.pow(t/2,2)+Math.pow(n/2,2))/2)),s=Math.max(e.curveStepCount,e.curveStepCount/Math.sqrt(200)*o),r=2*Math.PI/s;let i=Math.abs(t/2),a=Math.abs(n/2);const c=1-e.curveFitting;return i+=m(i*c,e),a+=m(a*c,e),{increment:r,rx:i,ry:a}}function d(t){return t.randomizer||(t.randomizer=new h(t.seed||0)),t.randomizer.next()}function g(t,n,e,o=1){return e.roughness*o*(d(e)*(n-t)+t)}function m(t,n,e=1){return g(-t,t,n,e)}function M(t,n,e,o,s,r=!1){const i=r?s.disableMultiStrokeFill:s.disableMultiStroke,a=x(t,n,e,o,s,!0,!1);if(i)return a;const c=x(t,n,e,o,s,!0,!0);return a.concat(c)}function x(t,n,e,o,s,r,i){const a=Math.pow(t-e,2)+Math.pow(n-o,2),c=Math.sqrt(a);let h=1;h=c<200?1:c>500?.4:-.0016668*c+1.233334;let u=s.maxRandomnessOffset||0;u*u*100>a&&(u=c/10);const l=u/2,f=.2+.2*d(s);let p=s.bowing*s.maxRandomnessOffset*(o-n)/200,g=s.bowing*s.maxRandomnessOffset*(t-e)/200;p=m(p,s,h),g=m(g,s,h);const M=[],x=()=>m(l,s,h),y=()=>m(u,s,h);return r&&(i?M.push({op:"move",data:[t+x(),n+x()]}):M.push({op:"move",data:[t+m(u,s,h),n+m(u,s,h)]})),i?M.push({op:"bcurveTo",data:[p+t+(e-t)*f+x(),g+n+(o-n)*f+x(),p+t+2*(e-t)*f+x(),g+n+2*(o-n)*f+x(),e+x(),o+x()]}):M.push({op:"bcurveTo",data:[p+t+(e-t)*f+y(),g+n+(o-n)*f+y(),p+t+2*(e-t)*f+y(),g+n+2*(o-n)*f+y(),e+y(),o+y()]}),M}function y(t,n,e){const o=t.length,s=[];if(o>3){const r=[],i=1-e.curveTightness;s.push({op:"move",data:[t[1][0],t[1][1]]});for(let n=1;n+2<o;n++){const e=t[n];r[0]=[e[0],e[1]],r[1]=[e[0]+(i*t[n+1][0]-i*t[n-1][0])/6,e[1]+(i*t[n+1][1]-i*t[n-1][1])/6],r[2]=[t[n+1][0]+(i*t[n][0]-i*t[n+2][0])/6,t[n+1][1]+(i*t[n][1]-i*t[n+2][1])/6],r[3]=[t[n+1][0],t[n+1][1]],s.push({op:"bcurveTo",data:[r[1][0],r[1][1],r[2][0],r[2][1],r[3][0],r[3][1]]})}if(n&&2===n.length){const t=e.maxRandomnessOffset;s.push({op:"lineTo",data:[n[0]+m(t,e),n[1]+m(t,e)]})}}else 3===o?(s.push({op:"move",data:[t[1][0],t[1][1]]}),s.push({op:"bcurveTo",data:[t[1][0],t[1][1],t[2][0],t[2][1],t[2][0],t[2][1]]})):2===o&&s.push(...M(t[0][0],t[0][1],t[1][0],t[1][1],e));return s}function b(t,n,e,o,s,r,i,a){const c=[],h=[],u=m(.5,a)-Math.PI/2;h.push([m(r,a)+n+.9*o*Math.cos(u-t),m(r,a)+e+.9*s*Math.sin(u-t)]);for(let i=u;i<2*Math.PI+u-.01;i+=t){const t=[m(r,a)+n+o*Math.cos(i),m(r,a)+e+s*Math.sin(i)];c.push(t),h.push(t)}return h.push([m(r,a)+n+o*Math.cos(u+2*Math.PI+.5*i),m(r,a)+e+s*Math.sin(u+2*Math.PI+.5*i)]),h.push([m(r,a)+n+.98*o*Math.cos(u+i),m(r,a)+e+.98*s*Math.sin(u+i)]),h.push([m(r,a)+n+.9*o*Math.cos(u+.5*i),m(r,a)+e+.9*s*Math.sin(u+.5*i)]),[h,c]}const P={randOffset:(t,n)=>t,randOffsetWithRange:(t,n,e)=>(t+n)/2,ellipse:(t,n,e,o,s)=>f(t,n,e,o,s),doubleLineOps:(t,n,e,o,s)=>function(t,n,e,o,s){return M(t,n,e,o,s,!0)}(t,n,e,o,s)};function v(t){return{maxRandomnessOffset:2,roughness:1,bowing:.85,stroke:"#000",strokeWidth:1.5,curveTightness:0,curveFitting:.95,curveStepCount:9,fillStyle:"hachure",fillWeight:3.5,hachureAngle:-41,hachureGap:5,dashOffset:-1,dashGap:-1,zigzagOffset:0,combineNestedSvgPaths:!1,disableMultiStroke:!1,disableMultiStrokeFill:!1,seed:t}}function w(t,n){let e="";for(const o of t.ops){const t=o.data;switch(o.op){case"move":if(n&&e)break;e+=`M${t[0]} ${t[1]} `;break;case"bcurveTo":e+=`C${t[0]} ${t[1]}, ${t[2]} ${t[3]}, ${t[4]} ${t[5]} `;break;case"lineTo":e+=`L${t[0]} ${t[1]} `}}return e.trim()}function I(t,n){const e=document.createElementNS("http://www.w3.org/2000/svg",t);if(n)for(const t in n)e.setAttributeNS(null,t,n[t]);return e}function S(t,n,e=!1){const o=I("path",{d:w(t,e)});return n&&n.appendChild(o),o}function k(t,n,e,o,s,r){return S(function(t,n,e,o,s){return l([[t,n],[t+e,n],[t+e,n+o],[t,n+o]],s)}(n+2,e+2,o-4,s-4,v(r)),t)}function O(t,n,e,o,s,r){return S(u(n,e,o,s,v(r)),t)}function T(t,n,e){return S(l(n,v(e)),t,!0)}function $(t,n,e,o,s,r){return S(f(n,e,o=Math.max(o>10?o-4:o-1,1),s=Math.max(s>10?s-4:s-1,1),v(r)),t)}function E(t,n){return S(new c(P).fillPolygon(t,v(n)),null)}function L(t,n,e,o,s){const r=p(e,o,v(s)),i=[];let a=0;for(;a<=2*Math.PI;)i.push([t+r.rx*Math.cos(a),n+r.ry*Math.sin(a)]),a+=r.increment;return E(i,s)}export{$ as ellipse,L as hachureEllipseFill,E as hachureFill,O as line,T as polygon,k as rectangle,I as svgNode};