From d4a1010204933696ac360ae9745d74df1bbdde1d Mon Sep 17 00:00:00 2001 From: jinfeiyang Date: Thu, 10 Sep 2020 15:48:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=93=8D=E4=BD=9Celement=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/easy-canvas.min.js | 2 +- example/draw.js | 11 +++-------- lib/element.js | 8 ++++---- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/dist/easy-canvas.min.js b/dist/easy-canvas.min.js index c97db9a..518a3ab 100644 --- a/dist/easy-canvas.min.js +++ b/dist/easy-canvas.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).easyCanvas=e()}(this,(function(){"use strict";const t={BLOCK:"block",INLINE_BLOCK:"inline-block",INLINE:"inline",FLEX:"flex",NONE:"none"},e={AUTO:"auto",OUTER:"100%"},i={ROW:"row",COLUMN:"column"};var s={DISPLAY:t,WIDTH:e,POSITION:{ABSOLUTE:"absolute",FIXED:"fixed",RELATIVE:"relative",STATIC:"static"},DEFAULT_STYLES:{display:t.BLOCK,fontSize:14,fontWeight:400,fontFamily:"Microsoft Yahei",color:"#000",paddingTop:0,paddingBottom:0,paddingLeft:0,paddingRight:0,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,height:e.AUTO,borderRadius:0,lineCap:"square",flexDirection:i.ROW,verticalAlign:"middle",textAlign:"left",justifyContent:"flex-start",alignItems:"flex-start",whiteSpace:"normal",zIndex:1,visible:!0},TEXT_ALIGN:{LEFT:"left",RIGHT:"right",CENTER:"center"},FLEX_DIRECTION:i};function n(t){return"number"==typeof t}function r(t){return"auto"===t}function h(t){if("string"==typeof t)return t.match("%")}function o(t){let e=parseInt(t.replace("%",""));return isNaN(e)||e<0?0:e/100}function l(t,e){let i=!1,s=!1;const n=()=>i=!0,r=()=>s=!0;if(null!=t){var h=[];for(h.push(t);0!=h.length;){var o=h.pop();if(e(o,n,r),s)s=!1;else for(var l=o._getChildren(),d=l.length-1;d>=0;d--)i?i=!1:h.push(l[d])}}}function d(t,e){let i=t,s=!1;const n=()=>{s=!0};for(;i.parent&&(e(i.parent,n),!s);)i=i.parent}function a(){return!window}class g{constructor(){this.width=0,this.height=0,this.contentWidth=0,this.y=0,this.doorClosed=!1,this.outerWidth=0,this.container=null,this.elements=[],this.start=null,this.end=null,this.offsetX=0,this.id=Math.random()}bind(t){this.container=t.parent,this.initHeight(t),this.outerWidth=t.parent&&r(t.parent.styles.width)?1/0:t.parent.renderStyles.contentWidth,this.start=t,this.add(t)}initHeight(t){this.height=t.parent&&t.parent.renderStyles.lineHeight||0}initLayout(t){this.right=t._getContainerLayout().contentX,this.x=t._getContainerLayout().contentX,this.y=this.getPreLine(t).y}refreshElementPosition(t){this.start===t&&this.initLayout(t),t.x=this.right+this.offsetX,t.y=this.y+this.getOffsetY(t),this.right+=t.renderStyles.width}getOffsetY(t){return"bottom"===t.renderStyles.verticalAlign?this.height-t.renderStyles.height:"middle"===t.renderStyles.verticalAlign?(this.height-t.renderStyles.height)/2:0}add(t){this.elements.push(t),t.line=this,this.refreshWidthHeight(t),t.next||this.closeLine()}refreshWidthHeight(t){t.renderStyles.height>this.height&&(this.height=t.renderStyles.height),this.width+=t.renderStyles.width}canIEnter(t){return!(t.renderStyles.width+this.width>this.outerWidth)||(this.closeLine(),!1)}closeLine(){this.end=this.elements[this.elements.length-1],this.refreshXAlign()}getPreLine(t){return t.pre?t.pre.line?{y:t.pre.line.height+t.pre.line.y,x:t.pre.line.x}:{y:t._getPreLayout().y+t._getPreLayout().height,x:t._getPreLayout().x}:{y:t._getContainerLayout().contentY,x:t._getContainerLayout().contentX}}refreshXAlign(){if(this.outerWidth>5e3)return;if(!this.end.parent)return;let t=this.outerWidth-this.width;"center"===this.end.parent.renderStyles.textAlign?t/=2:"left"===this.end.parent.renderStyles.textAlign&&(t=0),this.offsetX=t}}const c={[s.FLEX_DIRECTION.ROW]:{width:"width",contentWidth:"contentWidth",x:"x",y:"y",contentX:"contentX",height:"height",contentHeight:"contentHeight"},[s.FLEX_DIRECTION.COLUMN]:{width:"height",contentWidth:"contentHeight",x:"y",y:"x",contentX:"contentY",height:"width",contentHeight:"contentWidth"}};class y extends g{constructor(){super(),this.exactValue=0,this.flexTotal=0,this.key=null}closeLine(){super.closeLine(),this.calcFlex()}bind(t){this.container=t.parent,t.parent&&(this.key=c[t.parent.renderStyles.flexDirection]),this.initHeight(t),this.outerWidth=t.parent&&r(t.parent.styles[this.key.width])?1/0:t.parent.renderStyles[this.key.contentWidth],this.start=t,this.add(t)}add(t){n(t.styles.flex)?this.flexTotal+=t.styles.flex:n(t.styles[this.key.width])&&(this.exactValue+=t.styles[this.key.width]),super.add(t)}initHeight(){this[this.key.height]=0}refreshWidthHeight(t){t.renderStyles[this.key.height]>this[this.key.height]&&(this[this.key.height]=t.renderStyles[this.key.height]),this[this.key.width]+=t.renderStyles[this.key.width]}initLayout(t){this.right=t._getContainerLayout()[this.key.contentX],this[this.key.x]=t._getContainerLayout()[this.key.contentX],this[this.key.y]=this.getPreLine(t)[this.key.y]}refreshElementPosition(t){this.start===t&&this.initLayout(t),t[this.key.x]=this.right+this.offsetX,t[this.key.y]=this[this.key.y]+this.getOffsetY(t),this.right+=t.renderStyles[this.key.width]}calcFlex(){const{[this.key.contentWidth]:t}=this.container.renderStyles;this.elements.forEach(e=>{n(e.styles.flex)&&(e.renderStyles[this.key.width]=e.styles.flex/this.flexTotal*(t-this.exactValue),e._refreshContentWithLayout())})}refreshXAlign(){if(!this.end.parent)return;let t=this.outerWidth-this[this.key.width];"center"===this.end.parent.renderStyles.justifyContent?t/=2:"flex-start"===this.end.parent.renderStyles.justifyContent&&(t=0),this.offsetX=t}getOffsetY(t){return"flex-end"===t.renderStyles.alignSelf?this.container.renderStyles[this.key.contentHeight]-t.renderStyles[this.key.height]:"center"===t.renderStyles.alignSelf?(this.container.renderStyles[this.key.contentHeight]-t.renderStyles[this.key.height])/2:0}}class u{static connectChildren(t){t.hasChildren()&&t._getChildren().map((e,i)=>{e._setParent(t),e._setSibling(t._getChildren()[i-1],t._getChildren()[i+1]),u.connectChildren(e)})}constructor(t){this.children=t||[],this.parent=null,this.root=null,this.pre=null,this.next=null}hasChildren(){return!(!Array.isArray(this.children)||!this.children.length)}_getChildren(){return this.hasChildren()?this.children:[]}_setParent(t){this.parent=t,this.root=t.root}_setSibling(t,e){this.pre=t||null,this.next=e||null}appendChild(t){if(!t instanceof u)throw Error("Unknown treeNode type");const e=this._getChildren()[this._getChildren().length-1];this.children.push(t),t._setParent(this),t._setSibling(e,null)}prependChild(t){if(!t instanceof u)throw Error("Unknown treeNode type");const e=this._getChildren()[0];this.children.unshift(t),t._setParent(this),t._setSibling(null,e)}removeChild(t){if(!t instanceof u)throw Error("Unknown treeNode type");const e=this._getChildren().indexOf(t);if(e<0)throw Error("treeNode must be the child of parent");const i=this._getChildren()[e-1],s=this._getChildren()[e+1];i&&i._setSibling(i.pre,s),s&&s._setSibling(i,s.next),this.children.splice(e,1)}remove(){if(!this.parent)throw Error("Can not remove root node");this.parent.removeChild(this)}append(t){if(!t instanceof u)throw Error("Unknown treeNode type");if(!this.parent)throw Error("Can not add treeNode to root level!");let e=[];t._setParent(this.parent),this.parent.children.forEach((i,s)=>{e.push(i),i===this&&(t._setSibling(i,this.parent.children[s+1]),e.push(t))}),this.parent.children=e}prepend(t){if(!t instanceof u)throw Error("Unknown treeNode type");if(!this.parent)throw Error("Can not add treeNode to root level!");let e=[];t._setParent(this.parent);for(let i=this.parent.children.length-1;i>=0;i--)e.unshift(this.parent.children[i]),this.parent.children[i]===this&&(t._setSibling(this.parent.children[i-1],this.parent.children[i]),e.unshift(t));this.parent.children=e}}function p(t){!function(t){t.parent&&t.parent.styles.display===s.DISPLAY.FLEX&&(t.styles.flex?"column"===t.parent.styles.flexDirection&&n(t.styles.flex)?t.styles.height=0:"row"===t.parent.styles.flexDirection&&n(t.styles.flex)&&(t.styles.width=0):n(t.styles.height)||n(t.styles.width)||(t.styles.flex=1))}(t),function(t){t.styles.width||(t.styles.display!==s.DISPLAY.INLINE_BLOCK&&t.styles.display!==s.DISPLAY.INLINE&&t.isInFlow()?t.styles.display===s.DISPLAY.BLOCK||t.styles.display===s.DISPLAY.FLEX?t.styles.width=s.WIDTH.OUTER:t.styles.width=0:t.styles.width=s.WIDTH.AUTO);h(t.styles.width)&&t.parent&&r(t.parent.styles.width)&&(t.styles.width=s.WIDTH.AUTO);h(t.styles.height)&&t.parent&&r(t.parent.styles.height)&&(t.styles.height=s.WIDTH.AUTO)}(t),function(t){let{borderWidth:e,borderLeftWidth:i,borderRightWidth:s,borderBottomWidth:n,borderTopWidth:r,borderRadius:h}=t.styles;e||(t.styles.borderWidth=0,e=0);Array.isArray(e)?(t.styles.borderTopWidth=e[0],t.styles.borderRightWidth=e[1],t.styles.borderBottomWidth=e[2],t.styles.borderLeftWidth=e[3]):(i||(t.styles.borderLeftWidth=e),s||(t.styles.borderRightWidth=e),n||(t.styles.borderBottomWidth=e),r||(t.styles.borderTopWidth=e));h&&(t.styles.overflow="hidden")}(t),function(t){t.styles.fontSize&&!t.styles.lineHeight&&(t.styles.lineHeight=1.4*t.styles.fontSize)}(t),function(t){t.styles.padding&&(n(t.styles.padding)?(t.styles.paddingLeft=t.styles.padding,t.styles.paddingBottom=t.styles.padding,t.styles.paddingRight=t.styles.padding,t.styles.paddingTop=t.styles.padding):Array.isArray(t.styles.padding)&&(2===t.styles.padding.length?(t.styles.paddingLeft=t.styles.paddingRight=t.styles.padding[1],t.styles.paddingBottom=t.styles.paddingTop=t.styles.padding[0]):4===t.styles.padding.length&&(t.styles.paddingLeft=t.styles.padding[3],t.styles.paddingBottom=t.styles.padding[2],t.styles.paddingRight=t.styles.padding[1],t.styles.paddingTop=t.styles.padding[0])));n(t.styles.margin)?(t.styles.marginLeft=t.styles.margin,t.styles.marginBottom=t.styles.margin,t.styles.marginRight=t.styles.margin,t.styles.marginTop=t.styles.margin):Array.isArray(t.styles.margin)&&(2===t.styles.margin.length?(t.styles.marginLeft=t.styles.marginRight=t.styles.margin[1],t.styles.marginBottom=t.styles.marginTop=t.styles.margin[0]):4===t.styles.margin.length&&(t.styles.marginLeft=t.styles.margin[3],t.styles.marginBottom=t.styles.margin[2],t.styles.marginRight=t.styles.margin[1],t.styles.marginTop=t.styles.margin[0]))}(t)}class f extends u{constructor(t,e){super(e),this.options=Object.assign({attrs:{},styles:{},on:{}},t),this.styles=null,this.renderStyles=null,this.x=0,this.y=0,this.render=null,this.container=null,this.visible=!0}init(){this._initStyles(),this.initEvent()}initEvent(){const{click:t}=this.options.on;if(t){const{click:t}=this.options.on;this.getLayer().eventManager.onClick(t,this)}}removeEvent(){this.getLayer().eventManager.removeElement(this)}getLayer(){return this.root.layer}getRender(){return this.root.layer.render}mount(t){t.mountNode(this)}_initStyles(){this.styles=Object.assign({},this._getDefaultStyles(),this._getParentStyles(this.options.styles),this.options.styles||{}),this._completeStyles(),this._initRenderStyles()}_initRenderStyles(){const t={...this.styles},e=this._getContainerLayout().contentWidth,i=this._getContainerLayout().contentHeight;r(t.width)?t.width=0:h(t.width)&&(t.width=o(t.width)*e),r(t.height)?t.height=0:h(t.height)&&(t.height=o(t.height)*i),t.width||(t.width=0),t.height||(t.height=0),t.contentWidth=t.width-t.paddingLeft-t.paddingRight-t.marginLeft-t.marginRight-this._getTotalBorderWidth(t),t.contentHeight=t.height-t.paddingTop-t.paddingBottom-t.marginTop-t.marginBottom-this._getTotalBorderHeight(t),this.renderStyles=t,this._InFlexBox()&&this._bindFlexBox()}_getParentStyles(t){let{textAlign:e,lineHeight:i,fontSize:s,color:n,fontFamily:r,alignItems:h,visible:o=!0}=this.parent&&this.parent.renderStyles||{},l={};return e&&(l.textAlign=e),s&&(l.fontSize=s),n&&(l.color=n),r&&(l.fontFamily=r),h&&!t.alignSelf&&(l.alignSelf=h),l.visible=o,l}_completeStyles(){p(this)}_getDefaultStyles(){return s.DEFAULT_STYLES}_getChildrenInFlow(){return this._getChildren().filter(t=>t.isInFlow())}isInFlow(){const{position:t,display:e}=this.styles;return t!==s.POSITION.ABSOLUTE&&t!==s.POSITION.FIXED}isVisible(){return this.renderStyles.visible&&this.visible}_generateRender(){return this}getCtx(){return this.root.layer.ctx}_reflow(){}_initWidthHeight(){const{width:t,height:e,display:i,flex:n,marginLeft:h,marginRight:o,marginTop:l,marginBottom:d}=this.styles;if(r(t)||r(e)){const i=this._measureLayout();r(t)&&(this.renderStyles.contentWidth=i.width),r(e)&&(this.renderStyles.contentHeight=i.height)}this._refreshLayoutWithContent(),this._InFlexBox()?this.line.refreshWidthHeight(this):i===s.DISPLAY.INLINE_BLOCK&&this._bindLine()}_initPosition(){const{contentX:t,contentY:e,contentWidth:i,contentHeight:r}=this._getContainerLayout(),{paddingLeft:l,paddingTop:d,borderLeftWidth:a,borderTopWidth:g,marginLeft:c,marginTop:y}=this.renderStyles;if(this.isInFlow())this._InFlexBox()||this.renderStyles.display===s.DISPLAY.INLINE_BLOCK?this.line.refreshElementPosition(this):(this.x=t,this.y=this._getPreLayout().y+this._getPreLayout().height);else{let{top:s,bottom:l,right:d,left:a,width:g,height:c}=this.renderStyles;h(s)&&(s=o(s)*r),h(l)&&(l=o(l)*r),h(a)&&(a=o(a)*i),h(d)&&(d=o(d)*i),n(s)?this.y=e+s:n(l)&&(this.y=e+r-l-c),n(a)?this.x=t+a:n(d)&&(this.x=t+i-d-g)}this.contentX=this.x+l+a+c,this.contentY=this.y+d+g+y}_InFlexBox(){return!!this.isInFlow()&&(!!this.parent&&(!(!this.parent||this.parent.renderStyles.display!==s.DISPLAY.FLEX)||void 0))}_refreshLayoutWithContent(){this.renderStyles.height=this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom+this.renderStyles.marginTop+this.renderStyles.marginBottom+this._getTotalBorderHeight(),this.renderStyles.width=this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight+this.renderStyles.marginLeft+this.renderStyles.marginRight+this._getTotalBorderWidth()}_refreshContentWithLayout(){this.renderStyles.contentHeight=this.renderStyles.height-this.renderStyles.paddingTop-this.renderStyles.paddingBottom-this.renderStyles.marginTop-this.renderStyles.marginBottom-this._getTotalBorderHeight(),this.renderStyles.contentWidth=this.renderStyles.width-this.renderStyles.paddingLeft-this.renderStyles.paddingRight-this.renderStyles.marginLeft-this.renderStyles.marginRight-this._getTotalBorderWidth()}_getTotalBorderWidth(t=this.renderStyles){return t.borderLeftWidth+t.borderRightWidth}_getTotalBorderHeight(t=this.renderStyles){return t.borderTopWidth+t.borderBottomWidth}_bindLine(){this.pre&&this.pre.line&&this.pre.line.canIEnter(this)?this.pre.line.add(this):(new g).bind(this)}_bindFlexBox(){this.pre&&this.pre.line?this.pre.line.add(this):(new y).bind(this)}_getContainerLayout(){let t=this.parent;return this.styles.position===s.POSITION.FIXED&&(t=this.root),t||(t={renderStyles:{width:this.container.width,height:this.container.height,paddingTop:0,paddingBottom:0,paddingLeft:0,paddingRight:0,marginLeft:0,marginRight:0,marginTop:0,marginBottom:0,contentWidth:this.container.width,contentHeight:this.container.height},x:0,y:0,contentX:0,contentY:0}),{width:t.renderStyles.width,height:t.renderStyles.height,x:t.x,y:t.y,paddingTop:t.renderStyles.paddingTop,paddingBottom:t.renderStyles.paddingBottom,paddingLeft:t.renderStyles.paddingLeft,paddingRight:t.renderStyles.paddingRight,marginLeft:t.renderStyles.marginLeft,marginRight:t.renderStyles.marginRight,marginTop:t.renderStyles.marginTop,marginBottom:t.renderStyles.marginBottom,contentX:t.contentX,contentY:t.contentY,contentWidth:t.renderStyles.contentWidth,contentHeight:t.renderStyles.contentHeight}}_getPreLayout(){let t=this.pre;for(;t&&!t.isInFlow();)t=t.pre;return t?{width:t.renderStyles.width,height:t.renderStyles.height,x:t.x,y:t.y}:{width:0,height:0,x:this._getContainerLayout().contentX,y:this._getContainerLayout().contentY}}_measureLayout(){let t=0,e=0;return this._getChildrenInFlow().forEach(i=>{i.line?i.line.start===i&&(i.line.width>t&&(t=i.line.width),e+=i.line.height):i.renderStyles.width>t?(t=i.renderStyles.width,e+=i.renderStyles.height):e+=i.renderStyles.height}),{width:t,height:e}}getElementBy(t,e){let i=[];return l(this,s=>{s.options.attrs[t]===e&&i.push(s)}),i}appendChild(t){return super.appendChild(t),this.getLayer().mountNode(this.root),t}prependChild(t){return super.prependChild(t),this.getLayer().mountNode(this.root),t}removeChild(t){super.removeChild(t),t.removeEvent(),this.getLayer().mountNode(this.root)}append(t){super.append(t),this.getLayer().mountNode(this.root)}prepend(t){super.prepend(t),this.getLayer().mountNode(this.root)}}class m extends f{constructor(t,e){super(t,e),this.type="view"}_getDefaultStyles(){return{...s.DEFAULT_STYLES,display:s.DISPLAY.BLOCK}}}class w extends f{constructor(t,e){super(t,e),this._layout=null,this._lines=[],this.children+="",this.type="text"}_getDefaultStyles(){return{...s.DEFAULT_STYLES,display:s.DISPLAY.INLINE_BLOCK,width:s.WIDTH.AUTO,textAlign:"left"}}_measureLayout(){return this._layout=this.getRender().measureText(this,this.children),this._layout.fontHeight=.8*this.renderStyles.fontSize,this._layout.height=this.renderStyles.lineHeight,this._calcLine(),this._layout}_getFont(){const{fontSize:t,fontWeight:e,fontFamily:i}=this.renderStyles;return`${e} ${t}px ${i}`}_calcLine(){if(!this.parent||!this.children)return;const{width:t,height:e}=this._layout;let{contentWidth:i}=this.parent.renderStyles;const{width:h}=this.parent.styles;if(r(this.styles.width)||(i=this.renderStyles.width),n(i)&&i>=t||h===s.WIDTH.AUTO)this._lines=[this.children];else{this._lines=[];let t=1,e="",s=null;for(let n=0;ni){if(t>=this.renderStyles.maxLine){e=e.substring(0,e.length-2)+"...";break}this._lines.push(e),e="",t+=1}e+=this.children[n]}this._layout.width=i,this._lines.push(e),this._layout.height=this._lines.length*this.renderStyles.lineHeight}}}class S extends m{constructor(t,e){super(t,e),this.type="image",this._imageInfo={width:0,height:0,sx:0,sy:0,swidth:0,sheight:0,dx:0,dy:0,dwidth:0,dheight:0},this.debugColor="blue",this._image=null,this._layout=null}init(){super.init(),this._loadImage()}_loadImage(){const{mode:t}=this.options.attrs;return new Promise((t,e)=>{this.getRender().getImageInstance(this.options.attrs.src).then(({info:e,image:i})=>{this._imageInfo=e,this._image=i,t(),this._layoutImage(),this.isVisible()&&this.getLayer().onElementChange(this),this.options.on&&this.options.on.load&&this.options.on.load(this)})})}_layoutImage(){const{contentWidth:t,contentHeight:e}=this.renderStyles,{mode:i}=this.options.attrs,{width:s,height:n}=this.styles,{width:h,height:o}=this._imageInfo;let l=t,d=e;!r(s)&&r(n)?(l=t,d=x(l,h,o)):!r(n)&&r(s)?(d=e,l=_(d,h,o)):r(s)&&r(n)?(l=h,d=o):"aspectFill"===i?l/d>h/o?(this._imageInfo.swidth=h,this._imageInfo.sheight=x(h,l,d),this._imageInfo.sx=0,this._imageInfo.sy=(o-this._imageInfo.sheight)/2):(this._imageInfo.sheight=o,this._imageInfo.swidth=_(o,t,e),this._imageInfo.sy=0,this._imageInfo.sx=(h-this._imageInfo.swidth)/2):"aspectFit"===i?l/d>h/o?(this._imageInfo.dwidth=_(e,h,o),this._imageInfo.dheight=e,this._imageInfo.dy=this.contentY,this._imageInfo.dx=(t-this._imageInfo.dwidth)/2+this.contentX):(this._imageInfo.dheight=x(t,h,o),this._imageInfo.dwidth=t,this._imageInfo.dx=this.contentX,this._imageInfo.dy=(e-this._imageInfo.dheight)/2+this.contentY):(l=t,d=e),this._layout={width:l,height:d}}_measureLayout(){return this._layout?this._layout:{width:this.renderStyles.width,height:this.renderStyles.height}}}function _(t,e,i){return t/i*e}function x(t,e,i){return t/e*i}class L{constructor({simulateClick:t=!0}){this.clickTree=new u,this.touchstartTree=new u,this.touchmoveTree=new u,this.touchendTree=new u,this.clickList=[],this.touchstartList=[],this.touchmoveList=[],this.touchendList=[],this.touchStartEvent=null,this.simulateClick=t}clear(){this.clickTree=new u,this.touchstartTree=new u,this.touchmoveTree=new u,this.touchendTree=new u,this.clickList=[],this.touchstartList=[],this.touchmoveList=[],this.touchendList=[]}click(t,e){let i=new C({x:t,y:e,type:"click"});this._emit(i)}touchstart(t,e){let i=new C({x:t,y:e,type:"touchstart"});this.touchStartEvent=i,this._emit(i)}touchmove(t,e){let i=new C({x:t,y:e,type:"touchmove"});this._emit(i)}touchend(t,e){let i=new C({x:t,y:e,type:"touchend"});this._emit(i),this.checkClick(i)}_emit(t){let e=[];switch(t.type){case"click":e=this.clickTree;break;case"touchstart":e=this.touchstartTree;break;case"touchmove":e=this.touchmoveTree;break;case"touchend":e=this.touchendTree}let i=[];l(e,(e,s,n)=>{e.element&&(this.isPointInElement(t.relativeX,t.relativeY,e.element)?(e.runCapture(t),i.unshift(e)):s())});for(let e=0;e=i.x,n=e>=i.y,r=t<=i.x+i.renderStyles.width,h=e<=i.y+i.renderStyles.height;return!!(s&&n&&r&&h)}removeElement(t){this.clickList=this.clickList.filter(e=>(e.element===t&&e.remove(),e.element!==t)),this.touchstartList=this.touchstartList.filter(e=>(e.element===t&&e.remove(),e.element!==t)),this.touchmoveList=this.touchmoveList.filter(e=>(e.element===t&&e.remove(),e.element!==t)),this.touchendList=this.touchendList.filter(e=>(e.element===t&&e.remove(),e.element!==t))}onClick(t,e,i=!1){this.addCallback(t,e,this.clickTree,this.clickList,i)}onTouchStart(t,e,i=!1){this.addCallback(t,e,this.touchstartTree,this.touchstartList,i)}onTouchMove(t,e,i=!1){this.addCallback(t,e,this.touchmoveTree,this.touchmoveList,i)}onTouchEnd(t,e,i=!1){this.addCallback(t,e,this.touchendTree,this.touchendList,i)}addCallback(t,e,i,s,n){let r=null,h=null;for(let t=s.length-1;t>=0;t--){if(e===s[t].element){r=s[t-1],h=s[t];break}if(d(e,(e,i)=>{e===s[t].element&&(r=s[t],i())}),r)break}h||(h=new b(e,t)),n?h.addCapture(t):h.addCallback(t),r?r.appendChild(h):i.appendChild(h),s.push(h)}checkClick(t){if(this.touchStartEvent&&this.simulateClick){let{x:e,y:i}=this.touchStartEvent,{x:s,y:n}=t,r=n*n+s*s-(i*i+e*e);r<5&&r>-5&&this.click(s,n)}}}class C{constructor({x:t,y:e,type:i}){this.x=t,this.y=e,this.relativeX=t,this.relativeY=e,this.type=i,this.cancelBubble=!1,this.currentTarget=null}stopPropagation(){this.cancelBubble=!0}}class b extends u{constructor(t){super(),this.element=t,this.callbackList=[],this.captureList=[]}addCallback(t){this.callbackList.push(t)}addCapture(t){this.captureList.push(t)}runCallback(t){this.callbackList.forEach(e=>e(t))}runCapture(t){this.captureList.forEach(e=>e(t))}}const T=Math.PI/2;class I{constructor(t){this.layer=t,this.imageBus={}}getCtx(){return this.layer.ctx}getLayer(){return this.layer}_restore(t){this.getCtx().save(),t(),this.getCtx().restore()}_path(t){this.getCtx().beginPath(),t(),this.getCtx().closePath()}paint(t){this.getCtx().save(),this._drawBackground(t),this._drawContent(t),this._drawBox(t),this.afterPaint(t)}afterPaint(t){t.hasChildren()&&"text"!==t.type||this.getCtx().restore(),this._helpParentRestoreCtx(t)}_helpParentRestoreCtx(t){if(t.isVisible()&&(!(e=t).parent||e.next||e.hasChildren())||!t.isVisible()&&t.next)return;var e;let i=t.parent;for(;i&&!i.next;)this.getCtx().restore(),i=i.parent;i&&i.next&&this.getCtx().restore()}topBorder({x:t,y:e,borderRadius:i,w:s,h:n}){this.getCtx().moveTo(t,e+i),i&&this.getCtx().arc(t+i,e+i,i,2*T,3*T),this.getCtx().lineTo(t+s-i,e)}rightBorder({x:t,y:e,borderRadius:i,w:s,h:n}){i&&this.getCtx().arc(t+s-i,e+i,i,3*T,4*T),this.getCtx().lineTo(t+s,e+n-i)}bottomBorder({x:t,y:e,borderRadius:i,w:s,h:n}){i&&this.getCtx().arc(t+s-i,e+n-i,i,0,T),this.getCtx().lineTo(t+i,e+n)}leftBorder({x:t,y:e,borderRadius:i,w:s,h:n}){i&&this.getCtx().arc(t+i,e+n-i,i,T,2*T),this.getCtx().lineTo(t,e+i)}_drawBox(t){if(!t.renderStyles.borderColor&&!t.renderStyles.shadowBlur)return;const{contentWidth:e,contentHeight:i,paddingLeft:s,paddingTop:n,borderStyle:r,paddingRight:h,paddingBottom:o,shadowBlur:l,shadowColor:d,backgroundColor:a,shadowOffsetX:g,shadowOffsetY:c,borderLeftWidth:y,borderRightWidth:u,borderTopWidth:p,borderBottomWidth:f}=t.renderStyles;let m=v(t),w=t.contentX-t.renderStyles.paddingLeft-y/2,S=t.contentY-t.renderStyles.paddingTop-p/2,_=e+s+h+(y+u)/2,x=i+n+o+(p+f)/2;this.getCtx().lineCap=t.renderStyles.lineCap,this.getCtx().strokeStyle=t.renderStyles.borderColor,r&&"solid"!==r&&(Array.isArray(r)?this.getCtx().setLineDash(r):this.getCtx().setLineDash([5,5]));const L=t=>{this.getCtx().lineWidth=t,this.getCtx().stroke()};this._restore(()=>{this._path(()=>{w=t.contentX-t.renderStyles.paddingLeft-y/2,S=t.contentY-t.renderStyles.paddingTop-p/2,_=e+s+h+(y+u)/2,x=i+n+o+(p+f)/2,t.renderStyles.borderTopWidth&&(this.topBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderTopWidth)),t.renderStyles.borderRightWidth&&(this.getCtx().moveTo(w+_-m,S),this.rightBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderRightWidth)),t.renderStyles.borderBottomWidth&&(this.getCtx().moveTo(w+_,S+x-m),this.bottomBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderBottomWidth)),t.renderStyles.borderLeftWidth&&(this.getCtx().moveTo(w+m,S+x),this.leftBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderLeftWidth))})})}_drawBackground(t){const{backgroundColor:e,contentWidth:i,contentHeight:s,shadowColor:r,shadowBlur:h,paddingLeft:o,paddingRight:l,paddingTop:d,paddingBottom:a,opacity:g,shadowOffsetX:c,shadowOffsetY:y,borderLeftWidth:u,borderRightWidth:p,borderTopWidth:f,borderBottomWidth:m}=t.renderStyles,w=this.getCtx();let S=v(t),_=t.contentX-t.renderStyles.paddingLeft-u/2,x=t.contentY-t.renderStyles.paddingTop-f/2,L=i+o+l+(u+p)/2,C=s+d+a+(f+m)/2;n(g)&&(w.globalAlpha=g),r&&h&&this._restore(()=>{this._path(()=>{this.topBorder({x:_,y:x,borderRadius:S,w:L,h:C}),this.rightBorder({x:_,y:x,borderRadius:S,w:L,h:C}),this.bottomBorder({x:_,y:x,borderRadius:S,w:L,h:C}),this.leftBorder({x:_,y:x,borderRadius:S,w:L,h:C})}),n(c)&&(this.getCtx().shadowOffsetX=c),n(y)&&(this.getCtx().shadowOffsetY=y),this.getCtx().shadowBlur=h,this.getCtx().shadowColor=r,this.getCtx().fillStyle=r,this.getCtx().fill()}),this._clip(t),e&&(this.getCtx().fillStyle=this._parseBackground(e,t),this.getCtx().fillRect(t.contentX-o,t.contentY-d,i+o+l,s+d+a)),this.getLayer().options&&this.getLayer().options.debug&&(this.getCtx().strokeStyle="green",this.getCtx().strokeRect(t.contentX,t.contentY,t.renderStyles.contentWidth,t.renderStyles.contentHeight))}_clip(t){if("hidden"!==t.renderStyles.overflow)return;const{contentWidth:e,contentHeight:i,paddingLeft:s,paddingTop:n,paddingRight:r,paddingBottom:h,shadowBlur:o,shadowColor:l,backgroundColor:d,borderLeftWidth:a,borderRightWidth:g,borderTopWidth:c,borderBottomWidth:y}=t.renderStyles;let u=v(t),p=t.contentX-t.renderStyles.paddingLeft-a,f=t.contentY-t.renderStyles.paddingTop-c,m=e+s+r+a+g,w=i+n+h+c+y;this._path(()=>{this.topBorder({x:p,y:f,borderRadius:u,w:m,h:w}),this.rightBorder({x:p,y:f,borderRadius:u,w:m,h:w}),this.bottomBorder({x:p,y:f,borderRadius:u,w:m,h:w}),this.leftBorder({x:p,y:f,borderRadius:u,w:m,h:w})}),this.getCtx().clip()}_parseBackground(t,e){if(Array.isArray(t)){const i=this.getCtx().createLinearGradient(e.contentX,e.contentY,e.renderStyles.contentWidth,e.renderStyles.contentHeight);for(let e=0;e{l=0===i&&h?o+h:o,this.getCtx().fillText(e,l,t.contentY+(n+t._layout.fontHeight)/2+n*i)})}measureText(t,e){let i=0;return this._restore(()=>{this.getCtx().font=t._getFont();const{width:s}=this.getCtx().measureText(e);i=s}),{width:i}}_drawImage(t){if(!t._image)return;const{contentWidth:e,contentHeight:i}=t.renderStyles,{mode:s}=t.options.attrs,{sx:n,sy:r,swidth:h,sheight:o,dx:l,dy:d,dwidth:a,dheight:g,width:c,height:y}=t._imageInfo;"aspectFill"===s?this.getCtx().drawImage(t._image,n,r,h,o,t.contentX,t.contentY,e,i):"aspectFit"===s?this.getCtx().drawImage(t._image,0,0,c,y,l,d,a,g):this.getCtx().drawImage(t._image,t.contentX,t.contentY,e,i)}_drawScroll(t){this.getCtx().translate(t.currentScrollX,t.currentScrollY)}getImageInstance(t){let e=null;if(this.imageBus[t])e=this.imageBus[t];else{if(a()){if(!this.getLayer().options.canvas)throw Error("微信小程序中需要在options中设置canvas以创建图片");e=this.getLayer().options.canvas.createImage()}else e=new Image;t&&(this.imageBus[t]=new Promise((t,i)=>{e.onload=function(i){t({image:e,info:{width:i.target.width,height:i.target.height}})}})),e.src=t}return this.imageBus[t]}render(t){t.parent?this.getCtx().clearRect(t.x,t.y,t.renderStyles.width,t.renderStyles.height):this.getCtx().clearRect(0,0,this.getLayer().options.width,this.getLayer().options.height),l(t,(t,e,i)=>{t.isVisible()?this.paint(t):(i(),this._helpParentRestoreCtx(t))}),a()&&this.getCtx().draw&&this.getCtx().draw()}}function v(t){const{contentWidth:e,contentHeight:i}=t.renderStyles;let{borderRadius:s}=t.renderStyles;return 2*s>e&&(s=e/2),2*s>i&&(s=i/2),s<0&&(s=0),s}class B{constructor(t,e){this.ctx=t,this.node=null,this.isAnimate=!1,this.nodeList=[],this.p2cList=[],this.c2pList=[],this.renderList=[],this.options=e,this.eventManager=new L(e),this.render=new I(this)}update(t,e){this.ctx=t,this.options=e,this.options.renderStyles=e,this.node.container=this.options}mountNode(t){this.node=t,this.node.root=this.node,this.node.layer=this,this.node.container=this.options,this.eventManager.clear(),this.initRender()}initRender(){const t=Date.now();u.connectChildren(this.node),this.p2cList=this.getP2CList(this.node),this.c2pList=function(t){var e=[];if(null!=t){var i=[];for(i.unshift(t);0!=i.length;){var s=i.shift();e.push(s._generateRender());for(var n=s._getChildren(),r=n.length-1;r>=0;r--)i.push(n[r]._generateRender())}}return e}(this.node).reverse(),this.initNode(),this.flow(),this.repaint(),console.log(`渲染${this.p2cList.length}个元素 耗时 ${Date.now()-t} ms`)}getP2CList(t){return function(t){var e=[];if(null!=t){var i=[];for(i.unshift(t);0!=i.length;){var s=i.shift();e.push(s._generateRender());for(var n=s._getChildren(),r=0;r{t._initWidthHeight()});for(let t=0;tthis._animate())}animate(){this.isAnimate=!0,window.requestAnimationFrame(()=>this._animate())}stopAnimate(){this.isAnimate=!1}}class W extends m{constructor(t,e){return super(t,e),t.styles.overflow="hidden",this.type="scroll-view",this._scrollView=new m(t,[this]),this._scrollView.type="scroll-view-container",this.visibleIndex=null,this.renderOnDemand=t.attrs&&t.attrs.renderOnDemand||!1,this._scrollView}_getDefaultStyles(){return{...s.DEFAULT_STYLES,direction:"y"}}beforePaint(){this.initChildrenVisible()}init(){super.init(),this.addEventListener();const{height:t,width:e,direction:i}=this.styles;i.match("y")&&(r(t)?console.error("scroll-view 必须设置明确的高度"):(this.styles.height="auto",this.renderStyles.height="auto")),i.match("x")&&(r(e)?console.error("scroll-view 必须设置明确的宽度"):(this.styles.width="auto",this.renderStyles.width="auto"))}addEventListener(){this.currentScrollX=0,this.currentScrollY=0;let t=this.styles.direction,e=0,i=0,s=0,n=0,r=!1,h=0,o=0,l=0,d=0,a=null,g=1,c=1;this.getLayer().eventManager.onClick(e=>{t.match("y")&&(e.relativeY-=this.currentScrollY),t.match("x")&&(e.relativeX-=this.currentScrollX)},this._scrollView,!0),this.getLayer().eventManager.onTouchStart(t=>{t.stopPropagation(),e=t.x,i=t.y,s=e,n=i,r=!0,clearInterval(a)},this._scrollView),this.getLayer().eventManager.onTouchMove(t=>{r&&(t.stopPropagation(),h=t.x-e,o=t.y-i,this.scrollBy(h,o)&&(s=e,n=i,e=t.x,i=t.y))},this._scrollView),this.getLayer().eventManager.onTouchEnd(t=>{r&&(r=!1,l=t.x-s,d=t.y-n,g=.02*-l,c=.02*-d,clearInterval(a),a=setInterval(()=>{this.scrollBy(l,d)||clearInterval(a),l+=g,d+=c,l*l<=.05&&d*d<=.05&&(l=0,d=0,clearInterval(a))},17))},this._scrollView)}calcScrollBoundX(t){const{contentWidth:e,contentHeight:i}=this._scrollView.renderStyles,{width:s,height:n,direction:r}=this.renderStyles;if(r.match("x")){if(e-this.currentScrollX-t>s)return!1;if(this.currentScrollX+t>0)return!1}return!0}calcScrollBoundY(t){const{contentWidth:e,contentHeight:i}=this._scrollView.renderStyles,{width:s,height:n,direction:r}=this.renderStyles;if(r.match("y")){if(i-this.currentScrollY-t>n)return!1;if(this.currentScrollY+t>0)return!1}return!0}scrollByX(t){return!!this.renderStyles.direction.match("x")&&(!!this.calcScrollBoundX(t)&&(this.currentScrollX+=t,!0))}scrollByY(t){return!!this.renderStyles.direction.match("y")&&(!!this.calcScrollBoundY(t)&&(this.currentScrollY+=t,this.calcChildrenVisible(),!0))}scrollBy(t,e){return!!(this.scrollByX(t)|this.scrollByY(e))&&(this.getLayer().repaint(this._scrollView),!0)}scrollTo(t){}initChildrenVisible(){if(!this.renderOnDemand)return;const t=this._getChildrenInFlow();for(let e=0;e=0;e--){if(this.isElementInViewport(t[e])){this.visibleIndex[1]=e;break}t[e].visible=!1}for(let e=this.visibleIndex[0];e<=this.visibleIndex[1];e++)t[e].visible=!0}calcChildrenVisible(){if(!this.renderOnDemand)return;const t=this._getChildrenInFlow(),e=k(this.visibleIndex[0],5),i=k(this.visibleIndex[1],5);let s=[];for(let i=e[0];i<=e[e.length-1];i++)t[i]&&(this.isElementInViewport(t[i])?(t[i].visible=!0,s.length||s.push(i)):t[i].visible=!1);for(let e=i[i.length-1];e>=i[0];e--)t[e]&&(this.isElementInViewport(t[e])?(t[e].visible=!0,1===s.length&&s.push(e)):t[e].visible=!1);this.visibleIndex=s}isElementInViewport(t){return!this.styles.direction.match("y")||t.y+t.renderStyles.height+this.currentScrollY>this._scrollView.contentY&&t.y+this.currentScrollYnew m(t,e)),R("text",(t,e)=>new w(t,e)),R("image",(t,e)=>new S(t,e)),R("scroll-view",(t,e)=>new W(t,e)),R("scrollview",(t,e)=>new W(t,e));return{createLayer:function(t,e){return new B(t,e)},createElement:function(t){return t((function t(e,i={},s=[]){let n=null,r=s;if(!E[e])throw Error(`Unknown tag name [${e}] !`);return n=E[e](i,r,t),n}))},component:R,View:m,Text:w,Image:S,Layer:B,ScrollView:W}})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).easyCanvas=e()}(this,(function(){"use strict";const t={BLOCK:"block",INLINE_BLOCK:"inline-block",INLINE:"inline",FLEX:"flex",NONE:"none"},e={AUTO:"auto",OUTER:"100%"},i={ROW:"row",COLUMN:"column"};var s={DISPLAY:t,WIDTH:e,POSITION:{ABSOLUTE:"absolute",FIXED:"fixed",RELATIVE:"relative",STATIC:"static"},DEFAULT_STYLES:{display:t.BLOCK,fontSize:14,fontWeight:400,fontFamily:"Microsoft Yahei",color:"#000",paddingTop:0,paddingBottom:0,paddingLeft:0,paddingRight:0,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,height:e.AUTO,borderRadius:0,lineCap:"square",flexDirection:i.ROW,verticalAlign:"middle",textAlign:"left",justifyContent:"flex-start",alignItems:"flex-start",whiteSpace:"normal",zIndex:1,visible:!0},TEXT_ALIGN:{LEFT:"left",RIGHT:"right",CENTER:"center"},FLEX_DIRECTION:i};function n(t){return"number"==typeof t}function r(t){return"auto"===t}function h(t){if("string"==typeof t)return t.match("%")}function o(t){let e=parseInt(t.replace("%",""));return isNaN(e)||e<0?0:e/100}function l(t,e){let i=!1,s=!1;const n=()=>i=!0,r=()=>s=!0;if(null!=t){var h=[];for(h.push(t);0!=h.length;){var o=h.pop();if(e(o,n,r),s)s=!1;else for(var l=o._getChildren(),d=l.length-1;d>=0;d--)i?i=!1:h.push(l[d])}}}function d(t,e){let i=t,s=!1;const n=()=>{s=!0};for(;i.parent&&(e(i.parent,n),!s);)i=i.parent}function a(){return!window}class g{constructor(){this.width=0,this.height=0,this.contentWidth=0,this.y=0,this.doorClosed=!1,this.outerWidth=0,this.container=null,this.elements=[],this.start=null,this.end=null,this.offsetX=0,this.id=Math.random()}bind(t){this.container=t.parent,this.initHeight(t),this.outerWidth=t.parent&&r(t.parent.styles.width)?1/0:t.parent.renderStyles.contentWidth,this.start=t,this.add(t)}initHeight(t){this.height=t.parent&&t.parent.renderStyles.lineHeight||0}initLayout(t){this.right=t._getContainerLayout().contentX,this.x=t._getContainerLayout().contentX,this.y=this.getPreLine(t).y}refreshElementPosition(t){this.start===t&&this.initLayout(t),t.x=this.right+this.offsetX,t.y=this.y+this.getOffsetY(t),this.right+=t.renderStyles.width}getOffsetY(t){return"bottom"===t.renderStyles.verticalAlign?this.height-t.renderStyles.height:"middle"===t.renderStyles.verticalAlign?(this.height-t.renderStyles.height)/2:0}add(t){this.elements.push(t),t.line=this,this.refreshWidthHeight(t),t.next||this.closeLine()}refreshWidthHeight(t){t.renderStyles.height>this.height&&(this.height=t.renderStyles.height),this.width+=t.renderStyles.width}canIEnter(t){return!(t.renderStyles.width+this.width>this.outerWidth)||(this.closeLine(),!1)}closeLine(){this.end=this.elements[this.elements.length-1],this.refreshXAlign()}getPreLine(t){return t.pre?t.pre.line?{y:t.pre.line.height+t.pre.line.y,x:t.pre.line.x}:{y:t._getPreLayout().y+t._getPreLayout().height,x:t._getPreLayout().x}:{y:t._getContainerLayout().contentY,x:t._getContainerLayout().contentX}}refreshXAlign(){if(this.outerWidth>5e3)return;if(!this.end.parent)return;let t=this.outerWidth-this.width;"center"===this.end.parent.renderStyles.textAlign?t/=2:"left"===this.end.parent.renderStyles.textAlign&&(t=0),this.offsetX=t}}const c={[s.FLEX_DIRECTION.ROW]:{width:"width",contentWidth:"contentWidth",x:"x",y:"y",contentX:"contentX",height:"height",contentHeight:"contentHeight"},[s.FLEX_DIRECTION.COLUMN]:{width:"height",contentWidth:"contentHeight",x:"y",y:"x",contentX:"contentY",height:"width",contentHeight:"contentWidth"}};class y extends g{constructor(){super(),this.exactValue=0,this.flexTotal=0,this.key=null}closeLine(){super.closeLine(),this.calcFlex()}bind(t){this.container=t.parent,t.parent&&(this.key=c[t.parent.renderStyles.flexDirection]),this.initHeight(t),this.outerWidth=t.parent&&r(t.parent.styles[this.key.width])?1/0:t.parent.renderStyles[this.key.contentWidth],this.start=t,this.add(t)}add(t){n(t.styles.flex)?this.flexTotal+=t.styles.flex:n(t.styles[this.key.width])&&(this.exactValue+=t.styles[this.key.width]),super.add(t)}initHeight(){this[this.key.height]=0}refreshWidthHeight(t){t.renderStyles[this.key.height]>this[this.key.height]&&(this[this.key.height]=t.renderStyles[this.key.height]),this[this.key.width]+=t.renderStyles[this.key.width]}initLayout(t){this.right=t._getContainerLayout()[this.key.contentX],this[this.key.x]=t._getContainerLayout()[this.key.contentX],this[this.key.y]=this.getPreLine(t)[this.key.y]}refreshElementPosition(t){this.start===t&&this.initLayout(t),t[this.key.x]=this.right+this.offsetX,t[this.key.y]=this[this.key.y]+this.getOffsetY(t),this.right+=t.renderStyles[this.key.width]}calcFlex(){const{[this.key.contentWidth]:t}=this.container.renderStyles;this.elements.forEach(e=>{n(e.styles.flex)&&(e.renderStyles[this.key.width]=e.styles.flex/this.flexTotal*(t-this.exactValue),e._refreshContentWithLayout())})}refreshXAlign(){if(!this.end.parent)return;let t=this.outerWidth-this[this.key.width];"center"===this.end.parent.renderStyles.justifyContent?t/=2:"flex-start"===this.end.parent.renderStyles.justifyContent&&(t=0),this.offsetX=t}getOffsetY(t){return"flex-end"===t.renderStyles.alignSelf?this.container.renderStyles[this.key.contentHeight]-t.renderStyles[this.key.height]:"center"===t.renderStyles.alignSelf?(this.container.renderStyles[this.key.contentHeight]-t.renderStyles[this.key.height])/2:0}}class p{static connectChildren(t){t.hasChildren()&&t._getChildren().map((e,i)=>{e._setParent(t),e._setSibling(t._getChildren()[i-1],t._getChildren()[i+1]),p.connectChildren(e)})}constructor(t){this.children=t||[],this.parent=null,this.root=null,this.pre=null,this.next=null}hasChildren(){return!(!Array.isArray(this.children)||!this.children.length)}_getChildren(){return this.hasChildren()?this.children:[]}_setParent(t){this.parent=t,this.root=t.root}_setSibling(t,e){this.pre=t||null,this.next=e||null}appendChild(t){if(!t instanceof p)throw Error("Unknown treeNode type");const e=this._getChildren()[this._getChildren().length-1];this.children.push(t),t._setParent(this),t._setSibling(e,null)}prependChild(t){if(!t instanceof p)throw Error("Unknown treeNode type");const e=this._getChildren()[0];this.children.unshift(t),t._setParent(this),t._setSibling(null,e)}removeChild(t){if(!t instanceof p)throw Error("Unknown treeNode type");const e=this._getChildren().indexOf(t);if(e<0)throw Error("treeNode must be the child of parent");const i=this._getChildren()[e-1],s=this._getChildren()[e+1];i&&i._setSibling(i.pre,s),s&&s._setSibling(i,s.next),this.children.splice(e,1)}remove(){if(!this.parent)throw Error("Can not remove root node");this.parent.removeChild(this)}append(t){if(!t instanceof p)throw Error("Unknown treeNode type");if(!this.parent)throw Error("Can not add treeNode to root level!");let e=[];t._setParent(this.parent),this.parent.children.forEach((i,s)=>{e.push(i),i===this&&(t._setSibling(i,this.parent.children[s+1]),e.push(t))}),this.parent.children=e}prepend(t){if(!t instanceof p)throw Error("Unknown treeNode type");if(!this.parent)throw Error("Can not add treeNode to root level!");let e=[];t._setParent(this.parent);for(let i=this.parent.children.length-1;i>=0;i--)e.unshift(this.parent.children[i]),this.parent.children[i]===this&&(t._setSibling(this.parent.children[i-1],this.parent.children[i]),e.unshift(t));this.parent.children=e}}function u(t){!function(t){t.parent&&t.parent.styles.display===s.DISPLAY.FLEX&&(t.styles.flex?"column"===t.parent.styles.flexDirection&&n(t.styles.flex)?t.styles.height=0:"row"===t.parent.styles.flexDirection&&n(t.styles.flex)&&(t.styles.width=0):n(t.styles.height)||n(t.styles.width)||(t.styles.flex=1))}(t),function(t){t.styles.width||(t.styles.display!==s.DISPLAY.INLINE_BLOCK&&t.styles.display!==s.DISPLAY.INLINE&&t.isInFlow()?t.styles.display===s.DISPLAY.BLOCK||t.styles.display===s.DISPLAY.FLEX?t.styles.width=s.WIDTH.OUTER:t.styles.width=0:t.styles.width=s.WIDTH.AUTO);h(t.styles.width)&&t.parent&&r(t.parent.styles.width)&&(t.styles.width=s.WIDTH.AUTO);h(t.styles.height)&&t.parent&&r(t.parent.styles.height)&&(t.styles.height=s.WIDTH.AUTO)}(t),function(t){let{borderWidth:e,borderLeftWidth:i,borderRightWidth:s,borderBottomWidth:n,borderTopWidth:r,borderRadius:h}=t.styles;e||(t.styles.borderWidth=0,e=0);Array.isArray(e)?(t.styles.borderTopWidth=e[0],t.styles.borderRightWidth=e[1],t.styles.borderBottomWidth=e[2],t.styles.borderLeftWidth=e[3]):(i||(t.styles.borderLeftWidth=e),s||(t.styles.borderRightWidth=e),n||(t.styles.borderBottomWidth=e),r||(t.styles.borderTopWidth=e));h&&(t.styles.overflow="hidden")}(t),function(t){t.styles.fontSize&&!t.styles.lineHeight&&(t.styles.lineHeight=1.4*t.styles.fontSize)}(t),function(t){t.styles.padding&&(n(t.styles.padding)?(t.styles.paddingLeft=t.styles.padding,t.styles.paddingBottom=t.styles.padding,t.styles.paddingRight=t.styles.padding,t.styles.paddingTop=t.styles.padding):Array.isArray(t.styles.padding)&&(2===t.styles.padding.length?(t.styles.paddingLeft=t.styles.paddingRight=t.styles.padding[1],t.styles.paddingBottom=t.styles.paddingTop=t.styles.padding[0]):4===t.styles.padding.length&&(t.styles.paddingLeft=t.styles.padding[3],t.styles.paddingBottom=t.styles.padding[2],t.styles.paddingRight=t.styles.padding[1],t.styles.paddingTop=t.styles.padding[0])));n(t.styles.margin)?(t.styles.marginLeft=t.styles.margin,t.styles.marginBottom=t.styles.margin,t.styles.marginRight=t.styles.margin,t.styles.marginTop=t.styles.margin):Array.isArray(t.styles.margin)&&(2===t.styles.margin.length?(t.styles.marginLeft=t.styles.marginRight=t.styles.margin[1],t.styles.marginBottom=t.styles.marginTop=t.styles.margin[0]):4===t.styles.margin.length&&(t.styles.marginLeft=t.styles.margin[3],t.styles.marginBottom=t.styles.margin[2],t.styles.marginRight=t.styles.margin[1],t.styles.marginTop=t.styles.margin[0]))}(t)}class f extends p{constructor(t,e){super(e),this.options=Object.assign({attrs:{},styles:{},on:{}},t),this.styles=null,this.renderStyles=null,this.x=0,this.y=0,this.render=null,this.container=null,this.visible=!0}init(){this._initStyles(),this.initEvent()}initEvent(){const{click:t}=this.options.on;if(t){const{click:t}=this.options.on;this.getLayer().eventManager.onClick(t,this)}}removeEvent(){this.getLayer().eventManager.removeElement(this)}getLayer(){return this.root.layer}getRender(){return this.root.layer.render}mount(t){t.mountNode(this)}_initStyles(){this.styles=Object.assign({},this._getDefaultStyles(),this._getParentStyles(this.options.styles),this.options.styles||{}),this._completeStyles(),this._initRenderStyles()}_initRenderStyles(){const t={...this.styles},e=this._getContainerLayout().contentWidth,i=this._getContainerLayout().contentHeight;r(t.width)?t.width=0:h(t.width)&&(t.width=o(t.width)*e),r(t.height)?t.height=0:h(t.height)&&(t.height=o(t.height)*i),t.width||(t.width=0),t.height||(t.height=0),t.contentWidth=t.width-t.paddingLeft-t.paddingRight-t.marginLeft-t.marginRight-this._getTotalBorderWidth(t),t.contentHeight=t.height-t.paddingTop-t.paddingBottom-t.marginTop-t.marginBottom-this._getTotalBorderHeight(t),this.renderStyles=t,this._InFlexBox()&&this._bindFlexBox()}_getParentStyles(t){let{textAlign:e,lineHeight:i,fontSize:s,color:n,fontFamily:r,alignItems:h,visible:o=!0}=this.parent&&this.parent.renderStyles||{},l={};return e&&(l.textAlign=e),s&&(l.fontSize=s),n&&(l.color=n),r&&(l.fontFamily=r),h&&!t.alignSelf&&(l.alignSelf=h),l.visible=o,l}_completeStyles(){u(this)}_getDefaultStyles(){return s.DEFAULT_STYLES}_getChildrenInFlow(){return this._getChildren().filter(t=>t.isInFlow())}isInFlow(){const{position:t,display:e}=this.styles;return t!==s.POSITION.ABSOLUTE&&t!==s.POSITION.FIXED}isVisible(){return this.renderStyles.visible&&this.visible}_generateRender(){return this}getCtx(){return this.root.layer.ctx}_reflow(){}_initWidthHeight(){const{width:t,height:e,display:i,flex:n,marginLeft:h,marginRight:o,marginTop:l,marginBottom:d}=this.styles;if(r(t)||r(e)){const i=this._measureLayout();r(t)&&(this.renderStyles.contentWidth=i.width),r(e)&&(this.renderStyles.contentHeight=i.height)}this._refreshLayoutWithContent(),this._InFlexBox()?this.line.refreshWidthHeight(this):i===s.DISPLAY.INLINE_BLOCK&&this._bindLine()}_initPosition(){const{contentX:t,contentY:e,contentWidth:i,contentHeight:r}=this._getContainerLayout(),{paddingLeft:l,paddingTop:d,borderLeftWidth:a,borderTopWidth:g,marginLeft:c,marginTop:y}=this.renderStyles;if(this.isInFlow())this._InFlexBox()||this.renderStyles.display===s.DISPLAY.INLINE_BLOCK?this.line.refreshElementPosition(this):(this.x=t,this.y=this._getPreLayout().y+this._getPreLayout().height);else{let{top:s,bottom:l,right:d,left:a,width:g,height:c}=this.renderStyles;h(s)&&(s=o(s)*r),h(l)&&(l=o(l)*r),h(a)&&(a=o(a)*i),h(d)&&(d=o(d)*i),n(s)?this.y=e+s:n(l)&&(this.y=e+r-l-c),n(a)?this.x=t+a:n(d)&&(this.x=t+i-d-g)}this.contentX=this.x+l+a+c,this.contentY=this.y+d+g+y}_InFlexBox(){return!!this.isInFlow()&&(!!this.parent&&(!(!this.parent||this.parent.renderStyles.display!==s.DISPLAY.FLEX)||void 0))}_refreshLayoutWithContent(){this.renderStyles.height=this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom+this.renderStyles.marginTop+this.renderStyles.marginBottom+this._getTotalBorderHeight(),this.renderStyles.width=this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight+this.renderStyles.marginLeft+this.renderStyles.marginRight+this._getTotalBorderWidth()}_refreshContentWithLayout(){this.renderStyles.contentHeight=this.renderStyles.height-this.renderStyles.paddingTop-this.renderStyles.paddingBottom-this.renderStyles.marginTop-this.renderStyles.marginBottom-this._getTotalBorderHeight(),this.renderStyles.contentWidth=this.renderStyles.width-this.renderStyles.paddingLeft-this.renderStyles.paddingRight-this.renderStyles.marginLeft-this.renderStyles.marginRight-this._getTotalBorderWidth()}_getTotalBorderWidth(t=this.renderStyles){return t.borderLeftWidth+t.borderRightWidth}_getTotalBorderHeight(t=this.renderStyles){return t.borderTopWidth+t.borderBottomWidth}_bindLine(){this.pre&&this.pre.line&&this.pre.line.canIEnter(this)?this.pre.line.add(this):(new g).bind(this)}_bindFlexBox(){this.pre&&this.pre.line?this.pre.line.add(this):(new y).bind(this)}_getContainerLayout(){let t=this.parent;return this.styles.position===s.POSITION.FIXED&&(t=this.root),t||(t={renderStyles:{width:this.container.width,height:this.container.height,paddingTop:0,paddingBottom:0,paddingLeft:0,paddingRight:0,marginLeft:0,marginRight:0,marginTop:0,marginBottom:0,contentWidth:this.container.width,contentHeight:this.container.height},x:0,y:0,contentX:0,contentY:0}),{width:t.renderStyles.width,height:t.renderStyles.height,x:t.x,y:t.y,paddingTop:t.renderStyles.paddingTop,paddingBottom:t.renderStyles.paddingBottom,paddingLeft:t.renderStyles.paddingLeft,paddingRight:t.renderStyles.paddingRight,marginLeft:t.renderStyles.marginLeft,marginRight:t.renderStyles.marginRight,marginTop:t.renderStyles.marginTop,marginBottom:t.renderStyles.marginBottom,contentX:t.contentX,contentY:t.contentY,contentWidth:t.renderStyles.contentWidth,contentHeight:t.renderStyles.contentHeight}}_getPreLayout(){let t=this.pre;for(;t&&!t.isInFlow();)t=t.pre;return t?{width:t.renderStyles.width,height:t.renderStyles.height,x:t.x,y:t.y}:{width:0,height:0,x:this._getContainerLayout().contentX,y:this._getContainerLayout().contentY}}_measureLayout(){let t=0,e=0;return this._getChildrenInFlow().forEach(i=>{i.line?i.line.start===i&&(i.line.width>t&&(t=i.line.width),e+=i.line.height):i.renderStyles.width>t?(t=i.renderStyles.width,e+=i.renderStyles.height):e+=i.renderStyles.height}),{width:t,height:e}}getElementBy(t,e){let i=[];return l(this,s=>{s.options.attrs[t]===e&&i.push(s)}),i}appendChild(t){return super.appendChild(t),this.getLayer().mountNode(this.root),t}prependChild(t){return super.prependChild(t),this.getLayer().onElementChange(t),t}removeChild(t){super.removeChild(t),t.removeEvent(),this.getLayer().onElementChange(t)}append(t){super.append(t),this.getLayer().onElementChange(t)}prepend(t){super.prepend(t),this.getLayer().onElementChange(t)}}class m extends f{constructor(t,e){super(t,e),this.type="view"}_getDefaultStyles(){return{...s.DEFAULT_STYLES,display:s.DISPLAY.BLOCK}}}class w extends f{constructor(t,e){super(t,e),this._layout=null,this._lines=[],this.children+="",this.type="text"}_getDefaultStyles(){return{...s.DEFAULT_STYLES,display:s.DISPLAY.INLINE_BLOCK,width:s.WIDTH.AUTO,textAlign:"left"}}_measureLayout(){return this._layout=this.getRender().measureText(this,this.children),this._layout.fontHeight=.8*this.renderStyles.fontSize,this._layout.height=this.renderStyles.lineHeight,this._calcLine(),this._layout}_getFont(){const{fontSize:t,fontWeight:e,fontFamily:i}=this.renderStyles;return`${e} ${t}px ${i}`}_calcLine(){if(!this.parent||!this.children)return;const{width:t,height:e}=this._layout;let{contentWidth:i}=this.parent.renderStyles;const{width:h}=this.parent.styles;if(r(this.styles.width)||(i=this.renderStyles.width),n(i)&&i>=t||h===s.WIDTH.AUTO)this._lines=[this.children];else{this._lines=[];let t=1,e="",s=null;for(let n=0;ni){if(t>=this.renderStyles.maxLine){e=e.substring(0,e.length-2)+"...";break}this._lines.push(e),e="",t+=1}e+=this.children[n]}this._layout.width=i,this._lines.push(e),this._layout.height=this._lines.length*this.renderStyles.lineHeight}}}class S extends m{constructor(t,e){super(t,e),this.type="image",this._imageInfo={width:0,height:0,sx:0,sy:0,swidth:0,sheight:0,dx:0,dy:0,dwidth:0,dheight:0},this.debugColor="blue",this._image=null,this._layout=null}init(){super.init(),this._loadImage()}_loadImage(){const{mode:t}=this.options.attrs;return new Promise((t,e)=>{this.getRender().getImageInstance(this.options.attrs.src).then(({info:e,image:i})=>{this._imageInfo=e,this._image=i,t(),this._layoutImage(),this.isVisible()&&this.getLayer().onElementChange(this),this.options.on&&this.options.on.load&&this.options.on.load(this)})})}_layoutImage(){const{contentWidth:t,contentHeight:e}=this.renderStyles,{mode:i}=this.options.attrs,{width:s,height:n}=this.styles,{width:h,height:o}=this._imageInfo;let l=t,d=e;!r(s)&&r(n)?(l=t,d=x(l,h,o)):!r(n)&&r(s)?(d=e,l=_(d,h,o)):r(s)&&r(n)?(l=h,d=o):"aspectFill"===i?l/d>h/o?(this._imageInfo.swidth=h,this._imageInfo.sheight=x(h,l,d),this._imageInfo.sx=0,this._imageInfo.sy=(o-this._imageInfo.sheight)/2):(this._imageInfo.sheight=o,this._imageInfo.swidth=_(o,t,e),this._imageInfo.sy=0,this._imageInfo.sx=(h-this._imageInfo.swidth)/2):"aspectFit"===i?l/d>h/o?(this._imageInfo.dwidth=_(e,h,o),this._imageInfo.dheight=e,this._imageInfo.dy=this.contentY,this._imageInfo.dx=(t-this._imageInfo.dwidth)/2+this.contentX):(this._imageInfo.dheight=x(t,h,o),this._imageInfo.dwidth=t,this._imageInfo.dx=this.contentX,this._imageInfo.dy=(e-this._imageInfo.dheight)/2+this.contentY):(l=t,d=e),this._layout={width:l,height:d}}_measureLayout(){return this._layout?this._layout:{width:this.renderStyles.width,height:this.renderStyles.height}}}function _(t,e,i){return t/i*e}function x(t,e,i){return t/e*i}class L{constructor({simulateClick:t=!0}){this.clickTree=new p,this.touchstartTree=new p,this.touchmoveTree=new p,this.touchendTree=new p,this.clickList=[],this.touchstartList=[],this.touchmoveList=[],this.touchendList=[],this.touchStartEvent=null,this.simulateClick=t}clear(){this.clickTree=new p,this.touchstartTree=new p,this.touchmoveTree=new p,this.touchendTree=new p,this.clickList=[],this.touchstartList=[],this.touchmoveList=[],this.touchendList=[]}click(t,e){let i=new C({x:t,y:e,type:"click"});this._emit(i)}touchstart(t,e){let i=new C({x:t,y:e,type:"touchstart"});this.touchStartEvent=i,this._emit(i)}touchmove(t,e){let i=new C({x:t,y:e,type:"touchmove"});this._emit(i)}touchend(t,e){let i=new C({x:t,y:e,type:"touchend"});this._emit(i),this.checkClick(i)}_emit(t){let e=[];switch(t.type){case"click":e=this.clickTree;break;case"touchstart":e=this.touchstartTree;break;case"touchmove":e=this.touchmoveTree;break;case"touchend":e=this.touchendTree}let i=[];l(e,(e,s,n)=>{e.element&&(this.isPointInElement(t.relativeX,t.relativeY,e.element)?(e.runCapture(t),i.unshift(e)):s())});for(let e=0;e=i.x,n=e>=i.y,r=t<=i.x+i.renderStyles.width,h=e<=i.y+i.renderStyles.height;return!!(s&&n&&r&&h)}removeElement(t){this.clickList=this.clickList.filter(e=>(e.element===t&&e.remove(),e.element!==t)),this.touchstartList=this.touchstartList.filter(e=>(e.element===t&&e.remove(),e.element!==t)),this.touchmoveList=this.touchmoveList.filter(e=>(e.element===t&&e.remove(),e.element!==t)),this.touchendList=this.touchendList.filter(e=>(e.element===t&&e.remove(),e.element!==t))}onClick(t,e,i=!1){this.addCallback(t,e,this.clickTree,this.clickList,i)}onTouchStart(t,e,i=!1){this.addCallback(t,e,this.touchstartTree,this.touchstartList,i)}onTouchMove(t,e,i=!1){this.addCallback(t,e,this.touchmoveTree,this.touchmoveList,i)}onTouchEnd(t,e,i=!1){this.addCallback(t,e,this.touchendTree,this.touchendList,i)}addCallback(t,e,i,s,n){let r=null,h=null;for(let t=s.length-1;t>=0;t--){if(e===s[t].element){r=s[t-1],h=s[t];break}if(d(e,(e,i)=>{e===s[t].element&&(r=s[t],i())}),r)break}h||(h=new b(e,t)),n?h.addCapture(t):h.addCallback(t),r?r.appendChild(h):i.appendChild(h),s.push(h)}checkClick(t){if(this.touchStartEvent&&this.simulateClick){let{x:e,y:i}=this.touchStartEvent,{x:s,y:n}=t,r=n*n+s*s-(i*i+e*e);r<5&&r>-5&&this.click(s,n)}}}class C{constructor({x:t,y:e,type:i}){this.x=t,this.y=e,this.relativeX=t,this.relativeY=e,this.type=i,this.cancelBubble=!1,this.currentTarget=null}stopPropagation(){this.cancelBubble=!0}}class b extends p{constructor(t){super(),this.element=t,this.callbackList=[],this.captureList=[]}addCallback(t){this.callbackList.push(t)}addCapture(t){this.captureList.push(t)}runCallback(t){this.callbackList.forEach(e=>e(t))}runCapture(t){this.captureList.forEach(e=>e(t))}}const T=Math.PI/2;class I{constructor(t){this.layer=t,this.imageBus={}}getCtx(){return this.layer.ctx}getLayer(){return this.layer}_restore(t){this.getCtx().save(),t(),this.getCtx().restore()}_path(t){this.getCtx().beginPath(),t(),this.getCtx().closePath()}paint(t){this.getCtx().save(),this._drawBackground(t),this._drawContent(t),this._drawBox(t),this.afterPaint(t)}afterPaint(t){t.hasChildren()&&"text"!==t.type||this.getCtx().restore(),this._helpParentRestoreCtx(t)}_helpParentRestoreCtx(t){if(t.isVisible()&&(!(e=t).parent||e.next||e.hasChildren())||!t.isVisible()&&t.next)return;var e;let i=t.parent;for(;i&&!i.next;)this.getCtx().restore(),i=i.parent;i&&i.next&&this.getCtx().restore()}topBorder({x:t,y:e,borderRadius:i,w:s,h:n}){this.getCtx().moveTo(t,e+i),i&&this.getCtx().arc(t+i,e+i,i,2*T,3*T),this.getCtx().lineTo(t+s-i,e)}rightBorder({x:t,y:e,borderRadius:i,w:s,h:n}){i&&this.getCtx().arc(t+s-i,e+i,i,3*T,4*T),this.getCtx().lineTo(t+s,e+n-i)}bottomBorder({x:t,y:e,borderRadius:i,w:s,h:n}){i&&this.getCtx().arc(t+s-i,e+n-i,i,0,T),this.getCtx().lineTo(t+i,e+n)}leftBorder({x:t,y:e,borderRadius:i,w:s,h:n}){i&&this.getCtx().arc(t+i,e+n-i,i,T,2*T),this.getCtx().lineTo(t,e+i)}_drawBox(t){if(!t.renderStyles.borderColor&&!t.renderStyles.shadowBlur)return;const{contentWidth:e,contentHeight:i,paddingLeft:s,paddingTop:n,borderStyle:r,paddingRight:h,paddingBottom:o,shadowBlur:l,shadowColor:d,backgroundColor:a,shadowOffsetX:g,shadowOffsetY:c,borderLeftWidth:y,borderRightWidth:p,borderTopWidth:u,borderBottomWidth:f}=t.renderStyles;let m=v(t),w=t.contentX-t.renderStyles.paddingLeft-y/2,S=t.contentY-t.renderStyles.paddingTop-u/2,_=e+s+h+(y+p)/2,x=i+n+o+(u+f)/2;this.getCtx().lineCap=t.renderStyles.lineCap,this.getCtx().strokeStyle=t.renderStyles.borderColor,r&&"solid"!==r&&(Array.isArray(r)?this.getCtx().setLineDash(r):this.getCtx().setLineDash([5,5]));const L=t=>{this.getCtx().lineWidth=t,this.getCtx().stroke()};this._restore(()=>{this._path(()=>{w=t.contentX-t.renderStyles.paddingLeft-y/2,S=t.contentY-t.renderStyles.paddingTop-u/2,_=e+s+h+(y+p)/2,x=i+n+o+(u+f)/2,t.renderStyles.borderTopWidth&&(this.topBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderTopWidth)),t.renderStyles.borderRightWidth&&(this.getCtx().moveTo(w+_-m,S),this.rightBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderRightWidth)),t.renderStyles.borderBottomWidth&&(this.getCtx().moveTo(w+_,S+x-m),this.bottomBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderBottomWidth)),t.renderStyles.borderLeftWidth&&(this.getCtx().moveTo(w+m,S+x),this.leftBorder({x:w,y:S,borderRadius:m,w:_,h:x}),L(t.renderStyles.borderLeftWidth))})})}_drawBackground(t){const{backgroundColor:e,contentWidth:i,contentHeight:s,shadowColor:r,shadowBlur:h,paddingLeft:o,paddingRight:l,paddingTop:d,paddingBottom:a,opacity:g,shadowOffsetX:c,shadowOffsetY:y,borderLeftWidth:p,borderRightWidth:u,borderTopWidth:f,borderBottomWidth:m}=t.renderStyles,w=this.getCtx();let S=v(t),_=t.contentX-t.renderStyles.paddingLeft-p/2,x=t.contentY-t.renderStyles.paddingTop-f/2,L=i+o+l+(p+u)/2,C=s+d+a+(f+m)/2;n(g)&&(w.globalAlpha=g),r&&h&&this._restore(()=>{this._path(()=>{this.topBorder({x:_,y:x,borderRadius:S,w:L,h:C}),this.rightBorder({x:_,y:x,borderRadius:S,w:L,h:C}),this.bottomBorder({x:_,y:x,borderRadius:S,w:L,h:C}),this.leftBorder({x:_,y:x,borderRadius:S,w:L,h:C})}),n(c)&&(this.getCtx().shadowOffsetX=c),n(y)&&(this.getCtx().shadowOffsetY=y),this.getCtx().shadowBlur=h,this.getCtx().shadowColor=r,this.getCtx().fillStyle=r,this.getCtx().fill()}),this._clip(t),e&&(this.getCtx().fillStyle=this._parseBackground(e,t),this.getCtx().fillRect(t.contentX-o,t.contentY-d,i+o+l,s+d+a)),this.getLayer().options&&this.getLayer().options.debug&&(this.getCtx().strokeStyle="green",this.getCtx().strokeRect(t.contentX,t.contentY,t.renderStyles.contentWidth,t.renderStyles.contentHeight))}_clip(t){if("hidden"!==t.renderStyles.overflow)return;const{contentWidth:e,contentHeight:i,paddingLeft:s,paddingTop:n,paddingRight:r,paddingBottom:h,shadowBlur:o,shadowColor:l,backgroundColor:d,borderLeftWidth:a,borderRightWidth:g,borderTopWidth:c,borderBottomWidth:y}=t.renderStyles;let p=v(t),u=t.contentX-t.renderStyles.paddingLeft-a,f=t.contentY-t.renderStyles.paddingTop-c,m=e+s+r+a+g,w=i+n+h+c+y;this._path(()=>{this.topBorder({x:u,y:f,borderRadius:p,w:m,h:w}),this.rightBorder({x:u,y:f,borderRadius:p,w:m,h:w}),this.bottomBorder({x:u,y:f,borderRadius:p,w:m,h:w}),this.leftBorder({x:u,y:f,borderRadius:p,w:m,h:w})}),this.getCtx().clip()}_parseBackground(t,e){if(Array.isArray(t)){const i=this.getCtx().createLinearGradient(e.contentX,e.contentY,e.renderStyles.contentWidth,e.renderStyles.contentHeight);for(let e=0;e{l=0===i&&h?o+h:o,this.getCtx().fillText(e,l,t.contentY+(n+t._layout.fontHeight)/2+n*i)})}measureText(t,e){let i=0;return this._restore(()=>{this.getCtx().font=t._getFont();const{width:s}=this.getCtx().measureText(e);i=s}),{width:i}}_drawImage(t){if(!t._image)return;const{contentWidth:e,contentHeight:i}=t.renderStyles,{mode:s}=t.options.attrs,{sx:n,sy:r,swidth:h,sheight:o,dx:l,dy:d,dwidth:a,dheight:g,width:c,height:y}=t._imageInfo;"aspectFill"===s?this.getCtx().drawImage(t._image,n,r,h,o,t.contentX,t.contentY,e,i):"aspectFit"===s?this.getCtx().drawImage(t._image,0,0,c,y,l,d,a,g):this.getCtx().drawImage(t._image,t.contentX,t.contentY,e,i)}_drawScroll(t){this.getCtx().translate(t.currentScrollX,t.currentScrollY)}getImageInstance(t){let e=null;if(this.imageBus[t])e=this.imageBus[t];else{if(a()){if(!this.getLayer().options.canvas)throw Error("微信小程序中需要在options中设置canvas以创建图片");e=this.getLayer().options.canvas.createImage()}else e=new Image;t&&(this.imageBus[t]=new Promise((t,i)=>{e.onload=function(i){t({image:e,info:{width:i.target.width,height:i.target.height}})}})),e.src=t}return this.imageBus[t]}render(t){t.parent?this.getCtx().clearRect(t.x,t.y,t.renderStyles.width,t.renderStyles.height):this.getCtx().clearRect(0,0,this.getLayer().options.width,this.getLayer().options.height),l(t,(t,e,i)=>{t.isVisible()?this.paint(t):(i(),this._helpParentRestoreCtx(t))}),a()&&this.getCtx().draw&&this.getCtx().draw()}}function v(t){const{contentWidth:e,contentHeight:i}=t.renderStyles;let{borderRadius:s}=t.renderStyles;return 2*s>e&&(s=e/2),2*s>i&&(s=i/2),s<0&&(s=0),s}class B{constructor(t,e){this.ctx=t,this.node=null,this.isAnimate=!1,this.nodeList=[],this.p2cList=[],this.c2pList=[],this.renderList=[],this.options=e,this.eventManager=new L(e),this.render=new I(this)}update(t,e){this.ctx=t,this.options=e,this.options.renderStyles=e,this.node.container=this.options}mountNode(t){this.node=t,this.node.root=this.node,this.node.layer=this,this.node.container=this.options,this.eventManager.clear(),this.initRender()}initRender(){const t=Date.now();p.connectChildren(this.node),this.p2cList=this.getP2CList(this.node),this.c2pList=function(t){var e=[];if(null!=t){var i=[];for(i.unshift(t);0!=i.length;){var s=i.shift();e.push(s._generateRender());for(var n=s._getChildren(),r=n.length-1;r>=0;r--)i.push(n[r]._generateRender())}}return e}(this.node).reverse(),this.initNode(),this.flow(),this.repaint(),console.log(`渲染${this.p2cList.length}个元素 耗时 ${Date.now()-t} ms`)}getP2CList(t){return function(t){var e=[];if(null!=t){var i=[];for(i.unshift(t);0!=i.length;){var s=i.shift();e.push(s._generateRender());for(var n=s._getChildren(),r=0;r{t._initWidthHeight()});for(let t=0;tthis._animate())}animate(){this.isAnimate=!0,window.requestAnimationFrame(()=>this._animate())}stopAnimate(){this.isAnimate=!1}}class W extends m{constructor(t,e){return super(t,e),t.styles.overflow="hidden",this.type="scroll-view",this._scrollView=new m(t,[this]),this._scrollView.type="scroll-view-container",this.visibleIndex=null,this.renderOnDemand=t.attrs&&t.attrs.renderOnDemand||!1,this._scrollView}_getDefaultStyles(){return{...s.DEFAULT_STYLES,direction:"y"}}beforePaint(){this.initChildrenVisible()}init(){super.init(),this.addEventListener();const{height:t,width:e,direction:i}=this.styles;i.match("y")&&(r(t)?console.error("scroll-view 必须设置明确的高度"):(this.styles.height="auto",this.renderStyles.height="auto")),i.match("x")&&(r(e)?console.error("scroll-view 必须设置明确的宽度"):(this.styles.width="auto",this.renderStyles.width="auto"))}addEventListener(){this.currentScrollX=0,this.currentScrollY=0;let t=this.styles.direction,e=0,i=0,s=0,n=0,r=!1,h=0,o=0,l=0,d=0,a=null,g=1,c=1;this.getLayer().eventManager.onClick(e=>{t.match("y")&&(e.relativeY-=this.currentScrollY),t.match("x")&&(e.relativeX-=this.currentScrollX)},this._scrollView,!0),this.getLayer().eventManager.onTouchStart(t=>{t.stopPropagation(),e=t.x,i=t.y,s=e,n=i,r=!0,clearInterval(a)},this._scrollView),this.getLayer().eventManager.onTouchMove(t=>{r&&(t.stopPropagation(),h=t.x-e,o=t.y-i,this.scrollBy(h,o)&&(s=e,n=i,e=t.x,i=t.y))},this._scrollView),this.getLayer().eventManager.onTouchEnd(t=>{r&&(r=!1,l=t.x-s,d=t.y-n,g=.02*-l,c=.02*-d,clearInterval(a),a=setInterval(()=>{this.scrollBy(l,d)||clearInterval(a),l+=g,d+=c,l*l<=.05&&d*d<=.05&&(l=0,d=0,clearInterval(a))},17))},this._scrollView)}calcScrollBoundX(t){const{contentWidth:e,contentHeight:i}=this._scrollView.renderStyles,{width:s,height:n,direction:r}=this.renderStyles;if(r.match("x")){if(e-this.currentScrollX-t>s)return!1;if(this.currentScrollX+t>0)return!1}return!0}calcScrollBoundY(t){const{contentWidth:e,contentHeight:i}=this._scrollView.renderStyles,{width:s,height:n,direction:r}=this.renderStyles;if(r.match("y")){if(i-this.currentScrollY-t>n)return!1;if(this.currentScrollY+t>0)return!1}return!0}scrollByX(t){return!!this.renderStyles.direction.match("x")&&(!!this.calcScrollBoundX(t)&&(this.currentScrollX+=t,!0))}scrollByY(t){return!!this.renderStyles.direction.match("y")&&(!!this.calcScrollBoundY(t)&&(this.currentScrollY+=t,this.calcChildrenVisible(),!0))}scrollBy(t,e){return!!(this.scrollByX(t)|this.scrollByY(e))&&(this.getLayer().repaint(this._scrollView),!0)}scrollTo(t){}initChildrenVisible(){if(!this.renderOnDemand)return;const t=this._getChildrenInFlow();for(let e=0;e=0;e--){if(this.isElementInViewport(t[e])){this.visibleIndex[1]=e;break}t[e].visible=!1}for(let e=this.visibleIndex[0];e<=this.visibleIndex[1];e++)t[e].visible=!0}calcChildrenVisible(){if(!this.renderOnDemand)return;const t=this._getChildrenInFlow(),e=E(this.visibleIndex[0],5),i=E(this.visibleIndex[1],5);let s=[];for(let i=e[0];i<=e[e.length-1];i++)t[i]&&(this.isElementInViewport(t[i])?(t[i].visible=!0,s.length||s.push(i)):t[i].visible=!1);for(let e=i[i.length-1];e>=i[0];e--)t[e]&&(this.isElementInViewport(t[e])?(t[e].visible=!0,1===s.length&&s.push(e)):t[e].visible=!1);this.visibleIndex=s}isElementInViewport(t){return!this.styles.direction.match("y")||t.y+t.renderStyles.height+this.currentScrollY>this._scrollView.contentY&&t.y+this.currentScrollYnew m(t,e)),R("text",(t,e)=>new w(t,e)),R("image",(t,e)=>new S(t,e)),R("scroll-view",(t,e)=>new W(t,e)),R("scrollview",(t,e)=>new W(t,e));return{createLayer:function(t,e){return new B(t,e)},createElement:function(t){return t((function t(e,i={},s=[]){let n=null,r=s;if(!k[e])throw Error(`Unknown tag name [${e}] !`);return n=k[e](i,r,t),n}))},component:R,View:m,Text:w,Image:S,Layer:B,ScrollView:W}})); diff --git a/example/draw.js b/example/draw.js index 943bad9..ff9b502 100644 --- a/example/draw.js +++ b/example/draw.js @@ -159,7 +159,7 @@ function drawButton(h, text = 'text', options = {}) { paddingLeft: 10, paddingRight: 10, lineHeight: 16, - verticalAlign: 'middle' + verticalAlign: 'middle', }, on: { click(e) { @@ -556,17 +556,12 @@ function drawTicket(h) { } function Dialog(h, options) { - return h('view', { + return h('view', Object.assign({ attrs: { className: 'dialog' }, styles: { position: 'absolute', top: 0, left: 0, width: window.innerWidth, height: window.innerHeight, backgroundColor: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }, - on: { - click() { - console.log('outer') - } - } - }, [ + }, options), [ h('view', { styles: { width: 300, diff --git a/lib/element.js b/lib/element.js index b5e2555..c903fdd 100644 --- a/lib/element.js +++ b/lib/element.js @@ -373,24 +373,24 @@ export default class Element extends TreeNode { // prependChild(element) { super.prependChild(element) - this.getLayer().mountNode(this.root) + this.getLayer().onElementChange(element) return element } removeChild(element) { super.removeChild(element) element.removeEvent() - this.getLayer().mountNode(this.root) + this.getLayer().onElementChange(element) } append(element) { super.append(element) - this.getLayer().mountNode(this.root) + this.getLayer().onElementChange(element) } prepend(element) { super.prepend(element) - this.getLayer().mountNode(this.root) + this.getLayer().onElementChange(element) } }