@inottn/miniposter
Advanced tools
Comparing version 0.0.9 to 0.0.10
@@ -1,1 +0,1 @@ | ||
"use strict";var p=require("@inottn/fp-utils"),L=Object.defineProperty,U=Object.defineProperties,H=Object.getOwnPropertyDescriptors,T=Object.getOwnPropertySymbols,q=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable,R=(r,e,t)=>e in r?L(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,b=(r,e)=>{for(var t in e||(e={}))q.call(e,t)&&R(r,t,e[t]);if(T)for(var t of T(e))B.call(e,t)&&R(r,t,e[t]);return r},S=(r,e)=>U(r,H(e));const m=typeof wx=="object",A=typeof my=="object",N=()=>{let r;return m?r=wx:A&&(r=my),r},x=N(),G=r=>{const{fontFamily:e,fontSrc:t}=r,{resolve:o,reject:n,promise:i}=p.withResolvers();return x?x.loadFontFace(S(b({family:e,source:`url('${t}')`},m&&{scopes:["native"]}),{success:o,fail:n})):n("platform sdk not found"),i},J=(r,e)=>{const{resolve:t,reject:o,promise:n}=p.withResolvers();let i;return A?i=r.toTempFilePath:m?i=x.canvasToTempFilePath:o("platform sdk not found"),i&&i(S(b(b({},e),m&&{canvas:r}),{success:t,fail:o})),n};var K=Object.defineProperty,Q=Object.defineProperties,V=Object.getOwnPropertyDescriptors,$=Object.getOwnPropertySymbols,X=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable,M=(r,e,t)=>e in r?K(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,C=(r,e)=>{for(var t in e||(e={}))X.call(e,t)&&M(r,t,e[t]);if($)for(var t of $(e))Y.call(e,t)&&M(r,t,e[t]);return r},Z=(r,e)=>Q(r,V(e));const _=function(r,e){let t=0,o=r.length;for(;t<o;){const n=t+(o-t>>1);e(n)?o=n:t=n+1}return o-1},E=function({left:r,textAlign:e,textWidth:t,width:o}){if(p.isUndefined(o))return r;const n=o-(t||0);switch(e){case"center":return r+n/2;case"right":return r+n;default:return r}},tt=function(r,e){if(p.isUndefined(e))return r;const t=p.isFunction(r.left)?r.left():r.left,o=p.isFunction(r.top)?r.top():r.top;return Z(C({},r),{left:e.left+t,top:e.top+o})},P=function(r){const e=C({},r);return p.isFunction(r.left)&&(e.left=r.left()),p.isFunction(r.top)&&(e.top=r.top()),e};var et=Object.defineProperty,rt=Object.defineProperties,it=Object.getOwnPropertyDescriptors,z=Object.getOwnPropertySymbols,ot=Object.prototype.hasOwnProperty,nt=Object.prototype.propertyIsEnumerable,k=(r,e,t)=>e in r?et(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e)=>{for(var t in e||(e={}))ot.call(e,t)&&k(r,t,e[t]);if(z)for(var t of z(e))nt.call(e,t)&&k(r,t,e[t]);return r},st=(r,e)=>rt(r,it(e));class at{constructor(e,t){this.images=new Map,this.fonts=new Map,this.sizes=new Map,this.canvas=e,this.context=e.getContext("2d"),this.options=t}async render(e){const{canvas:t,context:o,options:n}=this,{width:i,height:a,pixelRatio:s=1}=v(v({},n),e);if(!i||!a)throw Error("\u7F3A\u5C11 width \u6216 height \u53C2\u6570");t.width=i*s,t.height=a*s,o.scale(s,s),await this.renderContainer(st(v({type:"container"},e),{left:0,top:0,width:i,height:a}))}async draw(e){if(Array.isArray(e))for(const t of e)await this.draw(t);else e.type==="container"&&await this.renderContainer(P(e)),e.type==="image"&&await this.renderImage(P(e)),e.type==="text"&&await this.renderText(P(e))}async renderContainer(e){const{context:t}=this,{left:o,top:n,width:i,height:a,backgroundColor:s,borderRadius:c=0,overflow:l,children:h}=e;if(t.save(),this.drawRoundedRect(o,n,i,a,c),t.clip(),s&&(t.fillStyle=s,t.fillRect(o,n,i,a)),l!=="hidden"&&t.restore(),p.isNonEmptyArray(h)){this.loadAssets(h);for(const f of h){const d=tt(f,{left:o,top:n});await this.draw(d)}}l==="hidden"&&t.restore()}async renderImage(e){const{context:t}=this,{src:o,backgroundColor:n,borderRadius:i=0,objectFit:a="fill"}=e,[s,c]=this.images.get(o);let{left:l,top:h,width:f,height:d}=e;await c,t.save(),this.drawRoundedRect(l,h,f,d,i),t.clip(),n&&(t.fillStyle=n,t.fillRect(l,h,f,d));const g=s.width/s.height,u=f/d;if(!(a==="fill"||g===u)&&(a==="contain"||a==="cover"))if(a==="contain"?g>u:g<u){const w=s.width/f,y=d;d=s.height/w,h+=(y-d)*.5}else{const w=s.height/d,y=f;f=s.width/w,l+=(y-f)*.5}t.drawImage(s,l,h,f,d),t.restore()}async renderText(e){const{context:t}=this,{id:o,content:n,left:i,top:a,width:s,fontSize:c=14,lineHeight:l=c*1.43,color:h="#333",fontFamily:f="sans-serif",fontWeight:d=400,fontSrc:g,textAlign:u="left",textDecoration:w}=e;g&&await this.fonts.get(g),t.save(),s&&(t.textAlign=u),t.textBaseline="alphabetic",t.fillStyle=h,t.font=`${d} ${c}px ${f}`;const y=E({left:i,textAlign:u,width:s}),O=s?this.getAllLines(e):[n];O.forEach((j,D)=>{const F=a+(l-c)/2+l*D;if(t.fillText(j,y,F+c),w==="line-through"){const{width:I}=t.measureText(j),W=E({left:i,textAlign:u,textWidth:I,width:s});t.fillRect(W,F+c*.64,I,c/14)}}),o&&this.sizes.set(o,{width:s||t.measureText(n).width,height:l*O.length}),t.restore()}getAllLines(e){const{context:t}=this,{width:o,content:n,lineClamp:i=1/0}=e,a=[];let s=0;for(;s<n.length&&a.length<i;){const c=s;s=_(n,l=>t.measureText(n.slice(s,l+1)).width>o)+1,s===c&&(s=c+1),i===a.length+1?a.push(n.slice(c,s-1)+"..."):a.push(n.slice(c,s))}return a}getSize(e){return this.sizes.get(e)}drawRoundedRect(e,t,o,n,i){const{context:a}=this;typeof i=="number"?i=[i,i,i,i]:i.length===1?i=[i[0],i[0],i[0],i[0]]:i.length===2?i=[i[0],i[1],i[0],i[1]]:i.length===3&&(i=[i[0],i[1],i[2],i[1]]);const[s,c,l,h]=i.map(f=>Math.min(f,o/2,n/2));a.save(),a.translate(e,t),a.beginPath(),a.moveTo(s,0),a.lineTo(o-c,0),a.arc(o-c,c,c,Math.PI*3/2,0,!1),a.lineTo(o,n-l),a.arc(o-l,n-l,l,0,Math.PI/2,!1),a.lineTo(h,n),a.arc(h,n-h,h,Math.PI/2,Math.PI,!1),a.lineTo(0,s),a.arc(s,s,s,Math.PI,Math.PI*3/2,!1),a.closePath(),a.restore()}loadAssets(e){e.forEach(t=>{const{type:o}=t;o==="image"&&this.loadImage(t),o==="text"&&t.fontFamily&&t.fontSrc&&this.loadFont(t)})}loadImage(e){const{src:t}=e;if(!this.images.has(t)){const o=this.canvas.createImage();o.src=t,this.images.set(t,[o,new Promise((n,i)=>{o.onload=n,o.onerror=i})])}}loadFont(e){const{fontFamily:t,fontSrc:o}=e;this.fonts.has(o)||this.fonts.set(o,G({fontFamily:t,fontSrc:o}))}export(e){const{canvas:t}=this;return J(t,v({x:0,y:0,width:t.width,height:t.height,destWidth:t.width,destHeight:t.height},e))}}exports.MiniPoster=at; | ||
"use strict";var p=require("@inottn/fp-utils"),L=Object.defineProperty,U=Object.defineProperties,H=Object.getOwnPropertyDescriptors,T=Object.getOwnPropertySymbols,q=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable,R=(r,e,t)=>e in r?L(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,b=(r,e)=>{for(var t in e||(e={}))q.call(e,t)&&R(r,t,e[t]);if(T)for(var t of T(e))B.call(e,t)&&R(r,t,e[t]);return r},S=(r,e)=>U(r,H(e));const m=typeof wx=="object",A=typeof my=="object",N=()=>{let r;return m?r=wx:A&&(r=my),r},x=N(),G=r=>{const{fontFamily:e,fontSrc:t}=r,{resolve:o,reject:n,promise:i}=p.withResolvers();return x?x.loadFontFace(S(b({family:e,source:`url('${t}')`},m&&{scopes:["native"]}),{success:o,fail:n})):n("platform sdk not found"),i},J=(r,e)=>{const{resolve:t,reject:o,promise:n}=p.withResolvers();let i;return A?i=r.toTempFilePath:m?i=x.canvasToTempFilePath:o("platform sdk not found"),i&&i(S(b(b({},e),m&&{canvas:r}),{success:t,fail:o})),n};var K=Object.defineProperty,Q=Object.defineProperties,V=Object.getOwnPropertyDescriptors,$=Object.getOwnPropertySymbols,X=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable,M=(r,e,t)=>e in r?K(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,C=(r,e)=>{for(var t in e||(e={}))X.call(e,t)&&M(r,t,e[t]);if($)for(var t of $(e))Y.call(e,t)&&M(r,t,e[t]);return r},Z=(r,e)=>Q(r,V(e));const _=function(r,e){let t=0,o=r.length;for(;t<o;){const n=t+(o-t>>1);e(n)?o=n:t=n+1}return o-1},E=function({left:r,textAlign:e,textWidth:t,width:o}){if(p.isUndefined(o))return r;const n=o-(t||0);switch(e){case"center":return r+n/2;case"right":return r+n;default:return r}},tt=function(r,e){if(p.isUndefined(e))return r;const t=p.isFunction(r.left)?r.left():r.left,o=p.isFunction(r.top)?r.top():r.top;return Z(C({},r),{left:e.left+t,top:e.top+o})},P=function(r){const e=C({},r);return p.isFunction(r.left)&&(e.left=r.left()),p.isFunction(r.top)&&(e.top=r.top()),e};var et=Object.defineProperty,rt=Object.defineProperties,it=Object.getOwnPropertyDescriptors,z=Object.getOwnPropertySymbols,ot=Object.prototype.hasOwnProperty,nt=Object.prototype.propertyIsEnumerable,k=(r,e,t)=>e in r?et(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e)=>{for(var t in e||(e={}))ot.call(e,t)&&k(r,t,e[t]);if(z)for(var t of z(e))nt.call(e,t)&&k(r,t,e[t]);return r},st=(r,e)=>rt(r,it(e));class at{constructor(e,t){this.images=new Map,this.fonts=new Map,this.sizes=new Map,this.canvas=e,this.context=e.getContext("2d"),this.options=t}async render(e){const{canvas:t,context:o,options:n}=this,{width:i,height:a,pixelRatio:s=1}=v(v({},n),e);if(!i||!a)throw Error("\u7F3A\u5C11 width \u6216 height \u53C2\u6570");t.width=i*s,t.height=a*s,o.scale(s,s),await this.renderContainer(st(v({type:"container"},e),{left:0,top:0,width:i,height:a}))}async draw(e){try{if(Array.isArray(e))for(const t of e)await this.draw(t);else e.type==="container"&&await this.renderContainer(P(e)),e.type==="image"&&await this.renderImage(P(e)),e.type==="text"&&await this.renderText(P(e))}catch(t){}}async renderContainer(e){const{context:t}=this,{left:o,top:n,width:i,height:a,backgroundColor:s,borderRadius:c=0,overflow:l,children:h}=e;if(t.save(),this.drawRoundedRect(o,n,i,a,c),t.clip(),s&&(t.fillStyle=s,t.fillRect(o,n,i,a)),l!=="hidden"&&t.restore(),p.isNonEmptyArray(h)){this.loadAssets(h);for(const f of h){const d=tt(f,{left:o,top:n});await this.draw(d)}}l==="hidden"&&t.restore()}async renderImage(e){const{context:t}=this,{src:o,backgroundColor:n,borderRadius:i=0,objectFit:a="fill"}=e,[s,c]=this.images.get(o);let{left:l,top:h,width:f,height:d}=e;await c,t.save(),this.drawRoundedRect(l,h,f,d,i),t.clip(),n&&(t.fillStyle=n,t.fillRect(l,h,f,d));const g=s.width/s.height,u=f/d;if(!(a==="fill"||g===u)&&(a==="contain"||a==="cover"))if(a==="contain"?g>u:g<u){const w=s.width/f,y=d;d=s.height/w,h+=(y-d)*.5}else{const w=s.height/d,y=f;f=s.width/w,l+=(y-f)*.5}t.drawImage(s,l,h,f,d),t.restore()}async renderText(e){const{context:t}=this,{id:o,content:n,left:i,top:a,width:s,fontSize:c=14,lineHeight:l=c*1.43,color:h="#333",fontFamily:f="sans-serif",fontWeight:d=400,fontSrc:g,textAlign:u="left",textDecoration:w}=e;g&&await this.fonts.get(g),t.save(),s&&(t.textAlign=u),t.textBaseline="alphabetic",t.fillStyle=h,t.font=`${d} ${c}px ${f}`;const y=E({left:i,textAlign:u,width:s}),O=s?this.getAllLines(e):[n];O.forEach((j,D)=>{const F=a+(l-c)/2+l*D;if(t.fillText(j,y,F+c),w==="line-through"){const{width:I}=t.measureText(j),W=E({left:i,textAlign:u,textWidth:I,width:s});t.fillRect(W,F+c*.64,I,c/14)}}),o&&this.sizes.set(o,{width:s||t.measureText(n).width,height:l*O.length}),t.restore()}getAllLines(e){const{context:t}=this,{width:o,content:n,lineClamp:i=1/0}=e,a=[];let s=0;for(;s<n.length&&a.length<i;){const c=s;s=_(n,l=>t.measureText(n.slice(s,l+1)).width>o)+1,s===c&&(s=c+1),i===a.length+1?a.push(n.slice(c,s-1)+"..."):a.push(n.slice(c,s))}return a}getSize(e){return this.sizes.get(e)}drawRoundedRect(e,t,o,n,i){const{context:a}=this;typeof i=="number"?i=[i,i,i,i]:i.length===1?i=[i[0],i[0],i[0],i[0]]:i.length===2?i=[i[0],i[1],i[0],i[1]]:i.length===3&&(i=[i[0],i[1],i[2],i[1]]);const[s,c,l,h]=i.map(f=>Math.min(f,o/2,n/2));a.save(),a.translate(e,t),a.beginPath(),a.moveTo(s,0),a.lineTo(o-c,0),a.arc(o-c,c,c,Math.PI*3/2,0,!1),a.lineTo(o,n-l),a.arc(o-l,n-l,l,0,Math.PI/2,!1),a.lineTo(h,n),a.arc(h,n-h,h,Math.PI/2,Math.PI,!1),a.lineTo(0,s),a.arc(s,s,s,Math.PI,Math.PI*3/2,!1),a.closePath(),a.restore()}loadAssets(e){e.forEach(t=>{const{type:o}=t;o==="image"&&this.loadImage(t),o==="text"&&t.fontFamily&&t.fontSrc&&this.loadFont(t)})}loadImage(e){const{src:t}=e;if(!this.images.has(t)){const o=this.canvas.createImage();o.src=t,this.images.set(t,[o,new Promise((n,i)=>{o.onload=n,o.onerror=i})])}}loadFont(e){const{fontFamily:t,fontSrc:o}=e;this.fonts.has(o)||this.fonts.set(o,G({fontFamily:t,fontSrc:o}))}export(e){const{canvas:t}=this;return J(t,v({x:0,y:0,width:t.width,height:t.height,destWidth:t.width,destHeight:t.height},e))}}exports.MiniPoster=at; |
@@ -1,1 +0,1 @@ | ||
import{withResolvers as T,isUndefined as S,isFunction as y,isNonEmptyArray as B}from"@inottn/fp-utils";var N=Object.defineProperty,U=Object.defineProperties,q=Object.getOwnPropertyDescriptors,A=Object.getOwnPropertySymbols,G=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable,R=(r,e,t)=>e in r?N(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e)=>{for(var t in e||(e={}))G.call(e,t)&&R(r,t,e[t]);if(A)for(var t of A(e))J.call(e,t)&&R(r,t,e[t]);return r},$=(r,e)=>U(r,q(e));const m=typeof wx=="object",M=typeof my=="object",K=()=>{let r;return m?r=wx:M&&(r=my),r},x=K(),Q=r=>{const{fontFamily:e,fontSrc:t}=r,{resolve:i,reject:n,promise:o}=T();return x?x.loadFontFace($(v({family:e,source:`url('${t}')`},m&&{scopes:["native"]}),{success:i,fail:n})):n("platform sdk not found"),o},V=(r,e)=>{const{resolve:t,reject:i,promise:n}=T();let o;return M?o=r.toTempFilePath:m?o=x.canvasToTempFilePath:i("platform sdk not found"),o&&o($(v(v({},e),m&&{canvas:r}),{success:t,fail:i})),n};var X=Object.defineProperty,Y=Object.defineProperties,Z=Object.getOwnPropertyDescriptors,C=Object.getOwnPropertySymbols,_=Object.prototype.hasOwnProperty,tt=Object.prototype.propertyIsEnumerable,E=(r,e,t)=>e in r?X(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,z=(r,e)=>{for(var t in e||(e={}))_.call(e,t)&&E(r,t,e[t]);if(C)for(var t of C(e))tt.call(e,t)&&E(r,t,e[t]);return r},et=(r,e)=>Y(r,Z(e));const rt=function(r,e){let t=0,i=r.length;for(;t<i;){const n=t+(i-t>>1);e(n)?i=n:t=n+1}return i-1},k=function({left:r,textAlign:e,textWidth:t,width:i}){if(S(i))return r;const n=i-(t||0);switch(e){case"center":return r+n/2;case"right":return r+n;default:return r}},ot=function(r,e){if(S(e))return r;const t=y(r.left)?r.left():r.left,i=y(r.top)?r.top():r.top;return et(z({},r),{left:e.left+t,top:e.top+i})},O=function(r){const e=z({},r);return y(r.left)&&(e.left=r.left()),y(r.top)&&(e.top=r.top()),e};var it=Object.defineProperty,nt=Object.defineProperties,st=Object.getOwnPropertyDescriptors,D=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty,ct=Object.prototype.propertyIsEnumerable,W=(r,e,t)=>e in r?it(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,b=(r,e)=>{for(var t in e||(e={}))at.call(e,t)&&W(r,t,e[t]);if(D)for(var t of D(e))ct.call(e,t)&&W(r,t,e[t]);return r},lt=(r,e)=>nt(r,st(e));class ht{constructor(e,t){this.images=new Map,this.fonts=new Map,this.sizes=new Map,this.canvas=e,this.context=e.getContext("2d"),this.options=t}async render(e){const{canvas:t,context:i,options:n}=this,{width:o,height:a,pixelRatio:s=1}=b(b({},n),e);if(!o||!a)throw Error("\u7F3A\u5C11 width \u6216 height \u53C2\u6570");t.width=o*s,t.height=a*s,i.scale(s,s),await this.renderContainer(lt(b({type:"container"},e),{left:0,top:0,width:o,height:a}))}async draw(e){if(Array.isArray(e))for(const t of e)await this.draw(t);else e.type==="container"&&await this.renderContainer(O(e)),e.type==="image"&&await this.renderImage(O(e)),e.type==="text"&&await this.renderText(O(e))}async renderContainer(e){const{context:t}=this,{left:i,top:n,width:o,height:a,backgroundColor:s,borderRadius:c=0,overflow:l,children:h}=e;if(t.save(),this.drawRoundedRect(i,n,o,a,c),t.clip(),s&&(t.fillStyle=s,t.fillRect(i,n,o,a)),l!=="hidden"&&t.restore(),B(h)){this.loadAssets(h);for(const f of h){const d=ot(f,{left:i,top:n});await this.draw(d)}}l==="hidden"&&t.restore()}async renderImage(e){const{context:t}=this,{src:i,backgroundColor:n,borderRadius:o=0,objectFit:a="fill"}=e,[s,c]=this.images.get(i);let{left:l,top:h,width:f,height:d}=e;await c,t.save(),this.drawRoundedRect(l,h,f,d,o),t.clip(),n&&(t.fillStyle=n,t.fillRect(l,h,f,d));const u=s.width/s.height,p=f/d;if(!(a==="fill"||u===p)&&(a==="contain"||a==="cover"))if(a==="contain"?u>p:u<p){const g=s.width/f,w=d;d=s.height/g,h+=(w-d)*.5}else{const g=s.height/d,w=f;f=s.width/g,l+=(w-f)*.5}t.drawImage(s,l,h,f,d),t.restore()}async renderText(e){const{context:t}=this,{id:i,content:n,left:o,top:a,width:s,fontSize:c=14,lineHeight:l=c*1.43,color:h="#333",fontFamily:f="sans-serif",fontWeight:d=400,fontSrc:u,textAlign:p="left",textDecoration:g}=e;u&&await this.fonts.get(u),t.save(),s&&(t.textAlign=p),t.textBaseline="alphabetic",t.fillStyle=h,t.font=`${d} ${c}px ${f}`;const w=k({left:o,textAlign:p,width:s}),P=s?this.getAllLines(e):[n];P.forEach((j,L)=>{const F=a+(l-c)/2+l*L;if(t.fillText(j,w,F+c),g==="line-through"){const{width:I}=t.measureText(j),H=k({left:o,textAlign:p,textWidth:I,width:s});t.fillRect(H,F+c*.64,I,c/14)}}),i&&this.sizes.set(i,{width:s||t.measureText(n).width,height:l*P.length}),t.restore()}getAllLines(e){const{context:t}=this,{width:i,content:n,lineClamp:o=1/0}=e,a=[];let s=0;for(;s<n.length&&a.length<o;){const c=s;s=rt(n,l=>t.measureText(n.slice(s,l+1)).width>i)+1,s===c&&(s=c+1),o===a.length+1?a.push(n.slice(c,s-1)+"..."):a.push(n.slice(c,s))}return a}getSize(e){return this.sizes.get(e)}drawRoundedRect(e,t,i,n,o){const{context:a}=this;typeof o=="number"?o=[o,o,o,o]:o.length===1?o=[o[0],o[0],o[0],o[0]]:o.length===2?o=[o[0],o[1],o[0],o[1]]:o.length===3&&(o=[o[0],o[1],o[2],o[1]]);const[s,c,l,h]=o.map(f=>Math.min(f,i/2,n/2));a.save(),a.translate(e,t),a.beginPath(),a.moveTo(s,0),a.lineTo(i-c,0),a.arc(i-c,c,c,Math.PI*3/2,0,!1),a.lineTo(i,n-l),a.arc(i-l,n-l,l,0,Math.PI/2,!1),a.lineTo(h,n),a.arc(h,n-h,h,Math.PI/2,Math.PI,!1),a.lineTo(0,s),a.arc(s,s,s,Math.PI,Math.PI*3/2,!1),a.closePath(),a.restore()}loadAssets(e){e.forEach(t=>{const{type:i}=t;i==="image"&&this.loadImage(t),i==="text"&&t.fontFamily&&t.fontSrc&&this.loadFont(t)})}loadImage(e){const{src:t}=e;if(!this.images.has(t)){const i=this.canvas.createImage();i.src=t,this.images.set(t,[i,new Promise((n,o)=>{i.onload=n,i.onerror=o})])}}loadFont(e){const{fontFamily:t,fontSrc:i}=e;this.fonts.has(i)||this.fonts.set(i,Q({fontFamily:t,fontSrc:i}))}export(e){const{canvas:t}=this;return V(t,b({x:0,y:0,width:t.width,height:t.height,destWidth:t.width,destHeight:t.height},e))}}export{ht as MiniPoster}; | ||
import{withResolvers as T,isUndefined as S,isFunction as y,isNonEmptyArray as B}from"@inottn/fp-utils";var N=Object.defineProperty,U=Object.defineProperties,q=Object.getOwnPropertyDescriptors,A=Object.getOwnPropertySymbols,G=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable,R=(r,e,t)=>e in r?N(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,v=(r,e)=>{for(var t in e||(e={}))G.call(e,t)&&R(r,t,e[t]);if(A)for(var t of A(e))J.call(e,t)&&R(r,t,e[t]);return r},$=(r,e)=>U(r,q(e));const m=typeof wx=="object",M=typeof my=="object",K=()=>{let r;return m?r=wx:M&&(r=my),r},x=K(),Q=r=>{const{fontFamily:e,fontSrc:t}=r,{resolve:i,reject:n,promise:o}=T();return x?x.loadFontFace($(v({family:e,source:`url('${t}')`},m&&{scopes:["native"]}),{success:i,fail:n})):n("platform sdk not found"),o},V=(r,e)=>{const{resolve:t,reject:i,promise:n}=T();let o;return M?o=r.toTempFilePath:m?o=x.canvasToTempFilePath:i("platform sdk not found"),o&&o($(v(v({},e),m&&{canvas:r}),{success:t,fail:i})),n};var X=Object.defineProperty,Y=Object.defineProperties,Z=Object.getOwnPropertyDescriptors,C=Object.getOwnPropertySymbols,_=Object.prototype.hasOwnProperty,tt=Object.prototype.propertyIsEnumerable,E=(r,e,t)=>e in r?X(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,z=(r,e)=>{for(var t in e||(e={}))_.call(e,t)&&E(r,t,e[t]);if(C)for(var t of C(e))tt.call(e,t)&&E(r,t,e[t]);return r},et=(r,e)=>Y(r,Z(e));const rt=function(r,e){let t=0,i=r.length;for(;t<i;){const n=t+(i-t>>1);e(n)?i=n:t=n+1}return i-1},k=function({left:r,textAlign:e,textWidth:t,width:i}){if(S(i))return r;const n=i-(t||0);switch(e){case"center":return r+n/2;case"right":return r+n;default:return r}},ot=function(r,e){if(S(e))return r;const t=y(r.left)?r.left():r.left,i=y(r.top)?r.top():r.top;return et(z({},r),{left:e.left+t,top:e.top+i})},O=function(r){const e=z({},r);return y(r.left)&&(e.left=r.left()),y(r.top)&&(e.top=r.top()),e};var it=Object.defineProperty,nt=Object.defineProperties,st=Object.getOwnPropertyDescriptors,D=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty,ct=Object.prototype.propertyIsEnumerable,W=(r,e,t)=>e in r?it(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,b=(r,e)=>{for(var t in e||(e={}))at.call(e,t)&&W(r,t,e[t]);if(D)for(var t of D(e))ct.call(e,t)&&W(r,t,e[t]);return r},lt=(r,e)=>nt(r,st(e));class ht{constructor(e,t){this.images=new Map,this.fonts=new Map,this.sizes=new Map,this.canvas=e,this.context=e.getContext("2d"),this.options=t}async render(e){const{canvas:t,context:i,options:n}=this,{width:o,height:a,pixelRatio:s=1}=b(b({},n),e);if(!o||!a)throw Error("\u7F3A\u5C11 width \u6216 height \u53C2\u6570");t.width=o*s,t.height=a*s,i.scale(s,s),await this.renderContainer(lt(b({type:"container"},e),{left:0,top:0,width:o,height:a}))}async draw(e){try{if(Array.isArray(e))for(const t of e)await this.draw(t);else e.type==="container"&&await this.renderContainer(O(e)),e.type==="image"&&await this.renderImage(O(e)),e.type==="text"&&await this.renderText(O(e))}catch(t){}}async renderContainer(e){const{context:t}=this,{left:i,top:n,width:o,height:a,backgroundColor:s,borderRadius:c=0,overflow:l,children:h}=e;if(t.save(),this.drawRoundedRect(i,n,o,a,c),t.clip(),s&&(t.fillStyle=s,t.fillRect(i,n,o,a)),l!=="hidden"&&t.restore(),B(h)){this.loadAssets(h);for(const f of h){const d=ot(f,{left:i,top:n});await this.draw(d)}}l==="hidden"&&t.restore()}async renderImage(e){const{context:t}=this,{src:i,backgroundColor:n,borderRadius:o=0,objectFit:a="fill"}=e,[s,c]=this.images.get(i);let{left:l,top:h,width:f,height:d}=e;await c,t.save(),this.drawRoundedRect(l,h,f,d,o),t.clip(),n&&(t.fillStyle=n,t.fillRect(l,h,f,d));const u=s.width/s.height,p=f/d;if(!(a==="fill"||u===p)&&(a==="contain"||a==="cover"))if(a==="contain"?u>p:u<p){const g=s.width/f,w=d;d=s.height/g,h+=(w-d)*.5}else{const g=s.height/d,w=f;f=s.width/g,l+=(w-f)*.5}t.drawImage(s,l,h,f,d),t.restore()}async renderText(e){const{context:t}=this,{id:i,content:n,left:o,top:a,width:s,fontSize:c=14,lineHeight:l=c*1.43,color:h="#333",fontFamily:f="sans-serif",fontWeight:d=400,fontSrc:u,textAlign:p="left",textDecoration:g}=e;u&&await this.fonts.get(u),t.save(),s&&(t.textAlign=p),t.textBaseline="alphabetic",t.fillStyle=h,t.font=`${d} ${c}px ${f}`;const w=k({left:o,textAlign:p,width:s}),P=s?this.getAllLines(e):[n];P.forEach((j,L)=>{const F=a+(l-c)/2+l*L;if(t.fillText(j,w,F+c),g==="line-through"){const{width:I}=t.measureText(j),H=k({left:o,textAlign:p,textWidth:I,width:s});t.fillRect(H,F+c*.64,I,c/14)}}),i&&this.sizes.set(i,{width:s||t.measureText(n).width,height:l*P.length}),t.restore()}getAllLines(e){const{context:t}=this,{width:i,content:n,lineClamp:o=1/0}=e,a=[];let s=0;for(;s<n.length&&a.length<o;){const c=s;s=rt(n,l=>t.measureText(n.slice(s,l+1)).width>i)+1,s===c&&(s=c+1),o===a.length+1?a.push(n.slice(c,s-1)+"..."):a.push(n.slice(c,s))}return a}getSize(e){return this.sizes.get(e)}drawRoundedRect(e,t,i,n,o){const{context:a}=this;typeof o=="number"?o=[o,o,o,o]:o.length===1?o=[o[0],o[0],o[0],o[0]]:o.length===2?o=[o[0],o[1],o[0],o[1]]:o.length===3&&(o=[o[0],o[1],o[2],o[1]]);const[s,c,l,h]=o.map(f=>Math.min(f,i/2,n/2));a.save(),a.translate(e,t),a.beginPath(),a.moveTo(s,0),a.lineTo(i-c,0),a.arc(i-c,c,c,Math.PI*3/2,0,!1),a.lineTo(i,n-l),a.arc(i-l,n-l,l,0,Math.PI/2,!1),a.lineTo(h,n),a.arc(h,n-h,h,Math.PI/2,Math.PI,!1),a.lineTo(0,s),a.arc(s,s,s,Math.PI,Math.PI*3/2,!1),a.closePath(),a.restore()}loadAssets(e){e.forEach(t=>{const{type:i}=t;i==="image"&&this.loadImage(t),i==="text"&&t.fontFamily&&t.fontSrc&&this.loadFont(t)})}loadImage(e){const{src:t}=e;if(!this.images.has(t)){const i=this.canvas.createImage();i.src=t,this.images.set(t,[i,new Promise((n,o)=>{i.onload=n,i.onerror=o})])}}loadFont(e){const{fontFamily:t,fontSrc:i}=e;this.fonts.has(i)||this.fonts.set(i,Q({fontFamily:t,fontSrc:i}))}export(e){const{canvas:t}=this;return V(t,b({x:0,y:0,width:t.width,height:t.height,destWidth:t.width,destHeight:t.height},e))}}export{ht as MiniPoster}; |
{ | ||
"name": "@inottn/miniposter", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"packageManager": "pnpm@8.7.0", | ||
@@ -25,8 +25,4 @@ "description": "使用 canvas 轻松绘制小程序海报,支持 微信 / 支付宝小程序", | ||
"build": "rimraf dist && rollup -c", | ||
"test": "vitest", | ||
"test:coverage": "vitest --coverage", | ||
"lint": "eslint ./src --ext .js,.ts,.mjs,.cjs", | ||
"lint:tsc": "tsc --noEmit --skipLibCheck", | ||
"docs:dev": "pnpm -C docs run dev", | ||
"docs:build": "pnpm -C docs run build", | ||
"prepare": "husky install" | ||
@@ -59,20 +55,18 @@ }, | ||
"devDependencies": { | ||
"@typescript-eslint/eslint-plugin": "^6.7.2", | ||
"@typescript-eslint/parser": "^6.7.2", | ||
"@vitest/coverage-v8": "^0.34.5", | ||
"eslint": "^8.50.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"@typescript-eslint/eslint-plugin": "^6.16.0", | ||
"@typescript-eslint/parser": "^6.16.0", | ||
"eslint": "^8.56.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"husky": "^8.0.3", | ||
"nano-staged": "^0.8.0", | ||
"prettier": "^3.0.3", | ||
"rimraf": "^5.0.1", | ||
"rollup": "^3.29.2", | ||
"rollup-plugin-dts": "^6.0.2", | ||
"rollup-plugin-esbuild": "^6.0.1", | ||
"typescript": "^5.2.2", | ||
"vitest": "^0.34.5" | ||
"prettier": "^3.1.1", | ||
"rimraf": "^5.0.5", | ||
"rollup": "^4.9.1", | ||
"rollup-plugin-dts": "^6.1.0", | ||
"rollup-plugin-esbuild": "^6.1.0", | ||
"typescript": "^5.3.3" | ||
}, | ||
"dependencies": { | ||
"@inottn/fp-utils": "^0.4.2" | ||
"@inottn/fp-utils": "^0.4.3" | ||
} | ||
} |
@@ -112,3 +112,3 @@ <p align="center"> | ||
### container | ||
### type: container | ||
@@ -133,3 +133,3 @@ ```js | ||
### image | ||
### type: image | ||
@@ -153,3 +153,3 @@ ```js | ||
### text | ||
### type: text | ||
@@ -182,1 +182,16 @@ ```js | ||
获取指定元素的宽高信息 | ||
## miniposter.export(config) | ||
将当前画布指定区域导出为图片 | ||
| 字段名 | 类型 | 默认值 | 说明 | | ||
| ---------- | -------------- | -------- | --------------------------------------------------------------------------- | | ||
| x | number | 0 | 指定的画布区域的左上角横坐标 | | ||
| y | number | 0 | 指定的画布区域的左上角纵坐标 | | ||
| width | number | 画布宽度 | 指定的画布区域的宽度 | | ||
| height | number | 画布高度 | 指定的画布区域的高度 | | ||
| destWidth | number | 画布宽度 | 输出的图片的宽度 | | ||
| destHeight | number | 画布高度 | 输出的图片的高度 | | ||
| fileType | 'png' \| 'jpg' | 'png' | 目标文件的类型 | | ||
| quality | number | 1 | 图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1 处理。 | |
26209
12
194
Updated@inottn/fp-utils@^0.4.3