-
Notifications
You must be signed in to change notification settings - Fork 1
/
pathfit.min.js
1 lines (1 loc) · 14.1 KB
/
pathfit.min.js
1
var Pathfit=function(){"use strict";class t{constructor(t,e){this._str=e,this._pos=0,this.string=t+e,this.offset=t.length}get more(){return this._pos<this._str.length}get position(){return this._pos}get_token(e,r){const s=this._str.substr(this._pos).match(t.regex[e]),i=(s||[""])[0];return this._pos+=i.length,r?null!==s:i}}t.regex={wsp:/^[\x09\x20\x0D\x0A]*/,comma:/^,/,brace_open:/^\(/,brace_close:/^\)/,flag:/^[01]/,number:/^[+-]?(\d*\.\d+|\d+\.?)([eE][+-]?\d+)*/,nonnegative:/^(\d*\.\d+|\d+\.?)([eE][+-]?\d+)*/};var e=t;class r extends Error{constructor(t,e,r){super(),this.name="ParseError",this.message=t+"\n",this.message+=e.string||e,r&&(this.message+="\n"+Array(r).fill("_").join("")+"^")}}var s=r;var i=class{constructor(){this.current=[],this.source=""}get_raw(t,r){return new e(t,r)}throw_parse_error(t,e,r){throw new s(t,e,r)}commands(t){const e=t.split(this.command_names),r=e.shift();return/[^\x09\x20\x0D\x0A]+/.test(r)&&this.throw_parse_error("expected nothing before command",r+e[0],0),e}coordinate(t){return{coordinate:this.number(t)}}coordinate_pair_sequence(t,e){const r={};let s=1;for(;s<e;)r["control_"+s]=this.coordinate_pair(t),this.comma_wsp(t),s++;return r.coordinate_pair=this.coordinate_pair(t),r}elliptical_arc(t){const e={rx:this.number(t,!0)};return this.comma_wsp(t),e.ry=this.number(t,!0),this.comma_wsp(t),e.rotation=this.number(t),this.comma_wsp(t),e.large_arc=this.flag(t),this.comma_wsp(t),e.sweep=this.flag(t),this.comma_wsp(t),e.coordinate_pair=this.coordinate_pair(t),e}coordinate_pair(t){const e={x:this.number(t)};return this.comma_wsp(t),e.y=this.number(t),e}coordinate_triple(t){const e={x:this.number(t)};return this.comma_wsp(t),e.y=this.number(t),this.comma_wsp(t),e.z=this.number(t),e}flag(t){const e=t.get_token("flag");return e||this.throw_parse_error("expected flag",t),"1"===e}number(t,e){const r=t.get_token(e?"nonnegative":"number"),s=parseFloat(r);return isNaN(s)&&this.throw_parse_error("expected number",t),s}comma_wsp(t){t.get_token("wsp");const e=t.get_token("comma",!0);return t.get_token("wsp"),e}test_end(t){t.get_token("wsp"),t.more&&this.throw_parse_error("expected nothing after close",t)}parse(t){return this.current=[],this.source=t,this.group(t)}};const a=/([mzlhvcsqta])/i,o=/m/i;var n=class extends i{get command_names(){return a}collect_arguments(t,e,r){const s=[];let i=!0;for(;i||e.more;)s.length&&(i=this.comma_wsp(e)),(i||e.more)&&s.push(this[t](e,r));return s}group(t){const e=this.commands(t);for(e.length&&!e[0].match(o)&&this.throw_parse_error("expected moveto at start",e.slice(0,2).join(""),0);e.length>1;){const t=e.shift(),r={command:t.toUpperCase()};"Z"!==r.command&&(r.relative=t!==t.toUpperCase());const s=this.get_raw(t,e.shift());switch(s.get_token("wsp"),r.command){case"M":case"L":case"T":r.sequence=this.collect_arguments("coordinate_pair_sequence",s,1);break;case"S":case"Q":r.sequence=this.collect_arguments("coordinate_pair_sequence",s,2);break;case"C":r.sequence=this.collect_arguments("coordinate_pair_sequence",s,3);break;case"H":case"V":r.sequence=this.collect_arguments("coordinate",s);break;case"A":r.sequence=this.collect_arguments("elliptical_arc",s);break;case"Z":this.test_end(s)}this.current.push(r)}return this.current}};const c=/(matrix|translate|scale|rotate|skewX|skewY)/i,h={matrix:{args:["a","b","c","d","e","f"],required:6},translate:{args:["tx","ty"],required:1},scale:{args:["sx","sy"],required:1},rotate:{args:["angle","cx","cy"],required:1},skewX:{args:["angle"],required:1},skewY:{args:["angle"],required:1}};var p=class extends i{get command_names(){return c}collect_arguments(t,e,r){t.get_token("wsp"),t.get_token("brace_open",!0)||this.throw_parse_error("expected opening brace",t),t.get_token("wsp");const s={};e.some(e=>{s[e]=this.number(t);const r=this.comma_wsp(t);return t.get_token("brace_close",!0)&&!r})||this.throw_parse_error("expected closing brace",t);const i=Object.keys(s).length;return i!==r&&i!==e.length&&this.throw_parse_error("wrong number of arguments",t),this.test_end(t),s}group(t){const e=this.commands(t,c);for(;e.length>1;){const t=e.shift(),r=this.get_raw(t,e.shift()),{args:s,required:i}=h[t],a=this.collect_arguments(r,s,i);a.command=t,this.current.push(a)}return this.current}parse(t){return Array.isArray(t)&&(t=t.join(" ")),super.parse(t)}};class m{constructor(t){this.normal_abs=[],this.normal_rel=[],this.transformation=[{command:"scale",sx:1}],Array.isArray(t)&&t.length>0&&(this.transformation=t),this.preprocess()}preprocess(){this.transformation.forEach((function(t){const e={...t},r={...t};switch(t.command){case"matrix":r.e=r.f=0;break;case"translate":r.tx=r.ty=0,e.ty=t.ty||0;break;case"scale":e.sy=r.sy=null!=t.sy?t.sy:t.sx;break;case"rotate":r.cx=r.cy=0,e.cx=t.cx||0,e.cy=t.cy||0}this.normal_abs.push(e),this.normal_rel.push(r)}),this)}static round(t){return Math.abs(Math.round(t)-t)<1e-10?Math.round(t)+0:t}static coordinate_pair(t,e){const r={x:0,y:0,...e};return t.concat([]).reverse().forEach(t=>{switch(t.command){case"matrix":var e=r.x,s=r.y;r.x=t.a*e+t.c*s+t.e,r.y=t.b*e+t.d*s+t.f;break;case"translate":r.x+=t.tx,r.y+=t.ty;break;case"scale":r.x*=t.sx,r.y*=t.sy;break;case"rotate":r.x-=t.cx,r.y-=t.cy;var i=Math.sqrt(r.x*r.x+r.y*r.y),a=180*Math.atan2(r.y,r.x)/Math.PI+t.angle;r.x=i*Math.cos(a*Math.PI/180),r.y=i*Math.sin(a*Math.PI/180),r.x+=t.cx,r.y+=t.cy;break;case"skewX":r.x+=Math.tan(t.angle/180*Math.PI)*r.y;break;case"skewY":r.y+=Math.tan(t.angle/180*Math.PI)*r.x}}),r.x=m.round(r.x),r.y=m.round(r.y),r}static arc_matrix(t,e){const r=Math.cos(e.rotation/180*Math.PI),s=Math.sin(e.rotation/180*Math.PI),i=[e.rx*(t.a*r+t.c*s),e.rx*(t.b*r+t.d*s),e.ry*(t.c*r-t.a*s),e.ry*(t.d*r-t.b*s)],a=i[0]*i[0]+i[2]*i[2],o=2*(i[0]*i[1]+i[2]*i[3]),n=i[1]*i[1]+i[3]*i[3],c=Math.sqrt((a-n)*(a-n)+o*o);return{rx:m.round(Math.sqrt(.5*(a+n+c))),ry:m.round(Math.sqrt(.5*Math.max(0,a+n-c))),rotation:m.round(90*Math.atan2(o,a-n)/Math.PI)}}static elliptical_arc(t,e){return t.concat([]).reverse().forEach(t=>{let r;switch(t.command){case"translate":r=[{command:"rotate",angle:e.rotation,cx:0,cy:0}];break;case"rotate":r=[{command:"rotate",angle:t.angle+e.rotation,cx:0,cy:0}];break;case"matrix":r=[{...t,e:0,f:0},{command:"rotate",angle:e.rotation,cx:0,cy:0}];break;default:r=[t,{command:"rotate",angle:e.rotation,cx:0,cy:0}]}const s=m.coordinate_pair(r,{x:e.rx,y:0}),i=m.coordinate_pair(r,{x:0,y:e.ry}),a={command:"matrix",a:s.x/e.rx,b:s.y/e.rx,c:i.x/e.ry,d:i.y/e.ry,e:0,f:0};e.rotation=0,({rx:e.rx,ry:e.ry,rotation:e.rotation}=m.arc_matrix(a,{...e})),a.a*a.d-a.b*a.c<0&&(e.sweep=!e.sweep)}),e.coordinate_pair=m.coordinate_pair(t,e.coordinate_pair),e}nest_transforms(t,e,r){const s={...e};return("arc"===t?m.elliptical_arc:m.coordinate_pair)(r?this.normal_rel:this.normal_abs,s)}argument_obj(t,e,r){let s={};switch(t){case"A":s=this.nest_transforms("arc",r,e);break;case"C":s.control_2=this.nest_transforms("pair",r.control_2,e);case"S":case"Q":s.control_1=this.nest_transforms("pair",r.control_1,e);default:s.coordinate_pair=this.nest_transforms("pair",r.coordinate_pair,e)}return s}transform(t){let e,r;return t.map((t,s)=>{let i=t.command;if("Z"===i)return{command:i};let a=t.sequence.map((a,o)=>{let n=i,c=t.relative;switch(i){case"H":a={coordinate_pair:{x:a.coordinate,y:c?0:r}},n="L";break;case"V":a={coordinate_pair:{x:c?0:e,y:a.coordinate}},n="L";break;case"M":0===s&&0===o&&(c=!1)}const h=this.argument_obj(n,c,a);return c?(e+=a.coordinate_pair.x,r+=a.coordinate_pair.y):(e=a.coordinate_pair.x,r=a.coordinate_pair.y),h},this);return"H"!==i&&"V"!==i||(i="L"),{command:i,relative:t.relative,sequence:a}},this)}}var _=m;const l={number:/^(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)*(.+)?/,par:/^(?:(none)|x(Min|Mid|Max)Y(Min|Mid|Max)\s+(meet|slice))$/,fit:/^(fill|contain|cover|none|scale-down)$/,position:/^(?:(left|center|right|top|bottom)|((?:[+-]?\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)*)(px|%))$/};function u(t){const e="number"==typeof t?null:t.match(l.number)[1],r=parseFloat(t);if(r<=0||e&&"px"!==e)throw new s("invalid or unusable length",t);return r}var f={length:u,viewport:function(t,e,r){const i={};if(r){if([i.x,i.y,i.width,i.height]=r.split(/[,\s]+/).map(t=>parseFloat(t)),i.width<=0||i.height<=0)throw new s("invalid viewBox",r)}else{if(!t||!e)throw new s("insufficiant data",null);i.x=0,i.y=0,i.width=u(t),i.height=u(e)}return i},aspect_ratio:function(t){const e=l.par.exec(t);if(!e)throw new s("invalid preserveAspectRatio",t);const r={preserve:!1};return"none"!==e[1]&&(r.preserve=!0,r.x=e[2],r.y=e[3],r.slice="slice"===e[4]),r},object_fit:function(t){const e=l.fit.exec(t);if(!e)throw new s("invalid object-fit",t);return e[1]},object_position:function(t){const e=t.split(/\s+/).map(e=>{const r=l.position.exec(e);if(!r)throw new s("invalid object-position",t);return r[1]?function(t){const e={relative:!0,value:0,reverse:!1};let r;switch(t){case"center":r=32,e.value=50;break;case"left":r=16;break;case"right":r=8,e.reverse=!0;break;case"top":r=4;break;case"bottom":r=2,e.reverse=!0}return{type:r,position:e}}(r[1]):{type:1,position:{value:parseFloat(r[2]),relative:"%"===r[3],reverse:!1}}});if(!e.length||e.length>4)throw new s("wrong number of object-position arguments",t);const r={x:{value:50,relative:!0,reverse:!1},y:{value:50,relative:!0,reverse:!1}};switch(e.length){case 1:6&e[0].type?r.y=e[0].position:r.x=e[0].position;break;case 2:if(56&e[0].type&&39&e[1].type||1&e[0].type&&1&e[1].type)r.x=e[0].position,r.y=e[1].position;else{if(!(38&e[0].type&&57&e[1].type&&(6&e[0].type||24&e[1].type)))throw new s("invalid object-position",t);r.x=e[1].position,r.y=e[0].position}break;case 3:if(24&e[0].type&&1&e[1].type&&38&e[2].type)r.x={...e[1].position,reverse:e[0].position.reverse},r.y=e[2].position;else if(56&e[0].type&&6&e[1].type&&1&e[2].type)r.x=e[0].position,r.y={...e[2].position,reverse:e[1].position.reverse};else if(38&e[0].type&&24&e[1].type&&1&e[2].type)r.x={...e[2].position,reverse:e[1].position.reverse},r.y=e[0].position;else{if(!(6&e[0].type&&1&e[1].type&&56&e[2].type))throw new s("invalid object-position",t);r.x=e[2].position,r.y={...e[1].position,reverse:e[0].position.reverse}}break;case 4:if(24&e[0].type&&1&e[1].type&&6&e[2].type&&1&e[3].type)r.x={...e[1].position,reverse:e[0].position.reverse},r.y={...e[3].position,reverse:e[2].position.reverse};else{if(!(6&e[0].type&&1&e[1].type&&24&e[2].type&&1&e[3].type))throw new s("invalid object-position",t);r.x={...e[3].position,reverse:e[2].position.reverse},r.y={...e[1].position,reverse:e[0].position.reverse}}}return r}};class d{constructor(t,e,r,s,i,a){this.fit={par:{},object:{}},this.set_viewport(t,e,r),this.set_preserveAspectRatio(s||void 0),this.set_object_fit(i||void 0),this.set_object_position(a||void 0)}set_viewport(t,e,r){Object.assign(this,f.viewport(t,e,r))}set_preserveAspectRatio(t="xMidYMid meet"){this.fit.par=f.aspect_ratio(t)}set_object_fit(t="fill"){this.fit.object.fit=f.object_fit(t)}set_object_position(t="50% 50%"){Object.assign(this.fit.object,f.object_position(t))}static optimize_transform(t,e,r,s){const i=[];return 0===r&&0===s||i.push({command:"translate",tx:r,ty:s}),1===t&&1===e||i.push({command:"scale",sx:t,sy:e}),i}transform_from_aspect_ratio(t,e){const r=f.length(t),s=f.length(e);let i=r/this.width,a=s/this.height;this.fit.par.preserve&&(i=a=this.fit.par.slice?Math.max(i,a):Math.min(i,a));let o=-this.x*i+0,n=-this.y*a+0;return"Mid"===this.fit.par.x&&(o+=(r-this.width*i)/2),"Max"===this.fit.par.x&&(o+=r-this.width*i),"Mid"===this.fit.par.y&&(n+=(s-this.height*a)/2),"Max"===this.fit.par.y&&(n+=s-this.height*a),d.optimize_transform(i,a,o,n)}static offset(t,e,r,s){return t.relative?t.reverse?(s-r*e)*(100-t.value)/100:(s-r*e)*t.value/100:t.reverse?s-r*e-t.value:t.value}transform_from_object_fit(t,e){const r=f.length(t),s=f.length(e);let i=r/this.width,a=s/this.height;switch(this.fit.object.fit){case"contain":i=a=Math.min(i,a);break;case"cover":i=a=Math.max(i,a);break;case"none":i=a=1;break;case"scale-down":i=a=Math.min(1,i,a)}let o=d.offset(this.fit.object.x,i,this.width,r),n=d.offset(this.fit.object.y,a,this.height,s);return d.optimize_transform(i,a,o,n)}}var w=d;class x{constructor(t){this.options={precision:6,...t}}flag(t){return t?1:0}number(t){return-Math.log(Math.abs(t))/Math.LN10>this.options.precision+3?0:+t.toPrecision(this.options.precision)}pair(t,e,r){return this.number(t[e])+x.pair_wsp+this.number(t[r])}argument(t,e){const r=[];switch(t){case"C":r.unshift(this.pair(e.control_2,"x","y"));case"S":case"Q":r.unshift(this.pair(e.control_1,"x","y"));case"M":case"L":case"T":r.push(this.pair(e.coordinate_pair,"x","y"));break;case"H":case"V":r.push(this.number(e.coordinate));break;case"A":r.push(this.pair(e,"rx","ry"),this.number(e.rotation),this.flag(e.large_arc),this.flag(e.sweep),this.pair(e.coordinate_pair,"x","y"))}return r.join(x.arg_wsp)}command(t,e){return t+=t?x.wsp:"","Z"===e.command?t+="z":(t+=(e.relative?e.command.toLowerCase():e.command)+x.wsp,t+=e.sequence.map(this.argument.bind(this,e.command)).join(x.arg_wsp)),t}format(t){return t.reduce(this.command.bind(this),"")}}x.wsp="",x.pair_wsp=" ",x.arg_wsp=" ";var y=x;return class{constructor(t,e,r,s,i){t&&this.set_viewbox(t),e&&this.set_object_style(e),this.formatter=new y({precision:6,...i}),r&&this.set_path(r,s)}set_viewbox(t){const{width:e,height:r,viewBox:s,preserveAspectRatio:i}=t;this.scale=new w(e,r,s,i)}set_aspect_ratio(t){if(!this.scale)throw new Error("no reference viewBox is set");this.scale.set_preserveAspectRatio(t)}set_object_style(t){if(!this.scale)throw new Error("no reference viewBox is set");t.objectFit&&this.scale.set_object_fit(t.objectFit),t.objectPosition&&this.scale.set_object_position(t.objectPosition)}set_path(t,e){if(this._ast=(new n).parse(t),e){const t=(new p).parse(e);this._ast=this._transform_ast(t)}return this.formatter.format(this._ast)}_transform_ast(t){if(!this._ast)throw new Error("no path is set");return new _(t).transform(this._ast)}transform(t){const e=(new p).parse(t),r=this._transform_ast(e);return this.formatter.format(r)}scale_with_aspect_ratio(t,e){if(!this.scale)throw new Error("no reference viewBox is set");const r=this.scale.transform_from_aspect_ratio(t,e),s=this._transform_ast(r);return this.formatter.format(s)}scale_with_object_fit(t,e){if(!this.scale)throw new Error("no reference viewBox is set");const r=this.scale.transform_from_object_fit(t,e),s=this._transform_ast(r);return this.formatter.format(s)}toString(){return this.formatter.format(this._ast||[])}}}();