diff --git a/dist/easy-canvas.min.js b/dist/easy-canvas.min.js index 3ee39e2..56b1fb1 100644 --- a/dist/easy-canvas.min.js +++ b/dist/easy-canvas.min.js @@ -1 +1,2 @@ -!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:"sans-serif",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,position:"static"},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){if(!t)return;let i=t,s=!1;const n=()=>{s=!0};for(;i.parent&&(e(i.parent,n),!s);)i=i.parent}function a(){try{return Boolean(wx.getSystemInfoSync)}catch(t){return!1}}function g(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=0;r--)i.push(n[r]._generateRender())}}return e.reverse()}const y=["attrs","styles","on"];function p(t){return.5+t<<0}class u{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&&"inline-block"===t.next.renderStyles.display||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 f={[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 m extends u{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=f[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[this.key.width])?this.exactValue+=t.renderStyles[this.key.width]:n(t.styles.flex)&&(this.flexTotal+=t.renderStyles.flex),this.elements.push(t),t.line=this,this.refreshWidthHeight(t),t.next||this.closeLine()}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 S{static connectChildren(t){t.hasChildren()&&(t.children=t.children.filter(t=>t instanceof S),t._getChildren().map((e,i)=>{e._setParent(t),e._setSibling(t._getChildren()[i-1],t._getChildren()[i+1]),S.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 S)throw Error("Unknown treeNode type");const e=this._getChildren()[this._getChildren().length-1];e&&e._setSibling(e.pre,t),this.children.push(t),t._setParent(this),t._setSibling(e,null)}prependChild(t){if(!t instanceof S)throw Error("Unknown treeNode type");const e=this._getChildren()[0];e&&e._setSibling(t,e.next),this.children.unshift(t),t._setParent(this),t._setSibling(null,e)}removeChild(t){if(!t instanceof S)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 S)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 S)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 x(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 w extends S{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(){this.options.on&&Object.keys(this.options.on).forEach(t=>{this.getLayer().eventManager.EVENTS.includes(t)&&this.getLayer().eventManager.addEventListener(t,this.options.on[t],this)})}removeEvent(){this.getLayer().eventManager.removeElement(this)}getLayer(){return this.root.layer}getRender(){return this.root.layer.render}_paint(){}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.paddingWidth=0:h(t.width)?t.paddingWidth=o(t.width)*e-t.marginLeft-t.marginRight:t.paddingWidth=t.width,r(t.height)?t.paddingHeight=0:h(t.height)?t.paddingHeight=o(t.height)*i-t.marginTop-t.marginBottom:t.paddingHeight=t.height,t.paddingWidth||(t.paddingWidth=0),t.paddingHeight||(t.paddingHeight=0),t.contentWidth=t.paddingWidth-t.paddingLeft-t.paddingRight,t.contentHeight=t.paddingHeight-t.paddingTop-t.paddingBottom,t.width=t.paddingWidth+t.marginLeft+t.marginRight+this._getTotalBorderWidth(t),t.height=t.paddingHeight+t.marginTop+t.marginBottom+this._getTotalBorderHeight(t),this.renderStyles=t,this._InFlexBox()?this._bindFlexBox():this.isInFlow()||(this.relativeTo=function(t){if(t.isInFlow())return t.parent;if("fixed"===t.renderStyles.position)return t.root;let e=null;return d(t,t=>{"static"===t.renderStyles.position||e||(e=t)}),e||(e=t.root),e}(this))}_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(){x(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=p(i.width)),r(e)&&(this.renderStyles.contentHeight=p(i.height))}this._refreshLayoutWithContent(),this._InFlexBox()?this.line.refreshWidthHeight(this):i===s.DISPLAY.INLINE_BLOCK&&this._bindLine()}_initPosition(){let{contentX:t}=this._getContainerLayout();const{paddingLeft:e,paddingTop:i,borderLeftWidth:r,borderTopWidth:l,marginLeft:d,marginTop:a}=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{contentX:t,contentY:e,contentWidth:i,contentHeight:s}=this._getContainerLayout(this.relativeTo),{top:r,bottom:l,right:d,left:a,width:g,height:c}=this.renderStyles;h(r)&&(r=o(r)*s),h(l)&&(l=o(l)*s),h(a)&&(a=o(a)*i),h(d)&&(d=o(d)*i),n(r)?this.y=e+r:n(l)&&(this.y=e+s-l-c),n(a)?this.x=t+a:n(d)&&(this.x=t+i-d-g)}this.x=p(this.x),this.y=p(this.y),this.contentX=this.x+e+r+d,this.contentY=this.y+i+l+a}_InFlexBox(){return!!this.isInFlow()&&(!!this.parent&&(!(!this.parent||this.parent.renderStyles.display!==s.DISPLAY.FLEX)||void 0))}_refreshLayoutWithContent(){this.renderStyles.height=p(this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom+this.renderStyles.marginTop+this.renderStyles.marginBottom+this._getTotalBorderHeight()),this.renderStyles.width=p(this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight+this.renderStyles.marginLeft+this.renderStyles.marginRight+this._getTotalBorderWidth()),this.renderStyles.paddingWidth=p(this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight),this.renderStyles.paddingHeight=p(this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom)}_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(),this.renderStyles.paddingWidth=p(this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight),this.renderStyles.paddingHeight=p(this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom)}_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 u).bind(this)}_bindFlexBox(){this.pre&&this.pre.line?this.pre.line.add(this):(new m).bind(this)}_getContainerLayout(t=this.parent){return t||(this.container,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().onElementAdd(t),t}prependChild(t){return super.prependChild(t),this.getLayer().onElementAdd(t),t}removeChild(t){super.removeChild(t),this.getLayer().onElementRemove(t)}append(t){super.append(t),this.getLayer().onElementAdd(t)}prepend(t){super.prepend(t),this.getLayer().onElementAdd(t)}setStyles(t){let e=!1;Object.keys(t).forEach(i=>{["width","height","position","display","padding","paddingTop","paddingLeft","paddingBottom","paddingRight","margin","marginLeft","marginTop","marginBottom","marginRight","borderWidth","flexDirection","justifyContent","alignItems","textAlign","left","top","right","bottom"].includes(i)?e=!0:this.renderStyles[i]=t[i]}),e?(Object.keys(t).forEach(e=>{this.options.styles[e]=t[e]}),this.getLayer().reflowElement(this,this)):this.getRender().requestRepaint()}}class _ extends w{constructor(t,e){super(t,e),this.type="view"}_getDefaultStyles(){return{...s.DEFAULT_STYLES,display:s.DISPLAY.BLOCK}}_paint(){this.getRender()._drawBackground(this),this.getRender()._drawBox(this)}}class L extends w{constructor(t,e){super(t,e),this._layout=null,this._lines=[],this.children+="",this.type="text",this.debugColor="blue"}_paint(){this.getRender()._drawBackground(this),this.getRender()._drawText(this),this.getRender()._drawBox(this)}_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.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=[{text:this.children,layout:this._layout}];else{this._lines=[];let t=1,e="",s=null,n=null;for(let r=0;ri){if(t>=this.renderStyles.maxLine){e=e.substring(0,e.length-2)+"...";break}this._lines.push({text:e,layout:n||s}),e="",t+=1}e+=this.children[r],n=s}this._layout.width=i,this._lines.push({text:e,layout:this.getRender().measureText(this,e)}),this._layout.height=this._lines.length*this.renderStyles.lineHeight}}getInnerText(){return this.children}setInnerText(t){void 0!==t&&t!==this.children&&(this.children=t,this.getLayer().reflowElement(this))}}class C extends _{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.options&&this.options.attrs&&this.options.attrs.timeout?setTimeout(()=>{this._loadImage()},this.options.attrs.timeout||0):this._loadImage()}_paint(){this.getRender()._drawBackground(this),this.getRender()._drawImage(this),this.getRender()._drawBox(this)}_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().reflowElement(this),this.options.on&&this.options.on.load&&this.options.on.load(this)}).catch(t=>{this.options.on&&this.options.on.error&&this.options.on.error(t)})})}_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=T(l,h,o)):!r(n)&&r(s)?(d=e,l=b(d,h,o)):r(s)&&r(n)?(l=h,d=o):"aspectFill"===i?l/d>h/o?(this._imageInfo.swidth=h,this._imageInfo.sheight=T(h,l,d),this._imageInfo.sx=0,this._imageInfo.sy=(o-this._imageInfo.sheight)/2):(this._imageInfo.sheight=o,this._imageInfo.swidth=b(o,t,e),this._imageInfo.sy=0,this._imageInfo.sx=(h-this._imageInfo.swidth)/2):"aspectFit"===i?l/d>h/o?(this._imageInfo.dwidth=b(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=T(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 b(t,e,i){return t/i*e}function T(t,e,i){return t/e*i}const I=["click","touchstart","touchmove","touchend","mousewheel"];class E{constructor({simulateClick:t=!0}){this.EVENTS=I,this.clear(),this.touchStartEvent=null,this.simulateClick=t}clear(){I.forEach(t=>{this[t+"Tree"]=new S,this[t+"List"]=[]})}click(t,e){let i=new v({x:t,y:e,type:"click"});this._emit(i)}touchstart(t,e){let i=new v({x:t,y:e,type:"touchstart"});this.touchStartEvent=i,this._emit(i)}touchmove(t,e){let i=new v({x:t,y:e,type:"touchmove"});this._emit(i)}touchend(t,e){let i=new v({x:t,y:e,type:"touchend"});this._emit(i),this.checkClick(i)}mousewheel(t,e,i,s){let n=new v({x:t,y:e,deltaX:i,deltaY:s,type:"mousewheel"});this._emit(n)}_emit(t){let e=this[t.type+"Tree"];if(!e)return;let i=[],s=e._getChildren();for(;s.length;)W(s,(e,n,r)=>{e.element.isVisible()&&this.isPointInElement(t.relativeX,t.relativeY,e.element)?(e.runCapture(t),i.unshift(e),n(),s=e._getChildren()):r&&(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){I.forEach(e=>{this[e+"List"]=this[e+"List"].filter(e=>(e.element===t&&e.remove(),e.element!==t))})}addEventListener(t,e,i,s){const n=this[t+"Tree"],r=this[t+"List"];n||console.error("Unknown event name ["+t+"]"),this.addCallback(e,i,n,r,s)}addCallback(t,e,i,s,n){let r=null,h=null,o=e;for(let t=s.length-1;t>=0;t--){if(e===s[t].element){r=s[t-1],h=s[t];break}if(!e.isInFlow()&&(o=e.relativeTo.parent,!o))break;if(d(o,(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.prependChild(h):i.prependChild(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 v{constructor({x:t,y:e,type:i,deltaX:s,deltaY:n}){this.x=t,this.y=e,this.relativeX=t,this.relativeY=e,this.type=i,this.cancelBubble=!1,this.currentTarget=null,"mousewheel"===i&&(this.deltaX=s,this.deltaY=n)}stopPropagation(){this.cancelBubble=!0}}class B extends S{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.call(this.element,t))}runCapture(t){this.captureList.forEach(e=>e.call(this.element,t))}}function W(t,e){let i=!1;const s=()=>i=!0;for(let n=0;n{this.getCtx().lineWidth=t,this.getCtx().stroke()};this._restore(()=>{this._path(()=>{t.renderStyles.borderTopWidth&&(this.topBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderTopWidth/2:0,w:_,h:L}),!m&&C(t.renderStyles.borderTopWidth)),t.renderStyles.borderRightWidth&&(this.getCtx().moveTo(x+_-S-(S?t.renderStyles.borderTopWidth/2:0),w),this.rightBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderRightWidth/2:0,w:_,h:L}),!m&&C(t.renderStyles.borderRightWidth)),t.renderStyles.borderBottomWidth&&(this.getCtx().moveTo(x+_,w+L-S-(S?t.renderStyles.borderRightWidth/2:0)),this.bottomBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderBottomWidth/2:0,w:_,h:L}),!m&&C(t.renderStyles.borderBottomWidth)),t.renderStyles.borderLeftWidth&&(this.getCtx().moveTo(x+S+(S?t.renderStyles.borderBottomWidth/2:0),w+L),this.leftBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderLeftWidth/2:0,w:_,h:L}),C(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,S=this.getCtx();let x=X(t),w=t.contentX-t.renderStyles.paddingLeft-p,_=t.contentY-t.renderStyles.paddingTop-f,L=i+o+l+(p+u),C=s+d+a+(f+m);n(g)&&(S.globalAlpha=g),r&&h&&this._restore(()=>{this._path(()=>{this.topBorder({x:w,y:_,borderRadius:x,w:L,h:C}),this.rightBorder({x:w,y:_,borderRadius:x,w:L,h:C}),this.bottomBorder({x:w,y:_,borderRadius:x,w:L,h:C}),this.leftBorder({x:w,y:_,borderRadius:x,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.isDebug()&&(this.getCtx().strokeStyle=t.debugColor||"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=X(t),u=t.contentX-t.renderStyles.paddingLeft-a,f=t.contentY-t.renderStyles.paddingTop-c,m=e+s+r+a+g,S=i+n+h+c+y;this._path(()=>{this.topBorder({x:u,y:f,borderRadius:p,w:m,h:S}),this.rightBorder({x:u,y:f,borderRadius:p,w:m,h:S}),this.bottomBorder({x:u,y:f,borderRadius:p,w:m,h:S}),this.leftBorder({x:u,y:f,borderRadius:p,w:m,h:S})}),this.getCtx().clip()}_parseBackground(t,e){if(Array.isArray(t)){const i=this.getCtx().createLinearGradient(e.contentX,e.contentY,e.contentX+e.renderStyles.contentWidth,e.contentY+e.renderStyles.contentHeight);for(let e=0;e{if(d=0===s&&h?l+h:l,g=t.contentY+n/2+n*s+.5,this.isDebug()&&this.getCtx().fillRect(d,g,2,2),this.getCtx().fillText(i.text,d,g),a()&&400!==t.renderStyles.fontWeight){const e=.001*t.renderStyles.fontSize;this.getCtx().fillText(i.text,d-e,g)}if(o){const s=o[0];g+=1,this._restore(()=>{this._path(()=>{let e=g;"underline"===s?e=g+t._layout.fontHeight/2:"line-through"===s&&(e=g),this.getCtx().moveTo(d,e),this.getCtx().lineTo(d+i.layout.width,e)}),this.getCtx().strokeStyle=e,this.getCtx().stroke()})}})}measureText(t,e){let i=0,s=0;return this._restore(()=>{this.getCtx().font=t._getFont();const{width:n,actualBoundingBoxAscent:r}=this.getCtx().measureText(e);i=n,s=r||.7*t.renderStyles.fontSize}),{width:i,fontHeight:s+1}}_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;return this.imageBus[t]?e=this.imageBus[t]:(a()?this.getCanvas()?e=this.getCanvas().createImage():(console.warn("小程序请使用设置canvas参数以创建图片"),e=function(t){const e={onload:()=>{}};return new Promise((e,i)=>{wx.downloadFile({url:t,success(t){wx.getImageInfo({src:t.tempFilePath,success(i){e({target:{width:i.width,height:i.height},image:t.tempFilePath})}})},fail(t){i(t)}})}).then(t=>{e.onload(t)}).catch(t=>{}),e}(t)):e=new Image,t&&(this.imageBus[t]=new Promise((t,i)=>{e.onload=i=>{t({image:a()&&!this.getCanvas()?i.image:e,info:{width:a()?e.width:i.target.width,height:a()?e.height:i.target.height}})},e.onerror=t=>{i(t)}})),e.src=t),this.imageBus[t]}render(t){this.lastFrameComplete=!1,this.lastPaintTime=Date.now(),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(),this.lastFrameComplete=!0}renderFPS(){}readyToRender(t){this.element=t;const e=this.getLayer().options;this.lastPaintTime=Date.now(),e&&e.animate?this.animate():this.render(this.element)}requestRepaint(t){this.isAnimate||this.render(this.element)}getCanvas(){const t=this.getLayer().options;return t&&t.canvas||null}_animate(t){const e=Date.now();this.render(this.element),this.isAnimate&&window.requestAnimationFrame(()=>this._animate(e))}animate(){this.isAnimate=!0,window.requestAnimationFrame(()=>this._animate())}stopAnimate(){this.isAnimate=!1}onEffectFinished(){const t=Object.keys(this.imageBus).map(t=>this.imageBus[t]);return Promise.all(t)}}function X(t){const{paddingWidth:e,paddingHeight: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),p(s)}class A{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 E(e),this.render=new k(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();S.connectChildren(this.node),this.initP2CList(),this.initC2PList(),this.flow(),this.render.onEffectFinished().then(t=>this.lifecycle("onEffectSuccess",t)).catch(t=>this.lifecycle("onEffectFail",t)),this.repaint(),console.log(`渲染${this.p2cList.length}个元素 耗时 ${Date.now()-t} ms`)}initP2CList(){this.p2cList=g(this.node)}initC2PList(){this.c2pList=c(this.node)}flow(t=this.node){for(let t=0;tt.init()),this.reflowElement(t)}onElementChange(t){d(t,(t,e)=>{t._initWidthHeight(),"scroll-view"===t.type&&e()});for(let t=0;t{this.getLayer().eventManager.addEventListener(e,e=>{t.match("y")&&(e.relativeY-=this.currentScrollY),t.match("x")&&(e.relativeX-=this.currentScrollX)},this._scrollView,!0)}),this.getLayer().eventManager.addEventListener("mousewheel",t=>{this.scrollBy(t.deltaX,t.deltaY)?t.stopPropagation():this.scrollTo({x:t.deltaX<=0?this.maxScrollX:0,y:t.deltaY<=0?this.maxScrollY:0})},this._scrollView),this.getLayer().eventManager.addEventListener("touchstart",t=>{t.stopPropagation(),e=t.x,i=t.y,s=e,n=i,r=!0,clearInterval(a)},this._scrollView),this.getLayer().eventManager.addEventListener("touchmove",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.addEventListener("touchend",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)||(this.scrollTo(this.currentScrollX+l,this.currentScrollY+d),clearInterval(a)),l+=g,d+=c,l*l<=.05&&d*d<=.05&&(l=0,d=0,clearInterval(a))},16))},this._scrollView)}initScroll(){const{contentWidth:t,contentHeight:e}=this._scrollView.renderStyles,{width:i,height:s,direction:n}=this.renderStyles;this.maxScrollX=i-t,this.maxScrollY=s-e}calcScrollBoundX(t){return!(-this.currentScrollX-t>this.maxScrollX)&&!(this.currentScrollX+t>0)}calcScrollBoundY(t){return!(-this.currentScrollY-t>this.maxScrollY)&&!(this.currentScrollY+t>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+=p(t),this.calcChildrenVisible(),!0))}scrollBy(t,e){return!!(this.scrollByX(t)|this.scrollByY(e))&&(this.getRender().requestRepaint(this._scrollView),!0)}scrollTo({x:t,y:e}){n(t)&&this.maxScrollX>0&&((t=t)>this.maxScrollX&&(t=this.maxScrollX),this.currentScrollX=-p(t)),n(e)&&this.maxScrollY>0&&((e=e)>this.maxScrollY&&(e=this.maxScrollY),this.currentScrollY=-p(e)),this.initChildrenVisible(),this.getRender().requestRepaint(this._scrollView)}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=H(this.visibleIndex[0],5),i=H(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,this.visibleIndex.length<2&&this.initChildrenVisible()}isElementInViewport(t){return!this.styles.direction.match("y")||t.y+t.renderStyles.height+this.currentScrollY>this._scrollView.contentY&&t.y+this.currentScrollYnew _(t,e)),F("text",(t,e)=>new L(t,e)),F("image",(t,e)=>new C(t,e)),F("scroll-view",(t,e)=>new P(t,e)),F("scrollview",(t,e)=>new P(t,e));return{createLayer:function(t,e){return new A(t,e)},createElement:function(t){return t((function t(e,i={},s=[]){let n=null,r=s;if(!Y[e])throw Error(`Unknown tag name [${e}] !`);if("string"==typeof s&&"text"!==e)r=[new L({},s)];else if(!Array.isArray(s)&&"text"!==e)throw Error(`Element [${e}]:Children must be type of Array!`);return n=Y[e](i,r,t),n}))},component:F,View:_,Text:L,Image:C,Layer:A,ScrollView:P,mergeOptions:function(t,e){let i={};return y.forEach(s=>{t[s]||(t[s]={}),e[s]||(e[s]={}),i[s]=Object.assign({},t[s],i[s])}),i}}})); +!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:"sans-serif",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,position:"static"},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){if(!t)return;let i=t,s=!1;const n=()=>{s=!0};for(;i.parent&&(e(i.parent,n),!s);)i=i.parent}function a(){try{return Boolean(wx.getSystemInfoSync)}catch(t){return!1}}function g(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=0;r--)i.push(n[r]._generateRender())}}return e.reverse()}const y=["attrs","styles","on"];function p(t){return.5+t<<0}class u{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&&"inline-block"===t.next.renderStyles.display||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 f={[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 m extends u{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=f[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[this.key.width])?this.exactValue+=t.renderStyles[this.key.width]:n(t.styles.flex)&&(this.flexTotal+=t.renderStyles.flex),this.elements.push(t),t.line=this,this.refreshWidthHeight(t),t.next||this.closeLine()}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 S{static connectChildren(t){t.hasChildren()&&(t.children=t.children.filter(t=>t instanceof S),t._getChildren().map((e,i)=>{e._setParent(t),e._setSibling(t._getChildren()[i-1],t._getChildren()[i+1]),S.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 S)throw Error("Unknown treeNode type");const e=this._getChildren()[this._getChildren().length-1];e&&e._setSibling(e.pre,t),this.children.push(t),t._setParent(this),t._setSibling(e,null)}prependChild(t){if(!t instanceof S)throw Error("Unknown treeNode type");const e=this._getChildren()[0];e&&e._setSibling(t,e.next),this.children.unshift(t),t._setParent(this),t._setSibling(null,e)}removeChild(t){if(!t instanceof S)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 S)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 S)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 x(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 w extends S{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(){this.options.on&&Object.keys(this.options.on).forEach(t=>{this.getLayer().eventManager.EVENTS.includes(t)&&this.getLayer().eventManager.addEventListener(t,this.options.on[t],this)})}removeEvent(){this.getLayer().eventManager.removeElement(this)}getLayer(){return this.root.layer}getRender(){return this.root.layer.render}_paint(){}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.paddingWidth=0:h(t.width)?t.paddingWidth=o(t.width)*e-t.marginLeft-t.marginRight:t.paddingWidth=t.width,r(t.height)?t.paddingHeight=0:h(t.height)?t.paddingHeight=o(t.height)*i-t.marginTop-t.marginBottom:t.paddingHeight=t.height,t.paddingWidth||(t.paddingWidth=0),t.paddingHeight||(t.paddingHeight=0),t.contentWidth=t.paddingWidth-t.paddingLeft-t.paddingRight,t.contentHeight=t.paddingHeight-t.paddingTop-t.paddingBottom,t.width=t.paddingWidth+t.marginLeft+t.marginRight+this._getTotalBorderWidth(t),t.height=t.paddingHeight+t.marginTop+t.marginBottom+this._getTotalBorderHeight(t),this.renderStyles=t,this._InFlexBox()?this._bindFlexBox():this.isInFlow()||(this.relativeTo=function(t){if(t.isInFlow())return t.parent;if("fixed"===t.renderStyles.position)return t.root;let e=null;return d(t,t=>{"static"===t.renderStyles.position||e||(e=t)}),e||(e=t.root),e}(this))}_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(){x(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=p(i.width)),r(e)&&(this.renderStyles.contentHeight=p(i.height))}this._refreshLayoutWithContent(),this._InFlexBox()?this.line.refreshWidthHeight(this):i===s.DISPLAY.INLINE_BLOCK&&this._bindLine()}_initPosition(){let{contentX:t}=this._getContainerLayout();const{paddingLeft:e,paddingTop:i,borderLeftWidth:r,borderTopWidth:l,marginLeft:d,marginTop:a}=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{contentX:t,contentY:e,contentWidth:i,contentHeight:s}=this._getContainerLayout(this.relativeTo),{top:r,bottom:l,right:d,left:a,width:g,height:c}=this.renderStyles;h(r)&&(r=o(r)*s),h(l)&&(l=o(l)*s),h(a)&&(a=o(a)*i),h(d)&&(d=o(d)*i),n(r)?this.y=e+r:n(l)&&(this.y=e+s-l-c),n(a)?this.x=t+a:n(d)&&(this.x=t+i-d-g)}this.x=p(this.x),this.y=p(this.y),this.contentX=this.x+e+r+d,this.contentY=this.y+i+l+a}_InFlexBox(){return!!this.isInFlow()&&(!!this.parent&&(!(!this.parent||this.parent.renderStyles.display!==s.DISPLAY.FLEX)||void 0))}_refreshLayoutWithContent(){this.renderStyles.height=p(this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom+this.renderStyles.marginTop+this.renderStyles.marginBottom+this._getTotalBorderHeight()),this.renderStyles.width=p(this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight+this.renderStyles.marginLeft+this.renderStyles.marginRight+this._getTotalBorderWidth()),this.renderStyles.paddingWidth=p(this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight),this.renderStyles.paddingHeight=p(this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom)}_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(),this.renderStyles.paddingWidth=p(this.renderStyles.contentWidth+this.renderStyles.paddingLeft+this.renderStyles.paddingRight),this.renderStyles.paddingHeight=p(this.renderStyles.contentHeight+this.renderStyles.paddingTop+this.renderStyles.paddingBottom)}_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 u).bind(this)}_bindFlexBox(){this.pre&&this.pre.line?this.pre.line.add(this):(new m).bind(this)}_getContainerLayout(t=this.parent){return t||(this.container,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().onElementAdd(t),t}prependChild(t){return super.prependChild(t),this.getLayer().onElementAdd(t),t}removeChild(t){super.removeChild(t),this.getLayer().onElementRemove(t)}append(t){super.append(t),this.getLayer().onElementAdd(t)}prepend(t){super.prepend(t),this.getLayer().onElementAdd(t)}setStyles(t){let e=!1;Object.keys(t).forEach(i=>{["width","height","position","display","padding","paddingTop","paddingLeft","paddingBottom","paddingRight","margin","marginLeft","marginTop","marginBottom","marginRight","borderWidth","flexDirection","justifyContent","alignItems","textAlign","left","top","right","bottom"].includes(i)?e=!0:this.renderStyles[i]=t[i]}),e?(Object.keys(t).forEach(e=>{this.options.styles[e]=t[e]}),this.getLayer().reflowElement(this,this)):this.getRender().requestRepaint()}}class _ extends w{constructor(t,e){super(t,e),this.type="view"}_getDefaultStyles(){return{...s.DEFAULT_STYLES,display:s.DISPLAY.BLOCK}}_paint(){this.options.render?this.options.render(this.getRender().getCtx(),this.getRender().getCanvas(),this):(this.getRender()._drawBackground(this),this.getRender()._drawBox(this))}}class L extends w{constructor(t,e){super(t,e),this._layout=null,this._lines=[],this.children+="",this.type="text",this.debugColor="blue"}_paint(){this.getRender()._drawBackground(this),this.getRender()._drawText(this),this.getRender()._drawBox(this)}_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.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=[{text:this.children,layout:this._layout}];else{this._lines=[];let t=1,e="",s=null,n=null;for(let r=0;ri){if(t>=this.renderStyles.maxLine){e=e.substring(0,e.length-2)+"...";break}this._lines.push({text:e,layout:n||s}),e="",t+=1}e+=this.children[r],n=s}this._layout.width=i,this._lines.push({text:e,layout:this.getRender().measureText(this,e)}),this._layout.height=this._lines.length*this.renderStyles.lineHeight}}getInnerText(){return this.children}setInnerText(t){void 0!==t&&t!==this.children&&(this.children=t,this.getLayer().reflowElement(this))}}class C extends _{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.options&&this.options.attrs&&this.options.attrs.timeout?setTimeout(()=>{this._loadImage()},this.options.attrs.timeout||0):this._loadImage()}_paint(){this.getRender()._drawBackground(this),this.getRender()._drawImage(this),this.getRender()._drawBox(this)}_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().reflowElement(this),this.options.on&&this.options.on.load&&this.options.on.load(this)}).catch(t=>{this.options.on&&this.options.on.error&&this.options.on.error(t)})})}_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=T(l,h,o)):!r(n)&&r(s)?(d=e,l=b(d,h,o)):r(s)&&r(n)?(l=h,d=o):"aspectFill"===i?l/d>h/o?(this._imageInfo.swidth=h,this._imageInfo.sheight=T(h,l,d),this._imageInfo.sx=0,this._imageInfo.sy=(o-this._imageInfo.sheight)/2):(this._imageInfo.sheight=o,this._imageInfo.swidth=b(o,t,e),this._imageInfo.sy=0,this._imageInfo.sx=(h-this._imageInfo.swidth)/2):"aspectFit"===i?l/d>h/o?(this._imageInfo.dwidth=b(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=T(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 b(t,e,i){return t/i*e}function T(t,e,i){return t/e*i}const I=["click","touchstart","touchmove","touchend","mousewheel"];class v{constructor({simulateClick:t=!0}){this.EVENTS=I,this.clear(),this.touchStartEvent=null,this.simulateClick=t}clear(){I.forEach(t=>{this[t+"Tree"]=new S,this[t+"List"]=[]})}click(t,e){let i=new E({x:t,y:e,type:"click"});this._emit(i)}touchstart(t,e){let i=new E({x:t,y:e,type:"touchstart"});this.touchStartEvent=i,this._emit(i)}touchmove(t,e){let i=new E({x:t,y:e,type:"touchmove"});this._emit(i)}touchend(t,e){let i=new E({x:t,y:e,type:"touchend"});this._emit(i),this.checkClick(i)}mousewheel(t,e,i,s){let n=new E({x:t,y:e,deltaX:i,deltaY:s,type:"mousewheel"});this._emit(n)}_emit(t){let e=this[t.type+"Tree"];if(!e)return;let i=[],s=e._getChildren();for(;s.length;)W(s,(e,n,r)=>{e.element.isVisible()&&this.isPointInElement(t.relativeX,t.relativeY,e.element)?(e.runCapture(t),i.unshift(e),n(),s=e._getChildren()):r&&(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){I.forEach(e=>{this[e+"List"]=this[e+"List"].filter(e=>(e.element===t&&e.remove(),e.element!==t))})}addEventListener(t,e,i,s){const n=this[t+"Tree"],r=this[t+"List"];n||console.error("Unknown event name ["+t+"]"),this.addCallback(e,i,n,r,s)}addCallback(t,e,i,s,n){let r=null,h=null,o=e;for(let t=s.length-1;t>=0;t--){if(e===s[t].element){r=s[t-1],h=s[t];break}if(!e.isInFlow()&&(o=e.relativeTo.parent,!o))break;if(d(o,(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.prependChild(h):i.prependChild(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 E{constructor({x:t,y:e,type:i,deltaX:s,deltaY:n}){this.x=t,this.y=e,this.relativeX=t,this.relativeY=e,this.type=i,this.cancelBubble=!1,this.currentTarget=null,"mousewheel"===i&&(this.deltaX=s,this.deltaY=n)}stopPropagation(){this.cancelBubble=!0}}class B extends S{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.call(this.element,t))}runCapture(t){this.captureList.forEach(e=>e.call(this.element,t))}}function W(t,e){let i=!1;const s=()=>i=!0;for(let n=0;n{this.getCtx().lineWidth=t,this.getCtx().stroke()};this._restore(()=>{this._path(()=>{t.renderStyles.borderTopWidth&&(this.topBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderTopWidth/2:0,w:_,h:L}),!m&&C(t.renderStyles.borderTopWidth)),t.renderStyles.borderRightWidth&&(this.getCtx().moveTo(x+_-S-(S?t.renderStyles.borderTopWidth/2:0),w),this.rightBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderRightWidth/2:0,w:_,h:L}),!m&&C(t.renderStyles.borderRightWidth)),t.renderStyles.borderBottomWidth&&(this.getCtx().moveTo(x+_,w+L-S-(S?t.renderStyles.borderRightWidth/2:0)),this.bottomBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderBottomWidth/2:0,w:_,h:L}),!m&&C(t.renderStyles.borderBottomWidth)),t.renderStyles.borderLeftWidth&&(this.getCtx().moveTo(x+S+(S?t.renderStyles.borderBottomWidth/2:0),w+L),this.leftBorder({x:x,y:w,borderRadius:S?S+t.renderStyles.borderLeftWidth/2:0,w:_,h:L}),C(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,S=this.getCtx();let x=X(t),w=t.contentX-t.renderStyles.paddingLeft-p,_=t.contentY-t.renderStyles.paddingTop-f,L=i+o+l+(p+u),C=s+d+a+(f+m);n(g)&&(S.globalAlpha=g),r&&h&&this._restore(()=>{this._path(()=>{this.topBorder({x:w,y:_,borderRadius:x,w:L,h:C}),this.rightBorder({x:w,y:_,borderRadius:x,w:L,h:C}),this.bottomBorder({x:w,y:_,borderRadius:x,w:L,h:C}),this.leftBorder({x:w,y:_,borderRadius:x,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.isDebug()&&(this.getCtx().strokeStyle=t.debugColor||"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=X(t),u=t.contentX-t.renderStyles.paddingLeft-a,f=t.contentY-t.renderStyles.paddingTop-c,m=e+s+r+a+g,S=i+n+h+c+y;this._path(()=>{this.topBorder({x:u,y:f,borderRadius:p,w:m,h:S}),this.rightBorder({x:u,y:f,borderRadius:p,w:m,h:S}),this.bottomBorder({x:u,y:f,borderRadius:p,w:m,h:S}),this.leftBorder({x:u,y:f,borderRadius:p,w:m,h:S})}),this.getCtx().clip()}_parseBackground(t,e){if(Array.isArray(t)){const i=this.getCtx().createLinearGradient(e.contentX,e.contentY,e.contentX+e.renderStyles.contentWidth,e.contentY+e.renderStyles.contentHeight);for(let e=0;e{if(d=0===s&&h?l+h:l,g=t.contentY+n/2+n*s+.5,this.isDebug()&&this.getCtx().fillRect(d,g,2,2),this.getCtx().fillText(i.text,d,g),a()&&400!==t.renderStyles.fontWeight){const e=.001*t.renderStyles.fontSize;this.getCtx().fillText(i.text,d-e,g)}if(o){const s=o[0];g+=1,this._restore(()=>{this._path(()=>{let e=g;"underline"===s?e=g+t._layout.fontHeight/2:"line-through"===s&&(e=g),this.getCtx().moveTo(d,e),this.getCtx().lineTo(d+i.layout.width,e)}),this.getCtx().strokeStyle=e,this.getCtx().stroke()})}})}measureText(t,e){let i=0,s=0;return this._restore(()=>{this.getCtx().font=t._getFont();const{width:n,actualBoundingBoxAscent:r}=this.getCtx().measureText(e);i=n,s=r||.7*t.renderStyles.fontSize}),{width:i,fontHeight:s+1}}_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;return this.imageBus[t]?e=this.imageBus[t]:(a()?this.getCanvas()?e=this.getCanvas().createImage():(console.warn("小程序请使用设置canvas参数以创建图片"),e=function(t){const e={onload:()=>{}};return new Promise((e,i)=>{wx.downloadFile({url:t,success(t){wx.getImageInfo({src:t.tempFilePath,success(i){e({target:{width:i.width,height:i.height},image:t.tempFilePath})}})},fail(t){i(t)}})}).then(t=>{e.onload(t)}).catch(t=>{}),e}(t)):e=new Image,t&&(this.imageBus[t]=new Promise((t,i)=>{e.onload=i=>{t({image:a()&&!this.getCanvas()?i.image:e,info:{width:a()?e.width:i.target.width,height:a()?e.height:i.target.height}})},e.onerror=t=>{i(t)}})),e.src=t),this.imageBus[t]}render(t){this.lastFrameComplete=!1,this.lastPaintTime=Date.now(),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(),this.lastFrameComplete=!0}renderFPS(){}readyToRender(t){this.element=t;const e=this.getLayer().options;this.lastPaintTime=Date.now(),e&&e.animate?this.animate():this.render(this.element)}requestRepaint(t){this.isAnimate||this.render(this.element)}getCanvas(){const t=this.getLayer().options;return t&&t.canvas||null}_animate(t){const e=Date.now();this.render(this.element),this.isAnimate&&window.requestAnimationFrame(()=>this._animate(e))}animate(){this.isAnimate=!0,window.requestAnimationFrame(()=>this._animate())}stopAnimate(){this.isAnimate=!1}onEffectFinished(){const t=Object.keys(this.imageBus).map(t=>this.imageBus[t]);return Promise.all(t)}}function X(t){const{paddingWidth:e,paddingHeight: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),p(s)}class A{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 v(e),this.render=new k(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();S.connectChildren(this.node),this.initP2CList(),this.initC2PList(),this.flow(),this.render.onEffectFinished().then(t=>this.lifecycle("onEffectSuccess",t)).catch(t=>this.lifecycle("onEffectFail",t)),this.repaint(),console.log(`渲染${this.p2cList.length}个元素 耗时 ${Date.now()-t} ms`)}initP2CList(){this.p2cList=g(this.node)}initC2PList(){this.c2pList=c(this.node)}flow(t=this.node){for(let t=0;tt.init()),this.reflowElement(t)}onElementChange(t){d(t,(t,e)=>{t._initWidthHeight(),"scroll-view"===t.type&&e()});for(let t=0;t{this.getLayer().eventManager.addEventListener(e,e=>{t.match("y")&&(e.relativeY-=this.currentScrollY),t.match("x")&&(e.relativeX-=this.currentScrollX)},this._scrollView,!0)}),this.getLayer().eventManager.addEventListener("mousewheel",t=>{this.scrollBy(t.deltaX,t.deltaY)?t.stopPropagation():this.scrollTo({x:t.deltaX<=0?this.maxScrollX:0,y:t.deltaY<=0?this.maxScrollY:0})},this._scrollView),this.getLayer().eventManager.addEventListener("touchstart",t=>{t.stopPropagation(),e=t.x,i=t.y,s=e,n=i,r=!0,clearInterval(a)},this._scrollView),this.getLayer().eventManager.addEventListener("touchmove",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.addEventListener("touchend",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)||(this.scrollTo(this.currentScrollX+l,this.currentScrollY+d),clearInterval(a)),l+=g,d+=c,l*l<=.05&&d*d<=.05&&(l=0,d=0,clearInterval(a))},16))},this._scrollView)}initScroll(){const{contentWidth:t,contentHeight:e}=this._scrollView.renderStyles,{width:i,height:s,direction:n}=this.renderStyles;this.maxScrollX=i-t,this.maxScrollY=s-e}calcScrollBoundX(t){return!(-this.currentScrollX-t>this.maxScrollX)&&!(this.currentScrollX+t>0)}calcScrollBoundY(t){return!(-this.currentScrollY-t>this.maxScrollY)&&!(this.currentScrollY+t>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+=p(t),this.calcChildrenVisible(),!0))}scrollBy(t,e){return!!(this.scrollByX(t)|this.scrollByY(e))&&(this.getRender().requestRepaint(this._scrollView),!0)}scrollTo({x:t,y:e}){n(t)&&this.maxScrollX>0&&((t=t)>this.maxScrollX&&(t=this.maxScrollX),this.currentScrollX=-p(t)),n(e)&&this.maxScrollY>0&&((e=e)>this.maxScrollY&&(e=this.maxScrollY),this.currentScrollY=-p(e)),this.initChildrenVisible(),this.getRender().requestRepaint(this._scrollView)}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=H(this.visibleIndex[0],5),i=H(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,this.visibleIndex.length<2&&this.initChildrenVisible()}isElementInViewport(t){return!this.styles.direction.match("y")||t.y+t.renderStyles.height+this.currentScrollY>this._scrollView.contentY&&t.y+this.currentScrollYnew _(t,e)),F("text",(t,e)=>new L(t,e)),F("image",(t,e)=>new C(t,e)),F("scroll-view",(t,e)=>new P(t,e)),F("scrollview",(t,e)=>new P(t,e));return{createLayer:function(t,e){return new A(t,e)},createElement:function(t){return t((function t(e,i={},s=[]){let n=null,r=s;if(!Y[e])throw Error(`Unknown tag name [${e}] !`);if("string"==typeof s&&"text"!==e)r=[new L({},s)];else if(!Array.isArray(s)&&"text"!==e)throw Error(`Element [${e}]:Children must be type of Array!`);return n=Y[e](i,r,t),n}))},component:F,View:_,Text:L,Image:C,Layer:A,ScrollView:P,mergeOptions:function(t,e){let i={};return y.forEach(s=>{t[s]||(t[s]={}),e[s]||(e[s]={}),i[s]=Object.assign({},t[s],i[s])}),i}}})); +//# sourceMappingURL=easy-canvas.min.js.map diff --git a/dist/easy-canvas.min.js.map b/dist/easy-canvas.min.js.map index ad33fe4..d28698b 100644 --- a/dist/easy-canvas.min.js.map +++ b/dist/easy-canvas.min.js.map @@ -1 +1 @@ -{"version":3,"file":"easy-canvas.min.js","sources":["../lib/constants.js","../lib/utils.js","../lib/line.js","../lib/flex-box.js","../lib/tree-node.js","../lib/complete-styles.js","../lib/element.js","../lib/view.js","../lib/text.js","../lib/image.js","../lib/event-manager.js","../lib/canvas-render.js","../lib/weapp-adapter.js","../lib/layer.js","../lib/scroll-view.js","../lib/create-element.js","../lib/index.js"],"sourcesContent":["const DISPLAY = {\n BLOCK: 'block',\n INLINE_BLOCK: 'inline-block',\n INLINE: 'inline', // 用户不能设置inline,text默认为inline\n FLEX: 'flex',\n NONE: 'none'\n}\n\nconst WIDTH = {\n AUTO: 'auto',\n OUTER: '100%'\n}\n\nconst POSITION = {\n ABSOLUTE: 'absolute',\n FIXED: 'fixed',\n RELATIVE: 'relative',\n STATIC: 'static'\n}\n\nconst TEXT_ALIGN = {\n LEFT: 'left',\n RIGHT: 'right',\n CENTER: 'center'\n}\n\nconst FLEX_DIRECTION = {\n ROW: 'row',\n COLUMN: 'column'\n}\n\nconst DEFAULT_STYLES = {\n display: DISPLAY.BLOCK,\n fontSize: 14,\n fontWeight: 400,\n fontFamily: \"sans-serif\",\n color: '#000',\n paddingTop: 0,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingRight: 0,\n marginTop: 0,\n marginBottom: 0,\n marginLeft: 0,\n marginRight: 0,\n height: WIDTH.AUTO,\n borderRadius: 0,\n lineCap: 'square',\n flexDirection: FLEX_DIRECTION.ROW,\n verticalAlign: 'middle',\n textAlign: 'left',\n justifyContent: 'flex-start',\n alignItems: 'flex-start',\n whiteSpace: 'normal',\n zIndex: 1,\n visible: true,\n position: 'static'\n}\n\nexport default {\n DISPLAY,\n WIDTH,\n POSITION,\n DEFAULT_STYLES,\n TEXT_ALIGN,\n FLEX_DIRECTION\n}\n","export function isExact(num) {\n return typeof num === 'number'\n}\n\nexport function isAuto(num) {\n return num === 'auto'\n}\n\nexport function isOuter(num) {\n if (typeof num !== 'string') return\n return num.match('%')\n}\n\nexport function parseOuter(num) {\n let _n = parseInt(num.replace('%', ''))\n return (isNaN(_n) || _n < 0) ? 0 : (_n / 100)\n}\n\n\nexport function walk(element, callback) {\n let _continue = false // 是否跳过当前节点以及后面的节点\n let _next = false // 是否跳过当前节点数,子元素都不会遍历\n const _callContinue = () => _continue = true\n const _callNext = () => _next = true\n if (element != null) {\n var stack = [];\n stack.push(element);\n while (stack.length != 0) {\n var item = stack.pop();\n callback(item, _callContinue, _callNext)\n if (!_next) {\n var children = item._getChildren();\n for (var i = children.length - 1; i >= 0; i--) {\n if (!_continue) {\n stack.push(children[i]);\n } else {\n // 复位\n _continue = false\n }\n\n }\n\n } else {\n // 复位\n _next = false\n }\n }\n }\n}\n\nexport function walkParent(element, callback) {\n if (!element) return\n let cur = element\n let stop = false\n const callbreak = () => {\n stop = true\n }\n while (cur.parent) {\n callback(cur.parent, callbreak)\n if (stop) {\n break\n }\n cur = cur.parent\n }\n}\n\nexport function findRelativeTo(element) {\n if (element.isInFlow()) return element.parent\n if (element.renderStyles.position === 'fixed') return element.root\n let relativeTo = null\n walkParent(element, (parent) => {\n if (parent.renderStyles.position !== 'static' && !relativeTo) {\n relativeTo = parent\n }\n })\n if (!relativeTo) {\n relativeTo = element.root\n }\n return relativeTo\n}\n\n\n//\nvar pow = Math.pow,\n sqrt = Math.sqrt,\n sin = Math.sin,\n cos = Math.cos,\n PI = Math.PI,\n c1 = 1.70158,\n c2 = c1 * 1.525,\n c3 = c1 + 1,\n c4 = (2 * PI) / 3,\n c5 = (2 * PI) / 4.5;\n\nexport function easeInOutElastic(x) {\n return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?\n -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2 :\n pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5) / 2 + 1;\n}\n\nfunction easeInOutExpo(pos) {\n if (pos === 0) return 0;\n if (pos === 1) return 1;\n if ((pos /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (pos - 1));\n return 0.5 * (-Math.pow(2, -10 * --pos) + 2);\n}\n\n\nexport function isWX() {\n try {\n return Boolean(wx.getSystemInfoSync);\n } catch(err) {\n return false\n }\n}\n\nexport function isEndNode(el) {\n return el.parent && !el.next && !el.hasChildren()\n}\n\nexport function breadthFirstSearch(node) {\n\n var nodes = [];\n\n if (node != null) {\n\n var queue = [];\n\n queue.unshift(node);\n\n while (queue.length != 0) {\n\n var item = queue.shift();\n\n nodes.push(item._generateRender());\n\n var children = item._getChildren();\n\n for (var i = 0; i < children.length; i++)\n queue.push(children[i]._generateRender());\n\n }\n\n }\n\n return nodes;\n\n}\n\nexport function breadthFirstSearchRight(node) {\n\n var nodes = [];\n\n if (node != null) {\n\n var queue = [];\n\n queue.unshift(node);\n\n while (queue.length != 0) {\n\n var item = queue.shift();\n\n nodes.push(item._generateRender());\n\n var children = item._getChildren();\n\n for (var i = children.length - 1; i >= 0; i--)\n queue.push(children[i]._generateRender());\n\n }\n\n }\n\n return nodes.reverse();\n\n}\n\nexport function needReflow(style) {\n return ['width',\n 'height',\n 'position',\n 'display',\n 'padding',\n 'paddingTop',\n 'paddingLeft',\n 'paddingBottom',\n 'paddingRight',\n 'margin',\n 'marginLeft',\n 'marginTop',\n 'marginBottom',\n 'marginRight',\n 'borderWidth',\n 'flexDirection',\n 'justifyContent',\n 'alignItems',\n 'textAlign',\n 'left',\n 'top',\n 'right',\n 'bottom'\n ].includes(style)\n}\n\nconst mergeKeys = ['attrs', 'styles', 'on']\nexport function mergeOptions(options, mergeOptions) {\n let mergedOptions = {}\n mergeKeys.forEach(key => {\n if (!options[key]) options[key] = {}\n if (!mergeOptions[key]) mergeOptions[key] = {}\n mergedOptions[key] = Object.assign({}, options[key], mergedOptions[key])\n })\n return mergedOptions\n}\n\n\nexport function floor(val){\n return (0.5 + val) << 0\n}\n\nexport function qSort3(arr,callback) { //三路快排\n if(arr.length == 0) {\n return [];\n }\n var left = [];\n var center = [];\n var right = [];\n var pivot = arr[0]; //偷懒,直接取第一个,实际取值情况 参考[快速排序算法的优化思路总结]\n let val = 0\n for(var i = 0; i < arr.length; i++) {\n val = callback(arr[i],pivot)\n if(val<0) {\n left.push(arr[i]);\n } else if(val === 0) {\n center.push(arr[i]);\n } else {\n right.push(arr[i]);\n }\n }\n return [...qSort3(left,callback), ...center, ...qSort3(right,callback)];\n}\n\nexport function getThrottle(threshold) {\n let timer;\n return function (fn) {\n if (!timer) {\n timer = setTimeout(function () {\n fn();\n timer = null;\n }, threshold)\n }\n }\n}\n","import { isExact, isAuto } from './utils'\n\nexport default class Line {\n constructor() {\n this.width = 0\n this.height = 0\n this.contentWidth = 0 // 右边界\n this.y = 0 // 上\n this.doorClosed = false // 是否允许加入\n this.outerWidth = 0\n this.container = null\n this.elements = []\n this.start = null // 起点,行最左边第一个\n this.end = null // 结束\n this.offsetX = 0\n this.id = Math.random()\n }\n\n bind(el) {\n this.container = el.parent\n this.initHeight(el)\n this.outerWidth = el.parent && isAuto(el.parent.styles.width) ? Infinity : el.parent.renderStyles.contentWidth\n\n this.start = el\n this.add(el)\n }\n\n initHeight(el) {\n this.height = el.parent && el.parent.renderStyles.lineHeight || 0\n }\n\n initLayout(el) {\n this.right = el._getContainerLayout().contentX\n this.x = el._getContainerLayout().contentX\n this.y = this.getPreLine(el).y\n }\n\n refreshElementPosition(el) {\n if (this.start === el) {\n this.initLayout(el)\n }\n // 刷新位置,首先以左边计算\n el.x = this.right + this.offsetX\n el.y = this.y + this.getOffsetY(el)\n // + (this.height - el.renderStyles.height) / 2\n this.right += el.renderStyles.width\n\n }\n\n getOffsetY(el) {\n if (el.renderStyles.verticalAlign === 'bottom') {\n return (this.height - el.renderStyles.height)\n } else if (el.renderStyles.verticalAlign === 'middle') {\n return (this.height - el.renderStyles.height) / 2\n } else {\n return 0\n }\n }\n\n\n add(el) {\n this.elements.push(el)\n el.line = this\n this.refreshWidthHeight(el)\n\n if (!el.next || el.next.renderStyles.display !== 'inline-block') {\n this.closeLine()\n }\n }\n\n refreshWidthHeight(el) {\n if (el.renderStyles.height > this.height) {\n this.height = el.renderStyles.height\n }\n\n this.width += el.renderStyles.width\n }\n\n canIEnter(el) {\n if ((el.renderStyles.width + this.width) > this.outerWidth) {\n this.closeLine()\n return false\n } else {\n return true\n }\n }\n\n closeLine() {\n // new line\n this.end = this.elements[this.elements.length - 1]\n this.refreshXAlign()\n\n }\n\n getPreLine(el) {\n if (el.pre) {\n if (el.pre.line) {\n return { y: el.pre.line.height + el.pre.line.y, x: el.pre.line.x }\n } else {\n return { y: el._getPreLayout().y + el._getPreLayout().height, x: el._getPreLayout().x }\n }\n } else {\n return { y: el._getContainerLayout().contentY, x: el._getContainerLayout().contentX }\n }\n }\n\n refreshXAlign() {\n if (this.outerWidth > 5000) return\n if (!this.end.parent) return\n let offsetX = this.outerWidth - this.width\n if (this.end.parent.renderStyles.textAlign === 'center') {\n offsetX = offsetX / 2\n } else if (this.end.parent.renderStyles.textAlign === 'left') {\n offsetX = 0\n }\n this.offsetX = offsetX\n }\n}\n","import Line from './line'\nimport { isExact, isAuto } from './utils'\nimport STYLES from './constants'\n\nconst KEY = {\n [STYLES.FLEX_DIRECTION.ROW]: {\n width: 'width',\n contentWidth: 'contentWidth',\n x: 'x',\n y: 'y',\n contentX: 'contentX',\n height: 'height',\n contentHeight: 'contentHeight'\n },\n [STYLES.FLEX_DIRECTION.COLUMN]: {\n width: 'height',\n contentWidth: 'contentHeight',\n x: 'y',\n y: 'x',\n contentX: 'contentY',\n height: 'width',\n contentHeight: 'contentWidth'\n }\n}\n// 目前flex是基于inline-block的简单实现,只支持row方向width + flex混用\nexport default class FlexBox extends Line {\n constructor() {\n super()\n this.exactValue = 0\n this.flexTotal = 0\n this.key = null\n }\n\n closeLine() {\n super.closeLine()\n this.calcFlex()\n }\n\n bind(el) {\n this.container = el.parent\n if (el.parent) {\n this.key = KEY[el.parent.renderStyles.flexDirection]\n }\n this.initHeight(el)\n this.outerWidth = el.parent && isAuto(el.parent.styles[this.key.width]) ? Infinity : el.parent.renderStyles[this.key.contentWidth]\n this.start = el\n this.add(el)\n }\n\n add(el) {\n if (isExact(el.styles[this.key.width])) {\n this.exactValue += el.renderStyles[this.key.width]\n } else if (isExact(el.styles.flex)) {\n this.flexTotal += el.renderStyles.flex\n }\n\n this.elements.push(el)\n el.line = this\n this.refreshWidthHeight(el)\n\n if (!el.next) {\n this.closeLine()\n }\n }\n\n initHeight() {\n this[this.key.height] = 0\n }\n\n refreshWidthHeight(el) {\n if (el.renderStyles[this.key.height] > this[this.key.height]) {\n this[this.key.height] = el.renderStyles[this.key.height]\n }\n\n this[this.key.width] += el.renderStyles[this.key.width]\n }\n\n initLayout(el) {\n this.right = el._getContainerLayout()[this.key.contentX]\n this[this.key.x] = el._getContainerLayout()[this.key.contentX]\n this[this.key.y] = this.getPreLine(el)[this.key.y]\n }\n\n refreshElementPosition(el) {\n if (this.start === el) {\n this.initLayout(el)\n }\n // 刷新位置,首先以左边计算\n el[this.key.x] = this.right + this.offsetX\n el[this.key.y] = this[this.key.y] + this.getOffsetY(el)\n // + (this.height - el.renderStyles.height) / 2\n this.right += el.renderStyles[this.key.width]\n\n }\n\n calcFlex() {\n const { [this.key.contentWidth]: containerWidth } = this.container.renderStyles\n this.elements.forEach(child => {\n if (isExact(child.styles.flex)) {\n child.renderStyles[this.key.width] = (child.styles.flex / this.flexTotal) * (containerWidth - this.exactValue)\n child._refreshContentWithLayout()\n }\n })\n }\n\n refreshXAlign() {\n if (!this.end.parent) return\n let offsetX = this.outerWidth - this[this.key.width]\n if (this.end.parent.renderStyles.justifyContent === 'center') {\n offsetX = offsetX / 2\n } else if (this.end.parent.renderStyles.justifyContent === 'flex-start') {\n offsetX = 0\n }\n this.offsetX = offsetX\n }\n\n getOffsetY(el) {\n if (el.renderStyles.alignSelf === 'flex-end') {\n return (this.container.renderStyles[this.key.contentHeight] - el.renderStyles[this.key.height])\n } else if (el.renderStyles.alignSelf === 'center') {\n return (this.container.renderStyles[this.key.contentHeight] - el.renderStyles[this.key.height]) / 2\n } else {\n return 0\n }\n }\n}\n","export default class TreeNode {\n\n static connectChildren(el) {\n if (el.hasChildren()) {\n el.children = el.children.filter(item => item instanceof TreeNode)\n el._getChildren().map((child, index) => {\n // 设置parent\n child._setParent(el)\n // 设置了上一个兄弟节点\n child._setSibling(el._getChildren()[index - 1], el._getChildren()[index + 1])\n TreeNode.connectChildren(child)\n })\n } else {\n }\n }\n\n constructor(children) {\n this.children = children || []\n this.parent = null\n this.root = null\n this.pre = null\n this.next = null\n }\n\n\n\n hasChildren() {\n return Array.isArray(this.children) && this.children.length ? true : false\n }\n\n _getChildren() {\n return this.hasChildren() ? this.children : []\n }\n\n _setParent(element) {\n this.parent = element\n this.root = element.root\n }\n\n _setSibling(pre, next) {\n this.pre = pre || null\n this.next = next || null\n }\n\n\n // 添加在最后\n appendChild(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n const pre = this._getChildren()[this._getChildren().length - 1]\n pre && pre._setSibling(pre.pre, treeNode)\n this.children.push(treeNode)\n treeNode._setParent(this)\n treeNode._setSibling(pre, null)\n // return treeNode\n }\n\n //\n prependChild(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n const next = this._getChildren()[0]\n next && next._setSibling(treeNode, next.next)\n this.children.unshift(treeNode)\n treeNode._setParent(this)\n treeNode._setSibling(null, next)\n // return treeNode\n }\n\n removeChild(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n const index = this._getChildren().indexOf(treeNode)\n if (index < 0) throw Error('treeNode must be the child of parent')\n const pre = this._getChildren()[index - 1]\n const next = this._getChildren()[index + 1]\n if (pre) {\n pre._setSibling(pre.pre, next)\n }\n if (next) {\n next._setSibling(pre, next.next)\n }\n this.children.splice(index, 1)\n }\n\n remove() {\n if (!this.parent) {\n throw Error('Can not remove root node')\n }\n this.parent.removeChild(this)\n }\n\n append(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n if (!this.parent) throw Error('Can not add treeNode to root level!')\n let children = []\n treeNode._setParent(this.parent)\n this.parent.children.forEach((child, index) => {\n children.push(child)\n if (child === this) {\n treeNode._setSibling(child, this.parent.children[index + 1])\n children.push(treeNode)\n }\n })\n this.parent.children = children\n }\n\n prepend(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n if (!this.parent) throw Error('Can not add treeNode to root level!')\n let children = []\n treeNode._setParent(this.parent)\n for (let i = this.parent.children.length - 1; i >= 0; i--) {\n children.unshift(this.parent.children[i])\n if (this.parent.children[i] === this) {\n treeNode._setSibling(this.parent.children[i - 1], this.parent.children[i])\n children.unshift(treeNode)\n }\n }\n this.parent.children = children\n }\n\n\n}\n","import { isExact, isAuto, isOuter } from './utils'\nimport STYLES from './constants'\n\n\nexport default function (element) {\n _completeFlex(element)\n\n _completeWidth(element)\n\n _completeBorder(element)\n\n _completeFont(element)\n\n _completePaddingMargin(element)\n}\n\n\nfunction _completePaddingMargin(element) {\n if (element.styles.padding) {\n if (isExact(element.styles.padding)) {\n element.styles.paddingLeft = element.styles.padding\n element.styles.paddingBottom = element.styles.padding\n element.styles.paddingRight = element.styles.padding\n element.styles.paddingTop = element.styles.padding\n } else if (Array.isArray(element.styles.padding)) {\n // 支持数组[10,20]相当于padding:10px 20px;\n if (element.styles.padding.length === 2) {\n element.styles.paddingLeft = element.styles.paddingRight = element.styles.padding[1]\n element.styles.paddingBottom = element.styles.paddingTop = element.styles.padding[0]\n } else if (element.styles.padding.length === 4) {\n element.styles.paddingLeft = element.styles.padding[3]\n element.styles.paddingBottom = element.styles.padding[2]\n element.styles.paddingRight = element.styles.padding[1]\n element.styles.paddingTop = element.styles.padding[0]\n }\n }\n }\n\n if (isExact(element.styles.margin)) {\n element.styles.marginLeft = element.styles.margin\n element.styles.marginBottom = element.styles.margin\n element.styles.marginRight = element.styles.margin\n element.styles.marginTop = element.styles.margin\n } else if (Array.isArray(element.styles.margin)) {\n // 支持数组[10,20]相当于padding:10px 20px;\n if (element.styles.margin.length === 2) {\n element.styles.marginLeft = element.styles.marginRight = element.styles.margin[1]\n element.styles.marginBottom = element.styles.marginTop = element.styles.margin[0]\n } else if (element.styles.margin.length === 4) {\n element.styles.marginLeft = element.styles.margin[3]\n element.styles.marginBottom = element.styles.margin[2]\n element.styles.marginRight = element.styles.margin[1]\n element.styles.marginTop = element.styles.margin[0]\n }\n }\n}\n\n/**\n * borderwidth到各个边\n */\nfunction _completeBorder(element) {\n let { borderWidth, borderLeftWidth, borderRightWidth, borderBottomWidth, borderTopWidth, borderRadius } = element.styles\n if (!borderWidth) {\n element.styles.borderWidth = 0\n borderWidth = 0\n }\n if (Array.isArray(borderWidth)) {\n element.styles.borderTopWidth = borderWidth[0]\n element.styles.borderRightWidth = borderWidth[1]\n element.styles.borderBottomWidth = borderWidth[2]\n element.styles.borderLeftWidth = borderWidth[3]\n } else {\n if (!borderLeftWidth) {\n element.styles.borderLeftWidth = borderWidth\n }\n if (!borderRightWidth) {\n element.styles.borderRightWidth = borderWidth\n }\n if (!borderBottomWidth) {\n element.styles.borderBottomWidth = borderWidth\n }\n if (!borderTopWidth) {\n element.styles.borderTopWidth = borderWidth\n }\n }\n if (borderRadius) {\n element.styles.overflow = 'hidden'\n }\n}\n\nfunction _completeWidth(element) {\n if (!element.styles.width) {\n if (element.styles.display === STYLES.DISPLAY.INLINE_BLOCK || element.styles.display === STYLES.DISPLAY.INLINE || !element.isInFlow()) {\n element.styles.width = STYLES.WIDTH.AUTO\n } else if (element.styles.display === STYLES.DISPLAY.BLOCK || element.styles.display === STYLES.DISPLAY.FLEX) {\n element.styles.width = STYLES.WIDTH.OUTER\n } else {\n element.styles.width = 0\n }\n }\n\n if (isOuter(element.styles.width)) {\n if (element.parent && isAuto(element.parent.styles.width)) {\n element.styles.width = STYLES.WIDTH.AUTO\n }\n }\n\n if (isOuter(element.styles.height)) {\n if (element.parent && isAuto(element.parent.styles.height)) {\n element.styles.height = STYLES.WIDTH.AUTO\n }\n }\n}\n\nfunction _completeFont(element) {\n if (element.styles.fontSize && !element.styles.lineHeight) {\n element.styles.lineHeight = element.styles.fontSize * 1.4\n }\n}\n\nfunction _completeFlex(element) {\n if (element.parent && element.parent.styles.display === STYLES.DISPLAY.FLEX) {\n // flex布局内 width 和flex需要有一个\n if (!element.styles.flex) {\n if (!isExact(element.styles.height) && !isExact(element.styles.width)) {\n element.styles.flex = 1\n }\n } else {\n if (element.parent.styles.flexDirection === 'column' && isExact(element.styles.flex)) {\n element.styles.height = 0\n } else if (element.parent.styles.flexDirection === 'row' && isExact(element.styles.flex)) {\n element.styles.width = 0\n }\n }\n\n }\n}\n","import STYLES from './constants'\nimport pxUtil from './px'\nimport { isExact, walk, isOuter, parseOuter, walkParent, isEndNode, isAuto, findRelativeTo, needReflow, floor } from './utils'\nimport Line from './line'\nimport FlexBox from './flex-box'\nimport TreeNode from './tree-node'\nimport completeStyles from './complete-styles'\n\n/**\n * Element类实现盒模型以及定位,不具备绘制\n * 其他类继承实现\n *\n */\n\n\n\n\nexport default class Element extends TreeNode {\n constructor(options, children) {\n super(children)\n this.options = Object.assign({ attrs: {}, styles: {}, on: {} }, options)\n this.styles = null\n this.renderStyles = null\n this.x = 0\n this.y = 0\n this.render = null\n this.container = null\n this.visible = true\n }\n\n init() {\n this._initStyles()\n this.initEvent()\n }\n\n initEvent() {\n if (this.options.on) {\n Object.keys(this.options.on).forEach(eventName => {\n if (this.getLayer().eventManager.EVENTS.includes(eventName)) {\n this.getLayer().eventManager.addEventListener(eventName, this.options.on[eventName], this)\n }\n })\n }\n }\n\n removeEvent() {\n this.getLayer().eventManager.removeElement(this)\n }\n\n getLayer() {\n return this.root.layer\n }\n\n getRender() {\n return this.root.layer.render\n }\n\n _paint() {\n\n }\n\n mount(layer) {\n layer.mountNode(this)\n }\n\n _initStyles() {\n this.styles = Object.assign({}, this._getDefaultStyles(), this._getParentStyles(this.options.styles), this.options.styles || {})\n\n this._completeStyles()\n\n this._initRenderStyles()\n }\n\n _initRenderStyles() {\n const renderStyles = { ...this.styles }\n const parentWidth = this._getContainerLayout().contentWidth\n const parentHeight = this._getContainerLayout().contentHeight\n\n if (isAuto(renderStyles.width)) {\n renderStyles.paddingWidth = 0\n } else if (isOuter(renderStyles.width)) {\n renderStyles.paddingWidth = parseOuter(renderStyles.width) * parentWidth - renderStyles.marginLeft - renderStyles.marginRight\n } else {\n renderStyles.paddingWidth = renderStyles.width\n }\n\n if (isAuto(renderStyles.height)) {\n renderStyles.paddingHeight = 0\n } else if (isOuter(renderStyles.height)) {\n renderStyles.paddingHeight = parseOuter(renderStyles.height) * parentHeight - renderStyles.marginTop - renderStyles.marginBottom\n } else {\n renderStyles.paddingHeight = renderStyles.height\n }\n\n if (!renderStyles.paddingWidth) renderStyles.paddingWidth = 0\n if (!renderStyles.paddingHeight) renderStyles.paddingHeight = 0\n\n // 初始化contentWidth\n renderStyles.contentWidth = renderStyles.paddingWidth - renderStyles.paddingLeft - renderStyles.paddingRight\n renderStyles.contentHeight = renderStyles.paddingHeight - renderStyles.paddingTop - renderStyles.paddingBottom\n\n renderStyles.width = renderStyles.paddingWidth + renderStyles.marginLeft + renderStyles.marginRight + this._getTotalBorderWidth(renderStyles)\n renderStyles.height = renderStyles.paddingHeight + renderStyles.marginTop + renderStyles.marginBottom + this._getTotalBorderHeight(renderStyles)\n\n this.renderStyles = renderStyles\n\n if (this._InFlexBox()) {\n this._bindFlexBox()\n } else if (!this.isInFlow()) {\n this.relativeTo = findRelativeTo(this)\n }\n\n\n }\n\n /**\n * 需要继承的styles放在这里\n */\n _getParentStyles(curStyles) {\n let { textAlign, lineHeight, fontSize, color, fontFamily, alignItems, visible = true } = this.parent && this.parent.renderStyles || {}\n let extendStyles = {}\n if (textAlign) extendStyles.textAlign = textAlign\n if (fontSize) extendStyles.fontSize = fontSize\n if (color) extendStyles.color = color\n if (fontFamily) extendStyles.fontFamily = fontFamily\n if (alignItems && !curStyles.alignSelf) extendStyles.alignSelf = alignItems\n extendStyles.visible = visible\n return extendStyles\n }\n\n _completeStyles() {\n completeStyles(this)\n }\n\n _getDefaultStyles() {\n return STYLES.DEFAULT_STYLES\n }\n\n // 获取文档流中的子节点\n _getChildrenInFlow() {\n return this._getChildren().filter(item => item.isInFlow())\n }\n\n // 是否在文档流中\n isInFlow() {\n const { position, display } = this.styles\n return position !== STYLES.POSITION.ABSOLUTE && position !== STYLES.POSITION.FIXED\n }\n\n isVisible() {\n return this.renderStyles.visible && this.visible\n }\n\n _generateRender() {\n return this\n }\n\n getCtx() {\n return this.root.layer.ctx\n }\n\n /**\n * 实现文档流 需要知道上一个兄弟节点\n */\n _reflow() {\n\n\n }\n\n _initWidthHeight() {\n const { width, height, display, flex, marginLeft, marginRight, marginTop, marginBottom } = this.styles\n if (isAuto(width) || isAuto(height)) {\n // 这一步需要遍历,判断一下\n const layout = this._measureLayout()\n // 初始化宽度高度\n if (isAuto(width)) {\n this.renderStyles.contentWidth = floor(layout.width)\n }\n\n if (isAuto(height)) {\n // 不填就是auto\n this.renderStyles.contentHeight = floor(layout.height)\n }\n }\n\n this._refreshLayoutWithContent()\n\n if (this._InFlexBox()) {\n this.line.refreshWidthHeight(this)\n } else if (display === STYLES.DISPLAY.INLINE_BLOCK) {\n // 如果是inline-block 这里仅计算高度\n this._bindLine()\n }\n }\n\n _initPosition() {\n let { contentX } = this._getContainerLayout()\n const { paddingLeft, paddingTop, borderLeftWidth, borderTopWidth, marginLeft, marginTop } = this.renderStyles\n // 初始化ctx位置\n if (!this.isInFlow()) {\n // 不在文档流中\n let { contentX, contentY, contentWidth, contentHeight } = this._getContainerLayout(this.relativeTo)\n let { top, bottom, right, left, width, height } = this.renderStyles\n if (isOuter(top)) top = parseOuter(top) * contentHeight\n if (isOuter(bottom)) bottom = parseOuter(bottom) * contentHeight\n if (isOuter(left)) left = parseOuter(left) * contentWidth\n if (isOuter(right)) right = parseOuter(right) * contentWidth\n if (isExact(top)) {\n this.y = contentY + top\n } else if (isExact(bottom)) {\n this.y = contentY + contentHeight - bottom - height\n }\n\n if (isExact(left)) {\n this.x = contentX + left\n } else if (isExact(right)) {\n this.x = contentX + contentWidth - right - width\n }\n } else if (this._InFlexBox()) {\n this.line.refreshElementPosition(this)\n } else if (this.renderStyles.display === STYLES.DISPLAY.INLINE_BLOCK) {\n // inline-block到line里计算\n // this._bindLine()\n this.line.refreshElementPosition(this)\n } else {\n this.x = contentX\n this.y = this._getPreLayout().y + this._getPreLayout().height\n }\n this.x = floor(this.x)\n this.y = floor(this.y)\n this.contentX = this.x + paddingLeft + borderLeftWidth + marginLeft\n this.contentY = this.y + paddingTop + borderTopWidth + marginTop\n }\n\n _InFlexBox() {\n if (!this.isInFlow()) return false\n if (!this.parent) return false\n if (this.parent && this.parent.renderStyles.display === STYLES.DISPLAY.FLEX) return true\n }\n\n\n // 父元素根据子元素撑开content后,再计算width\n _refreshLayoutWithContent() {\n this.renderStyles.height = floor(this.renderStyles.contentHeight + this.renderStyles.paddingTop + this.renderStyles.paddingBottom + this.renderStyles.marginTop + this.renderStyles.marginBottom + this._getTotalBorderHeight())\n this.renderStyles.width = floor(this.renderStyles.contentWidth + this.renderStyles.paddingLeft + this.renderStyles.paddingRight + this.renderStyles.marginLeft + this.renderStyles.marginRight + this._getTotalBorderWidth())\n this.renderStyles.paddingWidth = floor(this.renderStyles.contentWidth + this.renderStyles.paddingLeft + this.renderStyles.paddingRight)\n this.renderStyles.paddingHeight = floor(this.renderStyles.contentHeight + this.renderStyles.paddingTop + this.renderStyles.paddingBottom)\n }\n\n // 父元素根据子元素撑开content后,再计算width\n _refreshContentWithLayout() {\n this.renderStyles.contentHeight = this.renderStyles.height - this.renderStyles.paddingTop - this.renderStyles.paddingBottom - this.renderStyles.marginTop - this.renderStyles.marginBottom - this._getTotalBorderHeight()\n this.renderStyles.contentWidth = this.renderStyles.width - this.renderStyles.paddingLeft - this.renderStyles.paddingRight - this.renderStyles.marginLeft - this.renderStyles.marginRight - this._getTotalBorderWidth()\n this.renderStyles.paddingWidth = floor(this.renderStyles.contentWidth + this.renderStyles.paddingLeft + this.renderStyles.paddingRight)\n this.renderStyles.paddingHeight = floor(this.renderStyles.contentHeight + this.renderStyles.paddingTop + this.renderStyles.paddingBottom)\n }\n\n _getTotalBorderWidth(renderStyles = this.renderStyles) {\n return renderStyles.borderLeftWidth + renderStyles.borderRightWidth\n }\n\n _getTotalBorderHeight(renderStyles = this.renderStyles) {\n return renderStyles.borderTopWidth + renderStyles.borderBottomWidth\n }\n\n _bindLine() {\n if (this.pre && this.pre.line && this.pre.line.canIEnter(this)) {\n this.pre.line.add(this)\n } else {\n // 新行\n new Line().bind(this)\n }\n }\n\n _bindFlexBox() {\n if (this.pre && this.pre.line) {\n this.pre.line.add(this)\n } else {\n // 新行\n new FlexBox().bind(this)\n }\n }\n\n _getContainerLayout(container = this.parent) {\n if (!container) {\n // root\n if (!this.container) {\n debugger\n }\n container = {\n renderStyles: {\n width: this.container.width,\n height: this.container.height,\n paddingTop: 0,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingRight: 0,\n marginLeft: 0,\n marginRight: 0,\n marginTop: 0,\n marginBottom: 0,\n contentWidth: this.container.width,\n contentHeight: this.container.height\n },\n x: 0,\n y: 0,\n contentX: 0,\n contentY: 0\n }\n }\n return {\n width: container.renderStyles.width,\n height: container.renderStyles.height,\n x: container.x,\n y: container.y,\n paddingTop: container.renderStyles.paddingTop,\n paddingBottom: container.renderStyles.paddingBottom,\n paddingLeft: container.renderStyles.paddingLeft,\n paddingRight: container.renderStyles.paddingRight,\n marginLeft: container.renderStyles.marginLeft,\n marginRight: container.renderStyles.marginRight,\n marginTop: container.renderStyles.marginTop,\n marginBottom: container.renderStyles.marginBottom,\n contentX: container.contentX,\n contentY: container.contentY,\n contentWidth: container.renderStyles.contentWidth,\n contentHeight: container.renderStyles.contentHeight\n }\n }\n\n // 这里前一个节点必须在文档流中\n _getPreLayout() {\n let cur = this.pre\n while (cur && !cur.isInFlow()) {\n cur = cur.pre\n }\n // 如果没有前一个或者前面的都不在文档流中,获取容器的\n if (cur) {\n return {\n width: cur.renderStyles.width,\n height: cur.renderStyles.height,\n x: cur.x,\n y: cur.y\n }\n } else {\n return {\n width: 0,\n height: 0,\n x: this._getContainerLayout().contentX,\n y: this._getContainerLayout().contentY\n }\n }\n }\n\n // 计算自身的高度\n _measureLayout() {\n let width = 0 // 需要考虑原本的宽度\n let height = 0\n this._getChildrenInFlow().forEach(child => {\n if (child.line) {\n if (child.line.start === child) {\n if (child.line.width > width) {\n width = child.line.width\n }\n height += child.line.height\n }\n } else if (child.renderStyles.width > width) {\n width = child.renderStyles.width\n height += child.renderStyles.height\n } else {\n height += child.renderStyles.height\n }\n })\n\n return { width, height }\n }\n\n // 获取元素,只会找该元素子级\n getElementBy(key, value) {\n let match = []\n walk(this, (element) => {\n if (element.options.attrs[key] === value) {\n match.push(element)\n }\n })\n return match\n }\n\n // 添加在最后\n appendChild(element) {\n super.appendChild(element)\n this.getLayer().onElementAdd(element)\n return element\n }\n\n //\n prependChild(element) {\n super.prependChild(element)\n this.getLayer().onElementAdd(element)\n return element\n }\n\n removeChild(element) {\n super.removeChild(element)\n this.getLayer().onElementRemove(element)\n }\n\n append(element) {\n super.append(element)\n this.getLayer().onElementAdd(element)\n }\n\n prepend(element) {\n super.prepend(element)\n this.getLayer().onElementAdd(element)\n }\n\n setStyles(styles) {\n let _needReflow = false\n Object.keys(styles).forEach(key => {\n if (needReflow(key)) {\n _needReflow = true\n } else {\n this.renderStyles[key] = styles[key]\n }\n })\n if (_needReflow) {\n Object.keys(styles).forEach(key => {\n this.options.styles[key] = styles[key]\n })\n this.getLayer().reflowElement(this, this)\n // console.warn('实验性功能')\n } else {\n this.getRender().requestRepaint()\n }\n }\n\n}\n","import Element from './element'\nimport STYLES from './constants'\nimport { isExact } from './utils'\n\nexport default class View extends Element {\n\n constructor(options, children) {\n super(options, children)\n this.type = 'view'\n }\n\n _getDefaultStyles() {\n return {\n ...STYLES.DEFAULT_STYLES,\n display: STYLES.DISPLAY.BLOCK\n }\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawBox(this)\n }\n\n\n}\n","import Element from './element'\nimport STYLES from './constants'\nimport { isExact, isAuto } from './utils'\n\nexport default class Text extends Element {\n constructor(options, children) {\n super(options, children)\n this._layout = null // layout用来保存计算的自身高度\n this._lines = []\n this.children += ''\n this.type = 'text'\n this.debugColor = 'blue'\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawText(this)\n this.getRender()._drawBox(this)\n }\n\n _getDefaultStyles() {\n return {\n ...STYLES.DEFAULT_STYLES,\n display: STYLES.DISPLAY.INLINE_BLOCK,\n width: STYLES.WIDTH.AUTO,\n textAlign: 'left',\n }\n }\n\n _measureLayout() {\n this._layout = this.getRender().measureText(this, this.children)\n this._layout.height = this.renderStyles.lineHeight\n this._calcLine()\n return this._layout\n }\n\n _getFont() {\n const { fontSize, fontWeight, fontFamily } = this.renderStyles\n return `${fontWeight} ${fontSize}px ${fontFamily}`\n }\n\n _calcLine() {\n if (!this.parent || !this.children) return\n const { width: textWidth, height: textHeight } = this._layout\n let { contentWidth: parentContentWidth } = this.parent.renderStyles\n const { width: parentWidth } = this.parent.styles\n if (!isAuto(this.styles.width)) parentContentWidth = this.renderStyles.width\n // 如果一行宽度够,或者父级宽度是auto\n if ((isExact(parentContentWidth) && parentContentWidth >= textWidth) || parentWidth === STYLES.WIDTH.AUTO) {\n this._lines = [{\n text: this.children,\n layout: this._layout\n }]\n } else {\n this._lines = []\n let lineIndex = 1\n let lineText = ''\n let _layout = null\n let lastLayout = null\n for (let i = 0; i < this.children.length; i++) {\n _layout = this.getRender().measureText(this, lineText + this.children[i])\n if (_layout.width > parentContentWidth) {\n if (lineIndex >= this.renderStyles.maxLine) {\n // 最大行数限制 以及maxline省略号实现\n lineText = lineText.substring(0, lineText.length - 2) + '...'\n break\n }\n // 超出了\n this._lines.push({\n text: lineText,\n layout: lastLayout || _layout\n })\n lineText = ''\n lineIndex += 1\n\n }\n\n lineText += this.children[i]\n\n lastLayout = _layout\n }\n this._layout.width = parentContentWidth\n this._lines.push({\n text: lineText,\n layout: this.getRender().measureText(this, lineText)\n })\n // 根据lineheihgt更新height\n this._layout.height = this._lines.length * this.renderStyles.lineHeight\n }\n }\n\n getInnerText() {\n return this.children\n }\n\n setInnerText(val) {\n if (val === undefined) return\n if (val === this.children) return\n this.children = val\n this.getLayer().reflowElement(this)\n }\n}\n","import View from './view'\nimport STYLES from './constants'\nimport { isExact, isAuto, isWX } from './utils'\nimport { getImage } from './weapp-adapter'\n\nexport default class $Image extends View {\n\n constructor(options, children) {\n super(options, children)\n this.type = 'image'\n this._imageInfo = {\n width: 0,\n height: 0,\n sx: 0,\n sy: 0,\n swidth: 0,\n sheight: 0,\n dx: 0,\n dy: 0,\n dwidth: 0,\n dheight: 0\n }\n this.debugColor = 'blue'\n this._image = null\n this._layout = null\n }\n\n init() {\n super.init()\n if(this.options && this.options.attrs && this.options.attrs.timeout){\n setTimeout(() => {\n this._loadImage()\n },this.options.attrs.timeout || 0)\n }else{\n this._loadImage()\n }\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawImage(this)\n this.getRender()._drawBox(this)\n }\n\n _loadImage() {\n const { mode } = this.options.attrs\n\n return new Promise((resolve, reject) => {\n this.getRender().getImageInstance(this.options.attrs.src)\n .then(({ info, image }) => {\n this._imageInfo = info\n this._image = image\n resolve()\n\n this._layoutImage()\n\n if (this.isVisible()) {\n // if (mode === 'aspectFill' || mode === 'aspectFit') {\n // // this.getLayer().onElementChange(this)\n // this.getLayer().repaint(this)\n // } else {\n // // 重新布局绘制\n this.getLayer().reflowElement(this)\n // }\n }\n\n // call load callback\n if (this.options.on && this.options.on.load) {\n this.options.on.load(this)\n }\n })\n .catch(err => {\n // call error callback\n if (this.options.on && this.options.on.error) {\n this.options.on.error(err)\n }\n })\n })\n }\n\n // 计算图片布局\n _layoutImage() {\n const { contentWidth, contentHeight } = this.renderStyles\n const { mode } = this.options.attrs\n const { width, height } = this.styles\n const { width: imageW, height: imageH } = this._imageInfo\n // 根据用户设置判断图片宽高,目前支持widthfix、heightfix、平铺\n let w = contentWidth\n let h = contentHeight\n if (!isAuto(width) && isAuto(height)) {\n // width fix\n w = contentWidth\n h = getHeightByWidth(w, imageW, imageH)\n } else if (!isAuto(height) && isAuto(width)) {\n // height fix\n h = contentHeight\n w = getWidthByHeight(h, imageW, imageH)\n } else if (isAuto(width) && isAuto(height)) {\n // auto\n w = imageW\n h = imageH\n } else if (mode === 'aspectFill') {\n // 填充\n if ((w / h) > (imageW / imageH)) {\n this._imageInfo.swidth = imageW\n this._imageInfo.sheight = getHeightByWidth(imageW, w, h)\n this._imageInfo.sx = 0\n this._imageInfo.sy = (imageH - this._imageInfo.sheight) / 2\n } else {\n this._imageInfo.sheight = imageH\n this._imageInfo.swidth = getWidthByHeight(imageH, contentWidth, contentHeight)\n this._imageInfo.sy = 0\n this._imageInfo.sx = (imageW - this._imageInfo.swidth) / 2\n }\n } else if (mode === 'aspectFit') {\n if ((w / h) > (imageW / imageH)) {\n this._imageInfo.dwidth = getWidthByHeight(contentHeight, imageW, imageH)\n this._imageInfo.dheight = contentHeight\n this._imageInfo.dy = this.contentY\n this._imageInfo.dx = (contentWidth - this._imageInfo.dwidth) / 2 + this.contentX\n } else {\n this._imageInfo.dheight = getHeightByWidth(contentWidth, imageW, imageH)\n this._imageInfo.dwidth = contentWidth\n this._imageInfo.dx = this.contentX\n this._imageInfo.dy = (contentHeight - this._imageInfo.dheight) / 2 + this.contentY\n }\n } else {\n w = contentWidth\n h = contentHeight\n }\n this._layout = { width: w, height: h }\n }\n\n _measureLayout() {\n if (this._layout) {\n return this._layout\n } else {\n return {\n width: this.renderStyles.width,\n height: this.renderStyles.height\n }\n }\n }\n\n}\n\n\nfunction getWidthByHeight(height, originWidth, originHeight) {\n return height / originHeight * originWidth\n}\n\nfunction getHeightByWidth(width, originWidth, originHeight) {\n return width / originWidth * originHeight\n}\n","import TreeNode from './tree-node'\nimport { walkParent, walk } from './utils'\nconst events = ['click','touchstart','touchmove','touchend','mousewheel']\nexport default class EventManager {\n\n constructor({ simulateClick = true }) {\n this.EVENTS = events\n this.clear()\n this.touchStartEvent = null\n this.simulateClick = simulateClick // 是否模拟移动端点击事件\n }\n\n clear() {\n events.forEach(eventName => {\n this[`${eventName}Tree`] = new TreeNode()\n this[`${eventName}List`] = []\n })\n }\n\n click(x, y) {\n let event = new Event({ x, y, type: 'click' })\n this._emit(event)\n }\n\n touchstart(x, y) {\n let event = new Event({ x, y, type: 'touchstart' })\n this.touchStartEvent = event\n this._emit(event)\n }\n\n touchmove(x, y) {\n let event = new Event({ x, y, type: 'touchmove' })\n this._emit(event)\n }\n\n touchend(x, y) {\n let event = new Event({ x, y, type: 'touchend' })\n this._emit(event)\n this.checkClick(event)\n }\n\n mousewheel(x,y,deltaX,deltaY){\n let event = new Event({ x, y,deltaX,deltaY, type: 'mousewheel' })\n this._emit(event)\n }\n\n _emit(e) {\n let tree = this[`${e.type}Tree`]\n if(!tree) return\n\n /**\n * 遍历树,检查是否回调\n * 如果父级没有被触发,则子级也不需要检查,跳到下个同级节点\n * 执行capture回调,将on回调添加到stack\n */\n let callbackList = []\n let curArr = tree._getChildren()\n while (curArr.length) {\n walkArray(curArr, (node, callBreak, isEnd) => {\n if (node.element.isVisible() && this.isPointInElement(e.relativeX, e.relativeY, node.element)) {\n node.runCapture(e)\n callbackList.unshift(node)\n // 同级后面节点不需要执行了\n callBreak()\n curArr = node._getChildren()\n } else if (isEnd) {\n // 到最后一个还是没监测到,结束\n curArr = []\n }\n })\n }\n\n /**\n * 执行on回调,从子到父\n */\n for (let i = 0; i < callbackList.length; i++) {\n if (!e.currentTarget) e.currentTarget = callbackList[i].element\n callbackList[i].runCallback(e)\n if (e.cancelBubble) break\n }\n }\n\n // 待优化\n isPointInElement(x, y, element) {\n let a1 = x >= element.x\n let a2 = y >= element.y\n let a3 = (x <= (element.x + element.renderStyles.width))\n let a4 = (y <= (element.y + element.renderStyles.height))\n if (a1 && a2 && a3 && a4) {\n return true\n }\n return false\n }\n\n\n removeElement(element) {\n events.forEach(eventName => {\n this[`${eventName}List`] = this[`${eventName}List`].filter(item => {\n if (item.element === element) {\n item.remove()\n }\n return item.element !== element\n })\n })\n }\n\n addEventListener(type,callback,element,isCapture){\n const tree = this[`${type}Tree`]\n const list = this[`${type}List`]\n if(!tree){\n console.error('Unknown event name [' + type+']')\n }\n this.addCallback(callback,element,tree,list,isCapture)\n }\n\n /**\n * 不在文档流中,提到relativeTo同级\n * 根据element树的层级关系构建一个监听回调树模型,提高性能\n * 有新的监听时,查找应该挂载在哪个节点\n * 如果节点已经存在,复用原节点\n * @param {Function} callback\n * @param {Element} element\n * @param {Callback} tree\n * @param {Array} list\n * @param {Boolean} isCapture\n */\n addCallback(callback, element, tree, list, isCapture) {\n let parent = null\n let node = null\n // 寻找应该挂载的父节点\n let target = element\n for (let i = list.length - 1; i >= 0; i--) {\n // 寻找已存在节点\n if (element === list[i].element) {\n // 当前\n parent = list[i - 1]\n node = list[i]\n break\n }\n // 寻找应该挂载的父节点 通过对比当前父级最近的父级\n if (!element.isInFlow()) {\n target = element.relativeTo.parent\n if (!target) {\n break\n }\n }\n walkParent(target, (p, callBreak) => {\n if (p === list[i].element) {\n parent = list[i]\n callBreak()\n }\n })\n if (parent) {\n break\n }\n }\n\n // 如果不存在同样的元素节点\n if (!node) {\n node = new Callback(element, callback)\n }\n\n // 添加回调方法\n if (isCapture) {\n node.addCapture(callback)\n } else {\n node.addCallback(callback)\n }\n\n // 挂载节点\n if (parent) {\n // 用prepend是因为后来的层级上高于前面的,但是只有在absolute的元素才能感受到\n parent.prependChild(node)\n } else {\n tree.prependChild(node)\n }\n\n // 缓存到list\n list.push(node)\n }\n\n // 这里利用touchstart和touchend实现了移动端click事件\n checkClick(event) {\n if (this.touchStartEvent && this.simulateClick) {\n // 判断两点距离\n let { x: startx, y: starty } = this.touchStartEvent\n let { x: endx, y: endy } = event\n let distance = ((endy * endy + endx * endx) - (starty * starty + startx * startx))\n if (distance < 5 && distance > -5) {\n this.click(endx, endy)\n }\n }\n }\n}\n\nclass Event {\n constructor({ x, y, type,deltaX,deltaY }) {\n this.x = x\n this.y = y\n this.relativeX = x // scroll到每一层scrollview会不断变化\n this.relativeY = y\n this.type = type\n this.cancelBubble = false\n this.currentTarget = null // 第一个element\n\n if(type === 'mousewheel'){\n this.deltaX = deltaX\n this.deltaY = deltaY\n }\n }\n\n // 阻止冒泡\n stopPropagation() {\n this.cancelBubble = true\n }\n}\n\nclass Callback extends TreeNode {\n constructor(element) {\n super()\n this.element = element\n this.callbackList = []\n this.captureList = []\n }\n\n addCallback(callback) {\n this.callbackList.push(callback)\n }\n\n addCapture(callback) {\n this.captureList.push(callback)\n }\n\n runCallback(params) {\n this.callbackList.forEach(item => item.call(this.element,params))\n }\n\n runCapture(params) {\n this.captureList.forEach(item => item.call(this.element,params))\n }\n\n}\n\n\nfunction walkArray(arr, callback) {\n let _break = false\n const callBreak = () => _break = true\n for (let i = 0; i < arr.length; i++) {\n callback(arr[i], callBreak, i === arr.length - 1 ? true : false)\n if (_break) {\n break\n }\n }\n}\n","import { isExact, walk, isOuter, parseOuter, walkParent, isEndNode, isAuto, isWX, qSort3, getThrottle, floor } from './utils'\nimport TreeNode from './tree-node'\nimport STYLES from './constants'\nimport { getImage } from './weapp-adapter'\n\nconst angle = Math.PI / 2\n\n/**\n * 封装图形api\n */\nexport default class CanvasRender {\n constructor(layer) {\n this.layer = layer\n this.imageBus = {}\n this.isAnimate = false\n this.lastPaintTime = 0\n this.lastFrameComplete = false\n this.throttle = getThrottle(16)\n }\n\n isDebug(){\n return this.getLayer().options && this.getLayer().options.debug\n }\n\n getCtx() {\n return this.layer.ctx\n }\n\n getLayer() {\n return this.layer\n }\n\n _restore(callback) {\n this.getCtx().save()\n callback()\n this.getCtx().restore()\n }\n\n _path(callback) {\n this.getCtx().beginPath()\n callback()\n this.getCtx().closePath()\n }\n\n paint(element) {\n this.getCtx().save()\n\n element._paint(this.lastPaintTime)\n\n this.afterPaint(element)\n }\n\n afterPaint(element) {\n // 这里通过this.ctx栈实现了overflow\n // 第一步判断没有子元素,绘制完成即restore 有子元素需要子元素全部绘制完毕再restore\n if (!element.hasChildren() || element.type === 'text') {\n this.getCtx().restore()\n }\n\n // 如果到了层级的最后一个 释放父级的stack\n this._helpParentRestoreCtx(element)\n }\n\n _helpParentRestoreCtx(element) {\n if ((element.isVisible() && !isEndNode(element)) || (!element.isVisible() && element.next)) return\n this.getCtx().restore()\n let cur = element.parent\n while (cur && !cur.next) {\n // 如果父级也是同级最后一个,再闭合上一个\n this.getCtx().restore()\n cur = cur.parent\n }\n\n\n }\n\n topBorder({ x, y, borderRadius, w, h }) {\n // 左上角开始\n this.getCtx().moveTo(x, y + borderRadius)\n borderRadius && this.getCtx().arc(x + borderRadius, y + borderRadius, borderRadius, 2 * angle, 3 * angle)\n this.getCtx().lineTo(x + w - borderRadius, y)\n }\n\n rightBorder({ x, y, borderRadius, w, h }) {\n // 右上角\n // this.getCtx().moveTo(x + w - borderRadius, y)\n borderRadius && this.getCtx().arc(x + w - borderRadius, y + borderRadius, borderRadius, 3 * angle, 4 * angle)\n this.getCtx().lineTo(x + w, y + h - borderRadius)\n }\n\n bottomBorder({ x, y, borderRadius, w, h }) {\n // 右下角\n // this.getCtx().moveTo(x + w, y + h - borderRadius)\n borderRadius && this.getCtx().arc(x + w - borderRadius, y + h - borderRadius, borderRadius, 0, angle)\n this.getCtx().lineTo(x + borderRadius, y + h)\n }\n\n leftBorder({ x, y, borderRadius, w, h }) {\n // 左下角\n borderRadius && this.getCtx().arc(x + borderRadius, y + h - borderRadius, borderRadius, angle, angle * 2)\n this.getCtx().lineTo(x, y + borderRadius)\n }\n\n _drawBox(element) {\n if (!(element.renderStyles.borderColor || element.renderStyles.shadowBlur)) return\n const { contentWidth, contentHeight, paddingLeft, paddingTop, borderStyle,\n paddingRight, paddingBottom, shadowBlur, shadowColor, backgroundColor, shadowOffsetX, shadowOffsetY,\n borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth, borderWidth } = element.renderStyles\n\n let borderRadius = getBorderRadius(element)\n\n\n // 这里是计算画border的位置,起点位置是在线条中间,所以要考虑线条宽度\n let x = element.contentX - element.renderStyles.paddingLeft - borderLeftWidth / 2\n let y = element.contentY - element.renderStyles.paddingTop - borderTopWidth / 2\n let w = contentWidth + paddingLeft + paddingRight + (borderLeftWidth + borderRightWidth) / 2\n let h = contentHeight + paddingTop + paddingBottom + (borderTopWidth + borderBottomWidth) / 2\n\n this.getCtx().lineCap = element.renderStyles.lineCap\n this.getCtx().strokeStyle = element.renderStyles.borderColor\n this.getCtx().lineJoin = 'round'\n\n // 实现虚线\n if (borderStyle && borderStyle !== 'solid') {\n if (Array.isArray(borderStyle)) {\n this.getCtx().setLineDash(borderStyle)\n } else {\n this.getCtx().setLineDash([5, 5])\n }\n }\n\n const stroke = (borderWidth) => {\n // 有样式则绘制出来\n this.getCtx().lineWidth = borderWidth\n this.getCtx().stroke()\n }\n this._restore(() => {\n this._path(() => {\n\n if (element.renderStyles.borderTopWidth) {\n this.topBorder({ x, y, borderRadius: borderRadius ? borderRadius + (element.renderStyles.borderTopWidth / 2) : 0, w, h })\n // 判断borderwidth 如果都是一样宽,只需要最后一次性绘制,提高性能\n !borderWidth && stroke(element.renderStyles.borderTopWidth)\n }\n if (element.renderStyles.borderRightWidth) {\n this.getCtx().moveTo(x + w - borderRadius - (borderRadius ? (element.renderStyles.borderTopWidth / 2) : 0), y)\n this.rightBorder({ x, y, borderRadius: borderRadius ? borderRadius + element.renderStyles.borderRightWidth / 2 : 0, w, h })\n !borderWidth && stroke(element.renderStyles.borderRightWidth)\n }\n if (element.renderStyles.borderBottomWidth) {\n this.getCtx().moveTo(x + w, y + h - borderRadius - (borderRadius ? (element.renderStyles.borderRightWidth / 2) : 0))\n this.bottomBorder({ x, y, borderRadius: borderRadius ? borderRadius + (element.renderStyles.borderBottomWidth / 2) : 0, w, h })\n !borderWidth && stroke(element.renderStyles.borderBottomWidth)\n }\n if (element.renderStyles.borderLeftWidth) {\n this.getCtx().moveTo(x + borderRadius + (borderRadius ? (element.renderStyles.borderBottomWidth / 2) : 0), y + h)\n this.leftBorder({ x, y, borderRadius: borderRadius ? borderRadius + (element.renderStyles.borderLeftWidth / 2) : 0, w, h })\n stroke(element.renderStyles.borderLeftWidth)\n }\n })\n })\n\n }\n\n _drawBackground(element) {\n const { backgroundColor, contentWidth, contentHeight, shadowColor, shadowBlur,\n paddingLeft, paddingRight, paddingTop, paddingBottom, opacity, shadowOffsetX, shadowOffsetY,\n borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = element.renderStyles\n const ctx = this.getCtx()\n\n let borderRadius = getBorderRadius(element)\n\n\n // 这里是计算画border的位置,起点位置是在线条中间,所以要考虑线条宽度\n let x = element.contentX - element.renderStyles.paddingLeft - borderLeftWidth\n let y = element.contentY - element.renderStyles.paddingTop - borderTopWidth\n let w = contentWidth + paddingLeft + paddingRight + (borderLeftWidth + borderRightWidth)\n let h = contentHeight + paddingTop + paddingBottom + (borderTopWidth + borderBottomWidth)\n\n if (isExact(opacity)) {\n // 绘制透明图\n ctx.globalAlpha = opacity\n }\n\n // 绘制boxshadow\n // 需要在clip之前\n if (shadowColor && shadowBlur) {\n this._restore(() => {\n this._path(() => {\n this.topBorder({ x, y, borderRadius, w, h })\n this.rightBorder({ x, y, borderRadius, w, h })\n this.bottomBorder({ x, y, borderRadius, w, h })\n this.leftBorder({ x, y, borderRadius, w, h })\n })\n if (isExact(shadowOffsetX)) {\n this.getCtx().shadowOffsetX = shadowOffsetX\n }\n if (isExact(shadowOffsetY)) {\n this.getCtx().shadowOffsetY = shadowOffsetY\n }\n this.getCtx().shadowBlur = shadowBlur\n this.getCtx().shadowColor = shadowColor\n this.getCtx().fillStyle = shadowColor\n this.getCtx().fill()\n })\n }\n\n this._clip(element)\n\n\n\n // draw background\n if (backgroundColor) {\n this.getCtx().fillStyle = this._parseBackground(backgroundColor, element)\n this.getCtx().fillRect(element.contentX - paddingLeft, element.contentY - paddingTop, contentWidth + paddingLeft + paddingRight, contentHeight + paddingTop + paddingBottom)\n }\n\n // for debug\n if (this.isDebug()) {\n this.getCtx().strokeStyle = element.debugColor || 'green'\n this.getCtx().strokeRect(element.contentX, element.contentY, element.renderStyles.contentWidth, element.renderStyles.contentHeight)\n // ctx.strokeStyle = '#fff'\n // ctx.strokeText(`${parseInt(this.contentX)} ${parseInt(this.contentY)} ${contentWidth} ${contentHeight}`, this.contentX + 100, this.contentY + 10)\n\n //\n }\n }\n\n _clip(element) {\n if (element.renderStyles.overflow !== 'hidden') return\n const { contentWidth, contentHeight, paddingLeft, paddingTop,\n paddingRight, paddingBottom, shadowBlur, shadowColor, backgroundColor,\n borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = element.renderStyles\n\n const angle = Math.PI / 2\n\n let borderRadius = getBorderRadius(element)\n\n // 为了把border也切进去\n let x = element.contentX - element.renderStyles.paddingLeft - borderLeftWidth\n let y = element.contentY - element.renderStyles.paddingTop - borderTopWidth\n let w = contentWidth + paddingLeft + paddingRight + borderLeftWidth + borderRightWidth\n let h = contentHeight + paddingTop + paddingBottom + borderTopWidth + borderBottomWidth\n\n this._path(() => {\n this.topBorder({ x, y, borderRadius, w, h })\n this.rightBorder({ x, y, borderRadius, w, h })\n this.bottomBorder({ x, y, borderRadius, w, h })\n this.leftBorder({ x, y, borderRadius, w, h })\n })\n\n\n this.getCtx().clip()\n\n }\n\n _parseBackground(color, element) {\n if (Array.isArray(color)) {\n const gradient = this.getCtx().createLinearGradient(element.contentX, element.contentY, element.contentX+element.renderStyles.contentWidth, element.contentY+element.renderStyles.contentHeight)\n for (let i = 0; i < color.length; i++) {\n if (i === 0) {\n gradient.addColorStop(0, color[0])\n } else {\n gradient.addColorStop(i / (color.length - 1), color[i])\n }\n }\n return gradient\n } else {\n return color\n }\n }\n\n\n _drawText(element) {\n const { color, contentWidth, lineHeight, textAlign, textIndent, textDecoration } = element.renderStyles\n let x = element.contentX\n this.getCtx().fillStyle = color\n this.getCtx().textAlign = textAlign\n this.getCtx().font = element._getFont()\n this.getCtx().textBaseline = 'top'\n if (textAlign === STYLES.TEXT_ALIGN.RIGHT) {\n x = element.contentX + contentWidth\n } else if (textAlign === STYLES.TEXT_ALIGN.CENTER) {\n x = element.contentX + (contentWidth / 2)\n }\n let _x = x\n let _y = 0\n element._lines.forEach((line, index) => {\n if (index === 0 && textIndent) {\n // 第一行实现textIndent\n _x = x + textIndent\n } else {\n _x = x\n }\n _y = (element.contentY + ((lineHeight - element._layout.fontHeight) / 2) + lineHeight * index)\n if(this.isDebug()){\n this.getCtx().fillRect(_x,_y,2,2)\n }\n this.getCtx().fillText(line.text, _x, _y)\n if (isWX() && element.renderStyles.fontWeight !== 400) {\n // 小程序 字体加粗不生效\n const offset = element.renderStyles.fontSize * 0.001\n this.getCtx().fillText(line.text, _x - offset, _y)\n }\n // draw decoration\n if (textDecoration) {\n const decorationType = textDecoration[0]\n _y += 1\n this._restore(() => {\n this._path(() => {\n let decorationY = _y\n if (decorationType === 'underline') {\n decorationY = _y + lineHeight - (lineHeight - element._layout.fontHeight) / 2\n } else if (decorationType === 'line-through') {\n decorationY = _y + element._layout.fontHeight / 2\n }\n this.getCtx().moveTo(_x, decorationY)\n this.getCtx().lineTo(_x + line.layout.width, decorationY)\n })\n this.getCtx().strokeStyle = color\n this.getCtx().stroke()\n })\n }\n })\n }\n\n /**\n * @param {String} text\n * @return {Object}\n */\n measureText(element, text) {\n let w = 0\n let h = 0\n this._restore(() => {\n this.getCtx().font = element._getFont()\n const { width,fontBoundingBoxAscent } = this.getCtx().measureText(text)\n w = width\n h = fontBoundingBoxAscent || element.renderStyles.fontSize * 0.8\n })\n return {\n width: w,\n fontHeight:h\n }\n }\n\n _drawImage(element) {\n if (!element._image) return\n const { contentWidth, contentHeight } = element.renderStyles\n const { mode } = element.options.attrs\n const { sx, sy, swidth, sheight, dx, dy, dwidth, dheight, width: imageW, height: imageH } = element._imageInfo\n if (mode === 'aspectFill') {\n this.getCtx().drawImage(element._image, sx, sy, swidth, sheight, element.contentX, element.contentY, contentWidth, contentHeight)\n } else if (mode === 'aspectFit') {\n this.getCtx().drawImage(element._image, 0, 0, imageW, imageH, dx, dy, dwidth, dheight)\n } else {\n this.getCtx().drawImage(element._image, element.contentX, element.contentY, contentWidth, contentHeight)\n }\n }\n\n _drawScroll(element) {\n this.getCtx().translate(element.currentScrollX, element.currentScrollY)\n }\n\n /**\n * 这里应该保证onload src等接口\n */\n getImageInstance(src) {\n let image = null\n\n // 同样的路径返回缓存\n if (this.imageBus[src]) {\n image = this.imageBus[src]\n } else {\n\n if (isWX()) {\n if (this.getCanvas()) {\n image = this.getCanvas().createImage()\n } else {\n console.warn('小程序请使用设置canvas参数以创建图片')\n image = getImage(src)\n }\n } else {\n image = new Image()\n }\n\n if (src) {\n this.imageBus[src] = new Promise((resolve, reject) => {\n image.onload = (e) => {\n resolve({\n image: isWX() && !this.getCanvas() ? e.image : image,\n info: {\n width: isWX() ? image.width : e.target.width,\n height: isWX() ? image.height : e.target.height\n }\n })\n }\n image.onerror = (err) => {\n reject(err)\n }\n })\n }\n\n image.src = src\n }\n return this.imageBus[src]\n }\n\n render(node) {\n this.lastFrameComplete = false\n this.lastPaintTime = Date.now()\n if (!node.parent) {\n // root\n this.getCtx().clearRect(0, 0, this.getLayer().options.width, this.getLayer().options.height)\n } else {\n this.getCtx().clearRect(node.x, node.y, node.renderStyles.width, node.renderStyles.height)\n }\n let element = null\n walk(node, (renderNode, callContinue, callNext) => {\n if (renderNode.isVisible()) {\n // 可见的才渲染\n this.paint(renderNode)\n } else {\n // 跳过整个子节点\n callNext()\n this._helpParentRestoreCtx(renderNode)\n }\n })\n if (isWX()) {\n // 兼容小程序\n this.getCtx().draw && this.getCtx().draw()\n }\n\n this.lastFrameComplete = true\n\n }\n\n renderFPS() {\n\n }\n\n readyToRender(element) {\n\n // this.element = generateRenderTree(element)\n this.element = element\n\n const options = this.getLayer().options\n\n this.lastPaintTime = Date.now()\n\n if (options && options.animate) {\n this.animate()\n } else {\n this.render(this.element)\n }\n\n }\n\n requestRepaint(element) {\n if (this.isAnimate) return\n // 如果已经有frame在排队等待了 忽略\n // if(!this.lastFrameComplete) return\n // let nextFrameTime = Date.now() - this.lastPaintTime\n // if(nextFrameTime < 16){\n // setTimeout(() => this.render(this.element),nextFrameTime)\n // }else{\n this.render(this.element)\n // }\n\n }\n\n // could be null\n getCanvas() {\n const options = this.getLayer().options\n return options && options.canvas || null\n }\n\n _animate(preTime) {\n const now = Date.now()\n this.render(this.element)\n if (!this.isAnimate) return\n window.requestAnimationFrame(() => this._animate(now))\n }\n\n /**\n * 不建议使用了\n */\n animate() {\n this.isAnimate = true\n window.requestAnimationFrame(() => this._animate())\n }\n\n stopAnimate() {\n this.isAnimate = false\n }\n\n // 所有副作用完成\n // 图片加载异步请求\n onEffectFinished() {\n const list = Object.keys(this.imageBus).map(key => {\n return this.imageBus[key]\n })\n return Promise.all(list)\n }\n\n\n\n}\n\nfunction getBorderRadius(element) {\n const { paddingWidth, paddingHeight } = element.renderStyles\n let { borderRadius } = element.renderStyles\n if (borderRadius * 2 > paddingWidth) {\n // 如果大于一半,则角不是90度,统一限制最大为一半\n borderRadius = paddingWidth / 2\n }\n if (borderRadius * 2 > paddingHeight) {\n borderRadius = paddingHeight / 2\n }\n if (borderRadius < 0) borderRadius = 0\n return floor(borderRadius)\n}\n\n// function generateRenderTree(element){\n// const _root = new RenderNode(element)\n// let preZ = 0\n// let pivotZ = 0\n// let cur = null\n// let stack = [_root]\n// while(stack.length){\n// cur = stack.pop()\n// if(cur.element.hasChildren()){\n// cur.children = cur.element._getChildren().map(item => new RenderNode(item))\n// // sort by zIndex\n// cur.children = qSort3(cur.children,(pre,pivot) => {\n// preZ = pre.element.renderStyles.zIndex || 0\n// pivotZ = pivot.element.renderStyles.zIndex || 0\n// return preZ - pivotZ\n// })\n// Array.prototype.push.apply(stack,cur.children)\n// }\n// }\n// TreeNode.connectChildren(_root)\n// return _root\n// }\n\n// class RenderNode extends TreeNode {\n// constructor(element){\n// super()\n// this.element = element\n// }\n// }\n","import { isWX } from \"./utils\"\n\n// 只支持小程序最新的支持同层渲染的canvas api,\n// 不用了\nexport function getImage(url) {\n const instance = {onload: () => {}}\n new Promise((resolve, reject) => {\n wx.downloadFile({\n url:url,\n success(res) {\n wx.getImageInfo({\n src: res.tempFilePath,\n success(res1) {\n resolve({\n target: {\n width: res1.width,\n height: res1.height\n },\n image: res.tempFilePath\n })\n }\n })\n },\n fail(err) {\n reject(err)\n }\n })\n })\n .then((res) => {\n instance.onload(res)\n })\n .catch(err => {\n\n })\n return instance\n}\n\n","import EventManager from './event-manager'\nimport { walk, breadthFirstSearch, breadthFirstSearchRight, walkParent, isWX } from './utils'\nimport TreeNode from './tree-node'\nimport CanvasRender from './canvas-render'\nexport default class Layer {\n constructor(ctx, options) {\n this.ctx = ctx\n this.node = null\n this.isAnimate = false\n this.nodeList = []\n this.p2cList = []\n this.c2pList = []\n this.renderList = []\n this.options = options\n this.eventManager = new EventManager(options)\n this.render = new CanvasRender(this)\n }\n\n update(ctx, options) {\n this.ctx = ctx\n this.options = options\n this.options.renderStyles = options\n this.node.container = this.options\n }\n\n mountNode(node) {\n this.node = node\n this.node.root = this.node\n this.node.layer = this\n this.node.container = this.options\n // 事件也清空一下,重新挂载\n this.eventManager.clear()\n this.initRender()\n }\n\n initRender() {\n // for 打印耗时\n const startTime = Date.now()\n\n TreeNode.connectChildren(this.node)\n this.initP2CList()\n this.initC2PList()\n\n this.flow()\n\n // flow 完成后监听effect完成\n this.render.onEffectFinished()\n .then((res) => this.lifecycle('onEffectSuccess', res))\n .catch((res) => this.lifecycle('onEffectFail', res))\n // .finally((res) => this.lifecycle('onEffectFinished', res))\n\n this.repaint()\n\n console.log(`渲染${this.p2cList.length}个元素 耗时 ${(Date.now() - startTime)} ms`)\n }\n\n initP2CList() {\n // 广度优先\n this.p2cList = breadthFirstSearch(this.node)\n }\n\n initC2PList() {\n this.c2pList = breadthFirstSearchRight(this.node)\n }\n\n\n flow(node = this.node) {\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i].init()\n }\n\n this.reflow()\n }\n\n initPaintList() {\n // 这里实现index\n this.renderList = this.nodeList\n }\n\n reflow(node = this.node) {\n\n for (let i = 0; i < this.c2pList.length; i++) {\n this.c2pList[i]._initWidthHeight()\n }\n\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i]._initPosition()\n }\n }\n\n reflowElement(element) {\n // 如果有line,则需要重第一个开始\n let target = element\n while (target && target.line) {\n target = target.parent\n }\n const p2cList = breadthFirstSearch(target)\n for (let i = 0; i < p2cList.length; i++) {\n p2cList[i]._initStyles()\n }\n\n // 所有子元素\n const children = breadthFirstSearchRight(target)\n for (let i = 0; i < children.length; i++) {\n children[i]._initWidthHeight()\n }\n\n if (!element.isInFlow()) {\n for (let i = 0; i < p2cList.length; i++) {\n p2cList[i]._initPosition()\n }\n this.repaint()\n } else {\n this.onElementChange(target)\n }\n\n\n }\n\n onElementRemove(element) {\n this.eventManager.removeElement(element)\n this.initC2PList()\n this.initP2CList()\n this.reflowElement(element)\n }\n\n onElementAdd(element) {\n TreeNode.connectChildren(element)\n this.initC2PList()\n this.initP2CList()\n breadthFirstSearch(element).forEach(item => item.init())\n this.reflowElement(element)\n }\n\n // 元素变化后调用,尽可能少重排重绘\n onElementChange(element) {\n\n walkParent(element, (parent, callbreak) => {\n parent._initWidthHeight()\n if (parent.type === 'scroll-view') callbreak()\n })\n\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i]._initPosition()\n }\n this.repaint()\n }\n\n callBeforePaint() {\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i].beforePaint && this.p2cList[i].beforePaint()\n }\n }\n\n /**\n * 可以给定element,则只会重绘element所在的区域\n * @param {Element} element\n */\n repaint(element = this.node) {\n if (isWX()) {\n // 微信环境下始终重绘整个树\n element = this.node\n }\n if (!element.isInFlow()) element = this.node\n\n this.callBeforePaint()\n\n this.render.readyToRender(this.node)\n }\n\n animate() {\n console.warn('use [animate] option instead!')\n }\n\n getElementBy() {\n return this.node.getElementBy(...arguments)\n }\n\n lifecycle(name, arg) {\n if (this.options.lifecycle) {\n this.options.lifecycle[name] && this.options.lifecycle[name](arg)\n }\n }\n\n}\n\n\n","import View from './view'\nimport { easeInOutElastic, isExact, isAuto, floor } from './utils'\nimport STYLES from './constants'\n\nexport default class ScrollView extends View {\n\n constructor(options, children) {\n const { styles, ...rest } = options\n super(rest, children)\n this.options.styles = {\n direction: styles.direction || 'y'\n }\n // 外面包裹一层容器,内层的滚动\n options.styles.overflow = 'hidden'\n this.type = 'scroll-view'\n this._scrollView = new View(options, [this])\n this._scrollView.type = 'scroll-view-container'\n this.visibleIndex = null\n this.renderOnDemand = options.attrs && options.attrs.renderOnDemand || false\n return this._scrollView\n }\n\n _getDefaultStyles() {\n return {\n ...STYLES.DEFAULT_STYLES,\n direction: 'y',\n }\n }\n\n beforePaint() {\n this.initChildrenVisible()\n }\n\n _initWidthHeight() {\n super._initWidthHeight()\n // 这里需要父级款高度,但是外层必须是exact\n this.initScroll()\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawScroll(this)\n this.getRender()._drawBox(this)\n }\n\n init() {\n super.init()\n this.addEventListener()\n const { height, width } = this._scrollView.styles\n const { direction } = this.styles\n if (direction.match('y')) {\n if (isAuto(height)) {\n // 必须设置\n console.error('scroll-view 必须设置明确的高度')\n } else {\n this.styles.height = 'auto'\n this.renderStyles.height = 'auto'\n }\n }\n if (direction.match('x')) {\n if (isAuto(width)) {\n // 必须设置\n console.error('scroll-view 必须设置明确的宽度')\n } else {\n this.styles.width = 'auto'\n this.renderStyles.width = 'auto'\n }\n }\n }\n\n addEventListener() {\n // 监听滚动\n this.currentScrollX = 0\n this.currentScrollY = 0\n let direction = this.styles.direction\n let startX = 0\n let startY = 0\n let lastStartX = 0\n let lastStartY = 0\n let startMove = false\n let offsetX = 0\n let offsetY = 0\n let speedX = 0\n let speedY = 0\n let glideInterval = null\n let resistanceX = 1\n let resistanceY = 1\n\n this.getLayer().eventManager.EVENTS.forEach(eventName => {\n this.getLayer().eventManager.addEventListener(eventName, (e) => {\n if (direction.match('y')) {\n e.relativeY -= this.currentScrollY\n }\n if (direction.match('x')) {\n e.relativeX -= this.currentScrollX\n }\n }, this._scrollView, true)\n })\n\n this.getLayer().eventManager.addEventListener('mousewheel', (e) => {\n if (!this.scrollBy(e.deltaX, e.deltaY)) {\n this.scrollTo({ x: e.deltaX <= 0 ? this.maxScrollX : 0, y: e.deltaY <= 0 ? this.maxScrollY : 0 })\n } else {\n e.stopPropagation()\n }\n }, this._scrollView)\n\n this.getLayer().eventManager.addEventListener('touchstart', (e) => {\n e.stopPropagation()\n startX = e.x\n startY = e.y\n lastStartX = startX\n lastStartY = startY\n startMove = true\n clearInterval(glideInterval)\n }, this._scrollView)\n this.getLayer().eventManager.addEventListener('touchmove', (e) => {\n if (startMove) {\n e.stopPropagation()\n offsetX = (e.x - startX)\n offsetY = (e.y - startY)\n if (this.scrollBy(offsetX, offsetY)) {\n lastStartX = startX\n lastStartY = startY\n startX = e.x\n startY = e.y\n }\n }\n }, this._scrollView)\n this.getLayer().eventManager.addEventListener('touchend', (e) => {\n if (startMove) {\n startMove = false\n\n speedX = (e.x - lastStartX)\n speedY = (e.y - lastStartY)\n resistanceX = -speedX * 0.02\n resistanceY = -speedY * 0.02\n clearInterval(glideInterval)\n glideInterval = setInterval(() => {\n if (!this.scrollBy(speedX, speedY)) {\n this.scrollTo(this.currentScrollX + speedX, this.currentScrollY + speedY)\n clearInterval(glideInterval)\n }\n speedX += resistanceX\n speedY += resistanceY\n if (speedX * speedX <= 0.05 && speedY * speedY <= 0.05) {\n speedX = 0\n speedY = 0\n clearInterval(glideInterval)\n }\n }, 16)\n }\n }, this._scrollView)\n }\n\n initScroll() {\n const { contentWidth: offsetWidth, contentHeight: offsetHeight } = this._scrollView.renderStyles\n const { width: scrollWidth, height: scrollHeight, direction } = this.renderStyles\n this.maxScrollX = scrollWidth - offsetWidth\n this.maxScrollY = scrollHeight - offsetHeight\n }\n\n calcScrollBoundX(offsetX) {\n if ((- this.currentScrollX - offsetX) > this.maxScrollX) {\n return false\n } else if (this.currentScrollX + offsetX > 0) {\n return false\n }\n\n return true\n }\n\n calcScrollBoundY(offsetY) {\n if ((- this.currentScrollY - offsetY) > this.maxScrollY) {\n return false\n } else if (this.currentScrollY + offsetY > 0) {\n return false\n }\n\n return true\n }\n\n scrollByX(offsetX) {\n if (!this.renderStyles.direction.match('x')) return false\n if (this.calcScrollBoundX(offsetX)) {\n this.currentScrollX += offsetX\n return true\n } else {\n return false\n }\n }\n\n scrollByY(offsetY) {\n if (!this.renderStyles.direction.match('y')) return false\n if (this.calcScrollBoundY(offsetY)) {\n this.currentScrollY += floor(offsetY)\n this.calcChildrenVisible()\n // this.getLayer().repaint(this._scrollView)\n return true\n } else {\n return false\n }\n }\n\n scrollBy(offsetX, offsetY) {\n // 这里要两个都运行,所以不要用短路\n if (this.scrollByX(offsetX) | this.scrollByY(offsetY)) {\n this.getRender().requestRepaint(this._scrollView)\n return true\n }\n return false\n }\n\n scrollTo({ x, y }) {\n if (isExact(x) && this.maxScrollX > 0) {\n x = x\n if (x > this.maxScrollX) x = this.maxScrollX\n this.currentScrollX = -floor(x)\n }\n if (isExact(y) && this.maxScrollY > 0) {\n y = y\n if (y > this.maxScrollY) y = this.maxScrollY\n this.currentScrollY = -floor(y)\n }\n this.initChildrenVisible()\n this.getRender().requestRepaint(this._scrollView)\n }\n\n // TODO:\n initChildrenVisible() {\n if (!this.renderOnDemand) return\n\n // console.log('==============')\n const children = this._getChildrenInFlow()\n // 左\n for (let i = 0; i < children.length; i++) {\n if (this.isElementInViewport(children[i])) {\n this.visibleIndex = [i, -1]\n break\n } else {\n children[i].visible = false\n }\n }\n\n // 右\n for (let i = children.length - 1; i >= 0; i--) {\n if (this.isElementInViewport(children[i])) {\n this.visibleIndex[1] = i\n break\n } else {\n children[i].visible = false\n }\n }\n\n // 中间\n for (let i = this.visibleIndex[0]; i <= this.visibleIndex[1]; i++) {\n children[i].visible = true\n }\n }\n\n // 只用计算两头\n // 数据量时能显著提高效率\n // 滚动太快会有问题,暂时使用上面的init\n calcChildrenVisible() {\n if (!this.renderOnDemand) return\n const children = this._getChildrenInFlow()\n const head = generateSiblingNodeIndex(this.visibleIndex[0], 5)\n const foot = generateSiblingNodeIndex(this.visibleIndex[1], 5)\n let visibleIndex = []\n for (let i = head[0]; i <= head[head.length - 1]; i++) {\n if (children[i]) {\n if (this.isElementInViewport(children[i])) {\n children[i].visible = true\n if (!visibleIndex.length) {\n visibleIndex.push(i)\n }\n } else {\n children[i].visible = false\n }\n }\n }\n for (let i = foot[foot.length - 1]; i >= foot[0]; i--) {\n if (children[i]) {\n if (this.isElementInViewport(children[i])) {\n children[i].visible = true\n if (visibleIndex.length === 1) {\n visibleIndex.push(i)\n }\n } else {\n children[i].visible = false\n }\n }\n }\n this.visibleIndex = visibleIndex\n if (this.visibleIndex.length < 2) {\n this.initChildrenVisible()\n }\n }\n\n isElementInViewport(element) {\n if (this.styles.direction.match('y')) {\n return ((element.y + element.renderStyles.height + this.currentScrollY) > this._scrollView.contentY)\n && ((element.y + this.currentScrollY) < this._scrollView.contentY + this._scrollView.renderStyles.contentHeight)\n } else {\n return true\n // return ((element.x + element.renderStyles.width + this.currentScroll) > this._scrollView.contentX)\n // && ((element.x + this.currentScroll) < this._scrollView.contentX + this._scrollView.renderStyles.contentWidth)\n }\n }\n\n}\n\n\nfunction generateSiblingNodeIndex(index, offset) {\n let start = index - offset\n let end = index + offset\n let list = []\n for (let i = start; i <= end; i++) {\n list.push(i)\n }\n return list\n}\n","import View from './view'\nimport Text from './text'\nimport Image from './image'\nimport Layer from './layer'\nimport ScrollView from './scroll-view'\n\n/**\n * 生成一个element tree\n * @param {String} name\n * @param {Function} options\n */\n\nconst elementFactory = {}\n//\nregisterComponent('view', (options, children) => new View(options, children))\nregisterComponent('text', (options, children) => new Text(options, children))\nregisterComponent('image', (options, children) => new Image(options, children))\nregisterComponent('scroll-view', (options, children) => new ScrollView(options, children))\nregisterComponent('scrollview', (options, children) => new ScrollView(options, children))\n\nexport function createElement(model) {\n // 生成树\n function c(name, options = {}, children = []) {\n // if (arguments.length < 3) {\n // throw Error(`Element [${name}]: need 3 argument but get 2`)\n // }\n let _element = null\n let _children = children\n if (elementFactory[name]) {\n if (typeof children === 'string' && name !== 'text') {\n // 支持text简写\n _children = [new Text({}, children)]\n } else if (!Array.isArray(children) && name !== 'text') {\n throw Error(`Element [${name}]:Children must be type of Array!`)\n }\n _element = elementFactory[name](options, _children, c)\n } else {\n throw Error(`Unknown tag name [${name}] !`)\n }\n return _element\n }\n const _model = model(c)\n // 挂载children\n return _model\n}\n\nexport function createLayer(ctx, options) {\n return new Layer(ctx, options)\n}\n\n// 注册全局组件\nexport function registerComponent(name, factory) {\n if (elementFactory[name]) {\n throw Error(`Already exist tag name [${name}] !`)\n }\n elementFactory[name] = factory\n}\n\n\n\n\n\n","\nimport { createElement, createLayer, registerComponent } from './create-element'\nimport px from './px'\nimport './weapp-adapter'\nimport View from './view'\nimport Text from './text'\nimport Image from './image'\nimport Layer from './layer'\nimport ScrollView from './scroll-view'\nimport { mergeOptions } from './utils'\n\n\nconst ef = {\n createLayer,\n createElement,\n component: registerComponent,\n View,\n Text,\n Image,\n Layer,\n ScrollView,\n mergeOptions\n}\n\n\n\nexport default ef\n\n"],"names":["DISPLAY","BLOCK","INLINE_BLOCK","INLINE","FLEX","NONE","WIDTH","AUTO","OUTER","FLEX_DIRECTION","ROW","COLUMN","POSITION","ABSOLUTE","FIXED","RELATIVE","STATIC","DEFAULT_STYLES","display","fontSize","fontWeight","fontFamily","color","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","height","borderRadius","lineCap","flexDirection","verticalAlign","textAlign","justifyContent","alignItems","whiteSpace","zIndex","visible","position","TEXT_ALIGN","LEFT","RIGHT","CENTER","isExact","num","isAuto","isOuter","match","parseOuter","_n","parseInt","replace","isNaN","walk","element","callback","_continue","_next","_callContinue","_callNext","stack","push","length","item","pop","children","_getChildren","i","walkParent","cur","stop","callbreak","parent","isWX","Boolean","wx","getSystemInfoSync","err","breadthFirstSearch","node","nodes","queue","unshift","shift","_generateRender","breadthFirstSearchRight","reverse","mergeKeys","floor","val","Line","[object Object]","this","width","contentWidth","y","doorClosed","outerWidth","container","elements","start","end","offsetX","id","Math","random","el","initHeight","styles","Infinity","renderStyles","add","lineHeight","right","_getContainerLayout","contentX","x","getPreLine","initLayout","getOffsetY","line","refreshWidthHeight","next","closeLine","refreshXAlign","pre","_getPreLayout","contentY","KEY","STYLES","contentHeight","FlexBox","super","exactValue","flexTotal","key","calcFlex","flex","containerWidth","forEach","child","_refreshContentWithLayout","alignSelf","TreeNode","hasChildren","filter","map","index","_setParent","_setSibling","connectChildren","root","Array","isArray","treeNode","Error","indexOf","splice","removeChild","_completeFlex","isInFlow","_completeWidth","borderWidth","borderLeftWidth","borderRightWidth","borderBottomWidth","borderTopWidth","overflow","_completeBorder","_completeFont","padding","margin","_completePaddingMargin","Element","options","Object","assign","attrs","on","render","_initStyles","initEvent","keys","eventName","getLayer","eventManager","EVENTS","includes","addEventListener","removeElement","layer","mountNode","_getDefaultStyles","_getParentStyles","_completeStyles","_initRenderStyles","parentWidth","parentHeight","paddingWidth","paddingHeight","_getTotalBorderWidth","_getTotalBorderHeight","_InFlexBox","_bindFlexBox","relativeTo","findRelativeTo","curStyles","extendStyles","completeStyles","ctx","layout","_measureLayout","_refreshLayoutWithContent","_bindLine","refreshElementPosition","top","bottom","left","canIEnter","bind","_getChildrenInFlow","value","appendChild","onElementAdd","prependChild","onElementRemove","append","prepend","_needReflow","reflowElement","getRender","requestRepaint","View","type","_drawBackground","_drawBox","Text","_layout","_lines","debugColor","_drawText","measureText","_calcLine","textWidth","textHeight","parentContentWidth","text","lineIndex","lineText","lastLayout","maxLine","substring","undefined","$Image","_imageInfo","sx","sy","swidth","sheight","dx","dy","dwidth","dheight","_image","init","timeout","setTimeout","_loadImage","_drawImage","mode","Promise","resolve","reject","getImageInstance","src","then","info","image","_layoutImage","isVisible","load","catch","error","imageW","imageH","w","h","getHeightByWidth","getWidthByHeight","originWidth","originHeight","events","EventManager","simulateClick","clear","touchStartEvent","event","Event","_emit","checkClick","deltaX","deltaY","e","tree","callbackList","curArr","walkArray","callBreak","isEnd","isPointInElement","relativeX","relativeY","runCapture","currentTarget","runCallback","cancelBubble","a1","a2","a3","a4","remove","isCapture","list","console","addCallback","target","p","Callback","addCapture","startx","starty","endx","endy","distance","click","captureList","params","call","arr","_break","angle","PI","CanvasRender","imageBus","isAnimate","lastPaintTime","lastFrameComplete","throttle","threshold","timer","fn","getThrottle","debug","getCtx","save","restore","beginPath","closePath","_paint","afterPaint","_helpParentRestoreCtx","moveTo","arc","lineTo","borderColor","shadowBlur","borderStyle","shadowColor","backgroundColor","shadowOffsetX","shadowOffsetY","getBorderRadius","strokeStyle","lineJoin","setLineDash","stroke","lineWidth","_restore","_path","topBorder","rightBorder","bottomBorder","leftBorder","opacity","globalAlpha","fillStyle","fill","_clip","_parseBackground","fillRect","isDebug","strokeRect","clip","gradient","createLinearGradient","addColorStop","textIndent","textDecoration","font","_getFont","textBaseline","_x","_y","fontHeight","fillText","offset","decorationType","decorationY","fontBoundingBoxAscent","drawImage","translate","currentScrollX","currentScrollY","getCanvas","createImage","warn","url","instance","onload","downloadFile","res","getImageInfo","tempFilePath","res1","getImage","Image","onerror","Date","now","clearRect","renderNode","callContinue","callNext","paint","draw","animate","canvas","preTime","window","requestAnimationFrame","_animate","all","Layer","nodeList","p2cList","c2pList","renderList","initRender","startTime","initP2CList","initC2PList","flow","onEffectFinished","lifecycle","repaint","log","reflow","_initWidthHeight","_initPosition","onElementChange","beforePaint","callBeforePaint","readyToRender","getElementBy","arguments","name","arg","ScrollView","rest","direction","_scrollView","visibleIndex","renderOnDemand","initChildrenVisible","initScroll","_drawScroll","startX","startY","lastStartX","lastStartY","startMove","offsetY","speedX","speedY","glideInterval","resistanceX","resistanceY","scrollBy","stopPropagation","scrollTo","maxScrollX","maxScrollY","clearInterval","setInterval","offsetWidth","offsetHeight","scrollWidth","scrollHeight","calcScrollBoundX","calcScrollBoundY","calcChildrenVisible","scrollByX","scrollByY","isElementInViewport","head","generateSiblingNodeIndex","foot","elementFactory","registerComponent","factory","createLayer","createElement","model","c","_element","_children","component","mergeOptions","mergedOptions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"easy-canvas.min.js","sources":["../lib/constants.js","../lib/utils.js","../lib/line.js","../lib/flex-box.js","../lib/tree-node.js","../lib/complete-styles.js","../lib/element.js","../lib/view.js","../lib/text.js","../lib/image.js","../lib/event-manager.js","../lib/canvas-render.js","../lib/weapp-adapter.js","../lib/layer.js","../lib/scroll-view.js","../lib/create-element.js","../lib/index.js"],"sourcesContent":["const DISPLAY = {\n BLOCK: 'block',\n INLINE_BLOCK: 'inline-block',\n INLINE: 'inline', // 用户不能设置inline,text默认为inline\n FLEX: 'flex',\n NONE: 'none'\n}\n\nconst WIDTH = {\n AUTO: 'auto',\n OUTER: '100%'\n}\n\nconst POSITION = {\n ABSOLUTE: 'absolute',\n FIXED: 'fixed',\n RELATIVE: 'relative',\n STATIC: 'static'\n}\n\nconst TEXT_ALIGN = {\n LEFT: 'left',\n RIGHT: 'right',\n CENTER: 'center'\n}\n\nconst FLEX_DIRECTION = {\n ROW: 'row',\n COLUMN: 'column'\n}\n\nconst DEFAULT_STYLES = {\n display: DISPLAY.BLOCK,\n fontSize: 14,\n fontWeight: 400,\n fontFamily: \"sans-serif\",\n color: '#000',\n paddingTop: 0,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingRight: 0,\n marginTop: 0,\n marginBottom: 0,\n marginLeft: 0,\n marginRight: 0,\n height: WIDTH.AUTO,\n borderRadius: 0,\n lineCap: 'square',\n flexDirection: FLEX_DIRECTION.ROW,\n verticalAlign: 'middle',\n textAlign: 'left',\n justifyContent: 'flex-start',\n alignItems: 'flex-start',\n whiteSpace: 'normal',\n zIndex: 1,\n visible: true,\n position: 'static'\n}\n\nexport default {\n DISPLAY,\n WIDTH,\n POSITION,\n DEFAULT_STYLES,\n TEXT_ALIGN,\n FLEX_DIRECTION\n}\n","export function isExact(num) {\n return typeof num === 'number'\n}\n\nexport function isAuto(num) {\n return num === 'auto'\n}\n\nexport function isOuter(num) {\n if (typeof num !== 'string') return\n return num.match('%')\n}\n\nexport function parseOuter(num) {\n let _n = parseInt(num.replace('%', ''))\n return (isNaN(_n) || _n < 0) ? 0 : (_n / 100)\n}\n\n\nexport function walk(element, callback) {\n let _continue = false // 是否跳过当前节点以及后面的节点\n let _next = false // 是否跳过当前节点数,子元素都不会遍历\n const _callContinue = () => _continue = true\n const _callNext = () => _next = true\n if (element != null) {\n var stack = [];\n stack.push(element);\n while (stack.length != 0) {\n var item = stack.pop();\n callback(item, _callContinue, _callNext)\n if (!_next) {\n var children = item._getChildren();\n for (var i = children.length - 1; i >= 0; i--) {\n if (!_continue) {\n stack.push(children[i]);\n } else {\n // 复位\n _continue = false\n }\n\n }\n\n } else {\n // 复位\n _next = false\n }\n }\n }\n}\n\nexport function walkParent(element, callback) {\n if (!element) return\n let cur = element\n let stop = false\n const callbreak = () => {\n stop = true\n }\n while (cur.parent) {\n callback(cur.parent, callbreak)\n if (stop) {\n break\n }\n cur = cur.parent\n }\n}\n\nexport function findRelativeTo(element) {\n if (element.isInFlow()) return element.parent\n if (element.renderStyles.position === 'fixed') return element.root\n let relativeTo = null\n walkParent(element, (parent) => {\n if (parent.renderStyles.position !== 'static' && !relativeTo) {\n relativeTo = parent\n }\n })\n if (!relativeTo) {\n relativeTo = element.root\n }\n return relativeTo\n}\n\n\n//\nvar pow = Math.pow,\n sqrt = Math.sqrt,\n sin = Math.sin,\n cos = Math.cos,\n PI = Math.PI,\n c1 = 1.70158,\n c2 = c1 * 1.525,\n c3 = c1 + 1,\n c4 = (2 * PI) / 3,\n c5 = (2 * PI) / 4.5;\n\nexport function easeInOutElastic(x) {\n return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?\n -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2 :\n pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5) / 2 + 1;\n}\n\nfunction easeInOutExpo(pos) {\n if (pos === 0) return 0;\n if (pos === 1) return 1;\n if ((pos /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (pos - 1));\n return 0.5 * (-Math.pow(2, -10 * --pos) + 2);\n}\n\n\nexport function isWX() {\n try {\n return Boolean(wx.getSystemInfoSync);\n } catch(err) {\n return false\n }\n}\n\nexport function isEndNode(el) {\n return el.parent && !el.next && !el.hasChildren()\n}\n\nexport function breadthFirstSearch(node) {\n\n var nodes = [];\n\n if (node != null) {\n\n var queue = [];\n\n queue.unshift(node);\n\n while (queue.length != 0) {\n\n var item = queue.shift();\n\n nodes.push(item._generateRender());\n\n var children = item._getChildren();\n\n for (var i = 0; i < children.length; i++)\n queue.push(children[i]._generateRender());\n\n }\n\n }\n\n return nodes;\n\n}\n\nexport function breadthFirstSearchRight(node) {\n\n var nodes = [];\n\n if (node != null) {\n\n var queue = [];\n\n queue.unshift(node);\n\n while (queue.length != 0) {\n\n var item = queue.shift();\n\n nodes.push(item._generateRender());\n\n var children = item._getChildren();\n\n for (var i = children.length - 1; i >= 0; i--)\n queue.push(children[i]._generateRender());\n\n }\n\n }\n\n return nodes.reverse();\n\n}\n\nexport function needReflow(style) {\n return ['width',\n 'height',\n 'position',\n 'display',\n 'padding',\n 'paddingTop',\n 'paddingLeft',\n 'paddingBottom',\n 'paddingRight',\n 'margin',\n 'marginLeft',\n 'marginTop',\n 'marginBottom',\n 'marginRight',\n 'borderWidth',\n 'flexDirection',\n 'justifyContent',\n 'alignItems',\n 'textAlign',\n 'left',\n 'top',\n 'right',\n 'bottom'\n ].includes(style)\n}\n\nconst mergeKeys = ['attrs', 'styles', 'on']\nexport function mergeOptions(options, mergeOptions) {\n let mergedOptions = {}\n mergeKeys.forEach(key => {\n if (!options[key]) options[key] = {}\n if (!mergeOptions[key]) mergeOptions[key] = {}\n mergedOptions[key] = Object.assign({}, options[key], mergedOptions[key])\n })\n return mergedOptions\n}\n\n\nexport function floor(val){\n return (0.5 + val) << 0\n}\n\nexport function qSort3(arr,callback) { //三路快排\n if(arr.length == 0) {\n return [];\n }\n var left = [];\n var center = [];\n var right = [];\n var pivot = arr[0]; //偷懒,直接取第一个,实际取值情况 参考[快速排序算法的优化思路总结]\n let val = 0\n for(var i = 0; i < arr.length; i++) {\n val = callback(arr[i],pivot)\n if(val<0) {\n left.push(arr[i]);\n } else if(val === 0) {\n center.push(arr[i]);\n } else {\n right.push(arr[i]);\n }\n }\n return [...qSort3(left,callback), ...center, ...qSort3(right,callback)];\n}\n\nexport function getThrottle(threshold) {\n let timer;\n return function (fn) {\n if (!timer) {\n timer = setTimeout(function () {\n fn();\n timer = null;\n }, threshold)\n }\n }\n}\n","import { isExact, isAuto } from './utils'\n\nexport default class Line {\n constructor() {\n this.width = 0\n this.height = 0\n this.contentWidth = 0 // 右边界\n this.y = 0 // 上\n this.doorClosed = false // 是否允许加入\n this.outerWidth = 0\n this.container = null\n this.elements = []\n this.start = null // 起点,行最左边第一个\n this.end = null // 结束\n this.offsetX = 0\n this.id = Math.random()\n }\n\n bind(el) {\n this.container = el.parent\n this.initHeight(el)\n this.outerWidth = el.parent && isAuto(el.parent.styles.width) ? Infinity : el.parent.renderStyles.contentWidth\n\n this.start = el\n this.add(el)\n }\n\n initHeight(el) {\n this.height = el.parent && el.parent.renderStyles.lineHeight || 0\n }\n\n initLayout(el) {\n this.right = el._getContainerLayout().contentX\n this.x = el._getContainerLayout().contentX\n this.y = this.getPreLine(el).y\n }\n\n refreshElementPosition(el) {\n if (this.start === el) {\n this.initLayout(el)\n }\n // 刷新位置,首先以左边计算\n el.x = this.right + this.offsetX\n el.y = this.y + this.getOffsetY(el)\n // + (this.height - el.renderStyles.height) / 2\n this.right += el.renderStyles.width\n\n }\n\n getOffsetY(el) {\n if (el.renderStyles.verticalAlign === 'bottom') {\n return (this.height - el.renderStyles.height)\n } else if (el.renderStyles.verticalAlign === 'middle') {\n return (this.height - el.renderStyles.height) / 2\n } else {\n return 0\n }\n }\n\n\n add(el) {\n this.elements.push(el)\n el.line = this\n this.refreshWidthHeight(el)\n\n if (!el.next || el.next.renderStyles.display !== 'inline-block') {\n this.closeLine()\n }\n }\n\n refreshWidthHeight(el) {\n if (el.renderStyles.height > this.height) {\n this.height = el.renderStyles.height\n }\n\n this.width += el.renderStyles.width\n }\n\n canIEnter(el) {\n if ((el.renderStyles.width + this.width) > this.outerWidth) {\n this.closeLine()\n return false\n } else {\n return true\n }\n }\n\n closeLine() {\n // new line\n this.end = this.elements[this.elements.length - 1]\n this.refreshXAlign()\n\n }\n\n getPreLine(el) {\n if (el.pre) {\n if (el.pre.line) {\n return { y: el.pre.line.height + el.pre.line.y, x: el.pre.line.x }\n } else {\n return { y: el._getPreLayout().y + el._getPreLayout().height, x: el._getPreLayout().x }\n }\n } else {\n return { y: el._getContainerLayout().contentY, x: el._getContainerLayout().contentX }\n }\n }\n\n refreshXAlign() {\n if (this.outerWidth > 5000) return\n if (!this.end.parent) return\n let offsetX = this.outerWidth - this.width\n if (this.end.parent.renderStyles.textAlign === 'center') {\n offsetX = offsetX / 2\n } else if (this.end.parent.renderStyles.textAlign === 'left') {\n offsetX = 0\n }\n this.offsetX = offsetX\n }\n}\n","import Line from './line'\nimport { isExact, isAuto } from './utils'\nimport STYLES from './constants'\n\nconst KEY = {\n [STYLES.FLEX_DIRECTION.ROW]: {\n width: 'width',\n contentWidth: 'contentWidth',\n x: 'x',\n y: 'y',\n contentX: 'contentX',\n height: 'height',\n contentHeight: 'contentHeight'\n },\n [STYLES.FLEX_DIRECTION.COLUMN]: {\n width: 'height',\n contentWidth: 'contentHeight',\n x: 'y',\n y: 'x',\n contentX: 'contentY',\n height: 'width',\n contentHeight: 'contentWidth'\n }\n}\n// 目前flex是基于inline-block的简单实现,只支持row方向width + flex混用\nexport default class FlexBox extends Line {\n constructor() {\n super()\n this.exactValue = 0\n this.flexTotal = 0\n this.key = null\n }\n\n closeLine() {\n super.closeLine()\n this.calcFlex()\n }\n\n bind(el) {\n this.container = el.parent\n if (el.parent) {\n this.key = KEY[el.parent.renderStyles.flexDirection]\n }\n this.initHeight(el)\n this.outerWidth = el.parent && isAuto(el.parent.styles[this.key.width]) ? Infinity : el.parent.renderStyles[this.key.contentWidth]\n this.start = el\n this.add(el)\n }\n\n add(el) {\n if (isExact(el.styles[this.key.width])) {\n this.exactValue += el.renderStyles[this.key.width]\n } else if (isExact(el.styles.flex)) {\n this.flexTotal += el.renderStyles.flex\n }\n\n this.elements.push(el)\n el.line = this\n this.refreshWidthHeight(el)\n\n if (!el.next) {\n this.closeLine()\n }\n }\n\n initHeight() {\n this[this.key.height] = 0\n }\n\n refreshWidthHeight(el) {\n if (el.renderStyles[this.key.height] > this[this.key.height]) {\n this[this.key.height] = el.renderStyles[this.key.height]\n }\n\n this[this.key.width] += el.renderStyles[this.key.width]\n }\n\n initLayout(el) {\n this.right = el._getContainerLayout()[this.key.contentX]\n this[this.key.x] = el._getContainerLayout()[this.key.contentX]\n this[this.key.y] = this.getPreLine(el)[this.key.y]\n }\n\n refreshElementPosition(el) {\n if (this.start === el) {\n this.initLayout(el)\n }\n // 刷新位置,首先以左边计算\n el[this.key.x] = this.right + this.offsetX\n el[this.key.y] = this[this.key.y] + this.getOffsetY(el)\n // + (this.height - el.renderStyles.height) / 2\n this.right += el.renderStyles[this.key.width]\n\n }\n\n calcFlex() {\n const { [this.key.contentWidth]: containerWidth } = this.container.renderStyles\n this.elements.forEach(child => {\n if (isExact(child.styles.flex)) {\n child.renderStyles[this.key.width] = (child.styles.flex / this.flexTotal) * (containerWidth - this.exactValue)\n child._refreshContentWithLayout()\n }\n })\n }\n\n refreshXAlign() {\n if (!this.end.parent) return\n let offsetX = this.outerWidth - this[this.key.width]\n if (this.end.parent.renderStyles.justifyContent === 'center') {\n offsetX = offsetX / 2\n } else if (this.end.parent.renderStyles.justifyContent === 'flex-start') {\n offsetX = 0\n }\n this.offsetX = offsetX\n }\n\n getOffsetY(el) {\n if (el.renderStyles.alignSelf === 'flex-end') {\n return (this.container.renderStyles[this.key.contentHeight] - el.renderStyles[this.key.height])\n } else if (el.renderStyles.alignSelf === 'center') {\n return (this.container.renderStyles[this.key.contentHeight] - el.renderStyles[this.key.height]) / 2\n } else {\n return 0\n }\n }\n}\n","export default class TreeNode {\n\n static connectChildren(el) {\n if (el.hasChildren()) {\n el.children = el.children.filter(item => item instanceof TreeNode)\n el._getChildren().map((child, index) => {\n // 设置parent\n child._setParent(el)\n // 设置了上一个兄弟节点\n child._setSibling(el._getChildren()[index - 1], el._getChildren()[index + 1])\n TreeNode.connectChildren(child)\n })\n } else {\n }\n }\n\n constructor(children) {\n this.children = children || []\n this.parent = null\n this.root = null\n this.pre = null\n this.next = null\n }\n\n\n\n hasChildren() {\n return Array.isArray(this.children) && this.children.length ? true : false\n }\n\n _getChildren() {\n return this.hasChildren() ? this.children : []\n }\n\n _setParent(element) {\n this.parent = element\n this.root = element.root\n }\n\n _setSibling(pre, next) {\n this.pre = pre || null\n this.next = next || null\n }\n\n\n // 添加在最后\n appendChild(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n const pre = this._getChildren()[this._getChildren().length - 1]\n pre && pre._setSibling(pre.pre, treeNode)\n this.children.push(treeNode)\n treeNode._setParent(this)\n treeNode._setSibling(pre, null)\n // return treeNode\n }\n\n //\n prependChild(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n const next = this._getChildren()[0]\n next && next._setSibling(treeNode, next.next)\n this.children.unshift(treeNode)\n treeNode._setParent(this)\n treeNode._setSibling(null, next)\n // return treeNode\n }\n\n removeChild(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n const index = this._getChildren().indexOf(treeNode)\n if (index < 0) throw Error('treeNode must be the child of parent')\n const pre = this._getChildren()[index - 1]\n const next = this._getChildren()[index + 1]\n if (pre) {\n pre._setSibling(pre.pre, next)\n }\n if (next) {\n next._setSibling(pre, next.next)\n }\n this.children.splice(index, 1)\n }\n\n remove() {\n if (!this.parent) {\n throw Error('Can not remove root node')\n }\n this.parent.removeChild(this)\n }\n\n append(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n if (!this.parent) throw Error('Can not add treeNode to root level!')\n let children = []\n treeNode._setParent(this.parent)\n this.parent.children.forEach((child, index) => {\n children.push(child)\n if (child === this) {\n treeNode._setSibling(child, this.parent.children[index + 1])\n children.push(treeNode)\n }\n })\n this.parent.children = children\n }\n\n prepend(treeNode) {\n if (!treeNode instanceof TreeNode) throw Error('Unknown treeNode type')\n if (!this.parent) throw Error('Can not add treeNode to root level!')\n let children = []\n treeNode._setParent(this.parent)\n for (let i = this.parent.children.length - 1; i >= 0; i--) {\n children.unshift(this.parent.children[i])\n if (this.parent.children[i] === this) {\n treeNode._setSibling(this.parent.children[i - 1], this.parent.children[i])\n children.unshift(treeNode)\n }\n }\n this.parent.children = children\n }\n\n\n}\n","import { isExact, isAuto, isOuter } from './utils'\nimport STYLES from './constants'\n\n\nexport default function (element) {\n _completeFlex(element)\n\n _completeWidth(element)\n\n _completeBorder(element)\n\n _completeFont(element)\n\n _completePaddingMargin(element)\n}\n\n\nfunction _completePaddingMargin(element) {\n if (element.styles.padding) {\n if (isExact(element.styles.padding)) {\n element.styles.paddingLeft = element.styles.padding\n element.styles.paddingBottom = element.styles.padding\n element.styles.paddingRight = element.styles.padding\n element.styles.paddingTop = element.styles.padding\n } else if (Array.isArray(element.styles.padding)) {\n // 支持数组[10,20]相当于padding:10px 20px;\n if (element.styles.padding.length === 2) {\n element.styles.paddingLeft = element.styles.paddingRight = element.styles.padding[1]\n element.styles.paddingBottom = element.styles.paddingTop = element.styles.padding[0]\n } else if (element.styles.padding.length === 4) {\n element.styles.paddingLeft = element.styles.padding[3]\n element.styles.paddingBottom = element.styles.padding[2]\n element.styles.paddingRight = element.styles.padding[1]\n element.styles.paddingTop = element.styles.padding[0]\n }\n }\n }\n\n if (isExact(element.styles.margin)) {\n element.styles.marginLeft = element.styles.margin\n element.styles.marginBottom = element.styles.margin\n element.styles.marginRight = element.styles.margin\n element.styles.marginTop = element.styles.margin\n } else if (Array.isArray(element.styles.margin)) {\n // 支持数组[10,20]相当于padding:10px 20px;\n if (element.styles.margin.length === 2) {\n element.styles.marginLeft = element.styles.marginRight = element.styles.margin[1]\n element.styles.marginBottom = element.styles.marginTop = element.styles.margin[0]\n } else if (element.styles.margin.length === 4) {\n element.styles.marginLeft = element.styles.margin[3]\n element.styles.marginBottom = element.styles.margin[2]\n element.styles.marginRight = element.styles.margin[1]\n element.styles.marginTop = element.styles.margin[0]\n }\n }\n}\n\n/**\n * borderwidth到各个边\n */\nfunction _completeBorder(element) {\n let { borderWidth, borderLeftWidth, borderRightWidth, borderBottomWidth, borderTopWidth, borderRadius } = element.styles\n if (!borderWidth) {\n element.styles.borderWidth = 0\n borderWidth = 0\n }\n if (Array.isArray(borderWidth)) {\n element.styles.borderTopWidth = borderWidth[0]\n element.styles.borderRightWidth = borderWidth[1]\n element.styles.borderBottomWidth = borderWidth[2]\n element.styles.borderLeftWidth = borderWidth[3]\n } else {\n if (!borderLeftWidth) {\n element.styles.borderLeftWidth = borderWidth\n }\n if (!borderRightWidth) {\n element.styles.borderRightWidth = borderWidth\n }\n if (!borderBottomWidth) {\n element.styles.borderBottomWidth = borderWidth\n }\n if (!borderTopWidth) {\n element.styles.borderTopWidth = borderWidth\n }\n }\n if (borderRadius) {\n element.styles.overflow = 'hidden'\n }\n}\n\nfunction _completeWidth(element) {\n if (!element.styles.width) {\n if (element.styles.display === STYLES.DISPLAY.INLINE_BLOCK || element.styles.display === STYLES.DISPLAY.INLINE || !element.isInFlow()) {\n element.styles.width = STYLES.WIDTH.AUTO\n } else if (element.styles.display === STYLES.DISPLAY.BLOCK || element.styles.display === STYLES.DISPLAY.FLEX) {\n element.styles.width = STYLES.WIDTH.OUTER\n } else {\n element.styles.width = 0\n }\n }\n\n if (isOuter(element.styles.width)) {\n if (element.parent && isAuto(element.parent.styles.width)) {\n element.styles.width = STYLES.WIDTH.AUTO\n }\n }\n\n if (isOuter(element.styles.height)) {\n if (element.parent && isAuto(element.parent.styles.height)) {\n element.styles.height = STYLES.WIDTH.AUTO\n }\n }\n}\n\nfunction _completeFont(element) {\n if (element.styles.fontSize && !element.styles.lineHeight) {\n element.styles.lineHeight = element.styles.fontSize * 1.4\n }\n}\n\nfunction _completeFlex(element) {\n if (element.parent && element.parent.styles.display === STYLES.DISPLAY.FLEX) {\n // flex布局内 width 和flex需要有一个\n if (!element.styles.flex) {\n if (!isExact(element.styles.height) && !isExact(element.styles.width)) {\n element.styles.flex = 1\n }\n } else {\n if (element.parent.styles.flexDirection === 'column' && isExact(element.styles.flex)) {\n element.styles.height = 0\n } else if (element.parent.styles.flexDirection === 'row' && isExact(element.styles.flex)) {\n element.styles.width = 0\n }\n }\n\n }\n}\n","import STYLES from './constants'\nimport pxUtil from './px'\nimport { isExact, walk, isOuter, parseOuter, walkParent, isEndNode, isAuto, findRelativeTo, needReflow, floor } from './utils'\nimport Line from './line'\nimport FlexBox from './flex-box'\nimport TreeNode from './tree-node'\nimport completeStyles from './complete-styles'\n\n/**\n * Element类实现盒模型以及定位,不具备绘制\n * 其他类继承实现\n *\n */\n\n\n\n\nexport default class Element extends TreeNode {\n constructor(options, children) {\n super(children)\n this.options = Object.assign({ attrs: {}, styles: {}, on: {} }, options)\n this.styles = null\n this.renderStyles = null\n this.x = 0\n this.y = 0\n this.render = null\n this.container = null\n this.visible = true\n }\n\n init() {\n this._initStyles()\n this.initEvent()\n }\n\n initEvent() {\n if (this.options.on) {\n Object.keys(this.options.on).forEach(eventName => {\n if (this.getLayer().eventManager.EVENTS.includes(eventName)) {\n this.getLayer().eventManager.addEventListener(eventName, this.options.on[eventName], this)\n }\n })\n }\n }\n\n removeEvent() {\n this.getLayer().eventManager.removeElement(this)\n }\n\n getLayer() {\n return this.root.layer\n }\n\n getRender() {\n return this.root.layer.render\n }\n\n _paint() {\n\n }\n\n mount(layer) {\n layer.mountNode(this)\n }\n\n _initStyles() {\n this.styles = Object.assign({}, this._getDefaultStyles(), this._getParentStyles(this.options.styles), this.options.styles || {})\n\n this._completeStyles()\n\n this._initRenderStyles()\n }\n\n _initRenderStyles() {\n const renderStyles = { ...this.styles }\n const parentWidth = this._getContainerLayout().contentWidth\n const parentHeight = this._getContainerLayout().contentHeight\n\n if (isAuto(renderStyles.width)) {\n renderStyles.paddingWidth = 0\n } else if (isOuter(renderStyles.width)) {\n renderStyles.paddingWidth = parseOuter(renderStyles.width) * parentWidth - renderStyles.marginLeft - renderStyles.marginRight\n } else {\n renderStyles.paddingWidth = renderStyles.width\n }\n\n if (isAuto(renderStyles.height)) {\n renderStyles.paddingHeight = 0\n } else if (isOuter(renderStyles.height)) {\n renderStyles.paddingHeight = parseOuter(renderStyles.height) * parentHeight - renderStyles.marginTop - renderStyles.marginBottom\n } else {\n renderStyles.paddingHeight = renderStyles.height\n }\n\n if (!renderStyles.paddingWidth) renderStyles.paddingWidth = 0\n if (!renderStyles.paddingHeight) renderStyles.paddingHeight = 0\n\n // 初始化contentWidth\n renderStyles.contentWidth = renderStyles.paddingWidth - renderStyles.paddingLeft - renderStyles.paddingRight\n renderStyles.contentHeight = renderStyles.paddingHeight - renderStyles.paddingTop - renderStyles.paddingBottom\n\n renderStyles.width = renderStyles.paddingWidth + renderStyles.marginLeft + renderStyles.marginRight + this._getTotalBorderWidth(renderStyles)\n renderStyles.height = renderStyles.paddingHeight + renderStyles.marginTop + renderStyles.marginBottom + this._getTotalBorderHeight(renderStyles)\n\n this.renderStyles = renderStyles\n\n if (this._InFlexBox()) {\n this._bindFlexBox()\n } else if (!this.isInFlow()) {\n this.relativeTo = findRelativeTo(this)\n }\n\n\n }\n\n /**\n * 需要继承的styles放在这里\n */\n _getParentStyles(curStyles) {\n let { textAlign, lineHeight, fontSize, color, fontFamily, alignItems, visible = true } = this.parent && this.parent.renderStyles || {}\n let extendStyles = {}\n if (textAlign) extendStyles.textAlign = textAlign\n if (fontSize) extendStyles.fontSize = fontSize\n if (color) extendStyles.color = color\n if (fontFamily) extendStyles.fontFamily = fontFamily\n if (alignItems && !curStyles.alignSelf) extendStyles.alignSelf = alignItems\n extendStyles.visible = visible\n return extendStyles\n }\n\n _completeStyles() {\n completeStyles(this)\n }\n\n _getDefaultStyles() {\n return STYLES.DEFAULT_STYLES\n }\n\n // 获取文档流中的子节点\n _getChildrenInFlow() {\n return this._getChildren().filter(item => item.isInFlow())\n }\n\n // 是否在文档流中\n isInFlow() {\n const { position, display } = this.styles\n return position !== STYLES.POSITION.ABSOLUTE && position !== STYLES.POSITION.FIXED\n }\n\n isVisible() {\n return this.renderStyles.visible && this.visible\n }\n\n _generateRender() {\n return this\n }\n\n getCtx() {\n return this.root.layer.ctx\n }\n\n /**\n * 实现文档流 需要知道上一个兄弟节点\n */\n _reflow() {\n\n\n }\n\n _initWidthHeight() {\n const { width, height, display, flex, marginLeft, marginRight, marginTop, marginBottom } = this.styles\n if (isAuto(width) || isAuto(height)) {\n // 这一步需要遍历,判断一下\n const layout = this._measureLayout()\n // 初始化宽度高度\n if (isAuto(width)) {\n this.renderStyles.contentWidth = floor(layout.width)\n }\n\n if (isAuto(height)) {\n // 不填就是auto\n this.renderStyles.contentHeight = floor(layout.height)\n }\n }\n\n this._refreshLayoutWithContent()\n\n if (this._InFlexBox()) {\n this.line.refreshWidthHeight(this)\n } else if (display === STYLES.DISPLAY.INLINE_BLOCK) {\n // 如果是inline-block 这里仅计算高度\n this._bindLine()\n }\n }\n\n _initPosition() {\n let { contentX } = this._getContainerLayout()\n const { paddingLeft, paddingTop, borderLeftWidth, borderTopWidth, marginLeft, marginTop } = this.renderStyles\n // 初始化ctx位置\n if (!this.isInFlow()) {\n // 不在文档流中\n let { contentX, contentY, contentWidth, contentHeight } = this._getContainerLayout(this.relativeTo)\n let { top, bottom, right, left, width, height } = this.renderStyles\n if (isOuter(top)) top = parseOuter(top) * contentHeight\n if (isOuter(bottom)) bottom = parseOuter(bottom) * contentHeight\n if (isOuter(left)) left = parseOuter(left) * contentWidth\n if (isOuter(right)) right = parseOuter(right) * contentWidth\n if (isExact(top)) {\n this.y = contentY + top\n } else if (isExact(bottom)) {\n this.y = contentY + contentHeight - bottom - height\n }\n\n if (isExact(left)) {\n this.x = contentX + left\n } else if (isExact(right)) {\n this.x = contentX + contentWidth - right - width\n }\n } else if (this._InFlexBox()) {\n this.line.refreshElementPosition(this)\n } else if (this.renderStyles.display === STYLES.DISPLAY.INLINE_BLOCK) {\n // inline-block到line里计算\n // this._bindLine()\n this.line.refreshElementPosition(this)\n } else {\n this.x = contentX\n this.y = this._getPreLayout().y + this._getPreLayout().height\n }\n this.x = floor(this.x)\n this.y = floor(this.y)\n this.contentX = this.x + paddingLeft + borderLeftWidth + marginLeft\n this.contentY = this.y + paddingTop + borderTopWidth + marginTop\n }\n\n _InFlexBox() {\n if (!this.isInFlow()) return false\n if (!this.parent) return false\n if (this.parent && this.parent.renderStyles.display === STYLES.DISPLAY.FLEX) return true\n }\n\n\n // 父元素根据子元素撑开content后,再计算width\n _refreshLayoutWithContent() {\n this.renderStyles.height = floor(this.renderStyles.contentHeight + this.renderStyles.paddingTop + this.renderStyles.paddingBottom + this.renderStyles.marginTop + this.renderStyles.marginBottom + this._getTotalBorderHeight())\n this.renderStyles.width = floor(this.renderStyles.contentWidth + this.renderStyles.paddingLeft + this.renderStyles.paddingRight + this.renderStyles.marginLeft + this.renderStyles.marginRight + this._getTotalBorderWidth())\n this.renderStyles.paddingWidth = floor(this.renderStyles.contentWidth + this.renderStyles.paddingLeft + this.renderStyles.paddingRight)\n this.renderStyles.paddingHeight = floor(this.renderStyles.contentHeight + this.renderStyles.paddingTop + this.renderStyles.paddingBottom)\n }\n\n // 父元素根据子元素撑开content后,再计算width\n _refreshContentWithLayout() {\n this.renderStyles.contentHeight = this.renderStyles.height - this.renderStyles.paddingTop - this.renderStyles.paddingBottom - this.renderStyles.marginTop - this.renderStyles.marginBottom - this._getTotalBorderHeight()\n this.renderStyles.contentWidth = this.renderStyles.width - this.renderStyles.paddingLeft - this.renderStyles.paddingRight - this.renderStyles.marginLeft - this.renderStyles.marginRight - this._getTotalBorderWidth()\n this.renderStyles.paddingWidth = floor(this.renderStyles.contentWidth + this.renderStyles.paddingLeft + this.renderStyles.paddingRight)\n this.renderStyles.paddingHeight = floor(this.renderStyles.contentHeight + this.renderStyles.paddingTop + this.renderStyles.paddingBottom)\n }\n\n _getTotalBorderWidth(renderStyles = this.renderStyles) {\n return renderStyles.borderLeftWidth + renderStyles.borderRightWidth\n }\n\n _getTotalBorderHeight(renderStyles = this.renderStyles) {\n return renderStyles.borderTopWidth + renderStyles.borderBottomWidth\n }\n\n _bindLine() {\n if (this.pre && this.pre.line && this.pre.line.canIEnter(this)) {\n this.pre.line.add(this)\n } else {\n // 新行\n new Line().bind(this)\n }\n }\n\n _bindFlexBox() {\n if (this.pre && this.pre.line) {\n this.pre.line.add(this)\n } else {\n // 新行\n new FlexBox().bind(this)\n }\n }\n\n _getContainerLayout(container = this.parent) {\n if (!container) {\n // root\n if (!this.container) {\n debugger\n }\n container = {\n renderStyles: {\n width: this.container.width,\n height: this.container.height,\n paddingTop: 0,\n paddingBottom: 0,\n paddingLeft: 0,\n paddingRight: 0,\n marginLeft: 0,\n marginRight: 0,\n marginTop: 0,\n marginBottom: 0,\n contentWidth: this.container.width,\n contentHeight: this.container.height\n },\n x: 0,\n y: 0,\n contentX: 0,\n contentY: 0\n }\n }\n return {\n width: container.renderStyles.width,\n height: container.renderStyles.height,\n x: container.x,\n y: container.y,\n paddingTop: container.renderStyles.paddingTop,\n paddingBottom: container.renderStyles.paddingBottom,\n paddingLeft: container.renderStyles.paddingLeft,\n paddingRight: container.renderStyles.paddingRight,\n marginLeft: container.renderStyles.marginLeft,\n marginRight: container.renderStyles.marginRight,\n marginTop: container.renderStyles.marginTop,\n marginBottom: container.renderStyles.marginBottom,\n contentX: container.contentX,\n contentY: container.contentY,\n contentWidth: container.renderStyles.contentWidth,\n contentHeight: container.renderStyles.contentHeight\n }\n }\n\n // 这里前一个节点必须在文档流中\n _getPreLayout() {\n let cur = this.pre\n while (cur && !cur.isInFlow()) {\n cur = cur.pre\n }\n // 如果没有前一个或者前面的都不在文档流中,获取容器的\n if (cur) {\n return {\n width: cur.renderStyles.width,\n height: cur.renderStyles.height,\n x: cur.x,\n y: cur.y\n }\n } else {\n return {\n width: 0,\n height: 0,\n x: this._getContainerLayout().contentX,\n y: this._getContainerLayout().contentY\n }\n }\n }\n\n // 计算自身的高度\n _measureLayout() {\n let width = 0 // 需要考虑原本的宽度\n let height = 0\n this._getChildrenInFlow().forEach(child => {\n if (child.line) {\n if (child.line.start === child) {\n if (child.line.width > width) {\n width = child.line.width\n }\n height += child.line.height\n }\n } else if (child.renderStyles.width > width) {\n width = child.renderStyles.width\n height += child.renderStyles.height\n } else {\n height += child.renderStyles.height\n }\n })\n\n return { width, height }\n }\n\n // 获取元素,只会找该元素子级\n getElementBy(key, value) {\n let match = []\n walk(this, (element) => {\n if (element.options.attrs[key] === value) {\n match.push(element)\n }\n })\n return match\n }\n\n // 添加在最后\n appendChild(element) {\n super.appendChild(element)\n this.getLayer().onElementAdd(element)\n return element\n }\n\n //\n prependChild(element) {\n super.prependChild(element)\n this.getLayer().onElementAdd(element)\n return element\n }\n\n removeChild(element) {\n super.removeChild(element)\n this.getLayer().onElementRemove(element)\n }\n\n append(element) {\n super.append(element)\n this.getLayer().onElementAdd(element)\n }\n\n prepend(element) {\n super.prepend(element)\n this.getLayer().onElementAdd(element)\n }\n\n setStyles(styles) {\n let _needReflow = false\n Object.keys(styles).forEach(key => {\n if (needReflow(key)) {\n _needReflow = true\n } else {\n this.renderStyles[key] = styles[key]\n }\n })\n if (_needReflow) {\n Object.keys(styles).forEach(key => {\n this.options.styles[key] = styles[key]\n })\n this.getLayer().reflowElement(this, this)\n // console.warn('实验性功能')\n } else {\n this.getRender().requestRepaint()\n }\n }\n\n}\n","import Element from './element'\nimport STYLES from './constants'\nimport { isExact } from './utils'\n\nexport default class View extends Element {\n\n constructor(options, children) {\n super(options, children)\n this.type = 'view'\n }\n\n _getDefaultStyles() {\n return {\n ...STYLES.DEFAULT_STYLES,\n display: STYLES.DISPLAY.BLOCK\n }\n }\n\n _paint() {\n if(this.options.render){\n this.options.render(this.getRender().getCtx(),this.getRender().getCanvas(),this)\n }else{\n this.getRender()._drawBackground(this)\n this.getRender()._drawBox(this)\n }\n }\n\n\n}\n","import Element from './element'\nimport STYLES from './constants'\nimport { isExact, isAuto } from './utils'\n\nexport default class Text extends Element {\n constructor(options, children) {\n super(options, children)\n this._layout = null // layout用来保存计算的自身高度\n this._lines = []\n this.children += ''\n this.type = 'text'\n this.debugColor = 'blue'\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawText(this)\n this.getRender()._drawBox(this)\n }\n\n _getDefaultStyles() {\n return {\n ...STYLES.DEFAULT_STYLES,\n display: STYLES.DISPLAY.INLINE_BLOCK,\n width: STYLES.WIDTH.AUTO,\n textAlign: 'left',\n }\n }\n\n _measureLayout() {\n this._layout = this.getRender().measureText(this, this.children)\n this._layout.height = this.renderStyles.lineHeight\n this._calcLine()\n return this._layout\n }\n\n _getFont() {\n const { fontSize, fontWeight, fontFamily } = this.renderStyles\n return `${fontWeight} ${fontSize}px ${fontFamily}`\n }\n\n _calcLine() {\n if (!this.parent || !this.children) return\n const { width: textWidth, height: textHeight } = this._layout\n let { contentWidth: parentContentWidth } = this.parent.renderStyles\n const { width: parentWidth } = this.parent.styles\n if (!isAuto(this.styles.width)) parentContentWidth = this.renderStyles.width\n // 如果一行宽度够,或者父级宽度是auto\n if ((isExact(parentContentWidth) && parentContentWidth >= textWidth) || parentWidth === STYLES.WIDTH.AUTO) {\n this._lines = [{\n text: this.children,\n layout: this._layout\n }]\n } else {\n this._lines = []\n let lineIndex = 1\n let lineText = ''\n let _layout = null\n let lastLayout = null\n for (let i = 0; i < this.children.length; i++) {\n _layout = this.getRender().measureText(this, lineText + this.children[i])\n if (_layout.width > parentContentWidth) {\n if (lineIndex >= this.renderStyles.maxLine) {\n // 最大行数限制 以及maxline省略号实现\n lineText = lineText.substring(0, lineText.length - 2) + '...'\n break\n }\n // 超出了\n this._lines.push({\n text: lineText,\n layout: lastLayout || _layout\n })\n lineText = ''\n lineIndex += 1\n\n }\n\n lineText += this.children[i]\n\n lastLayout = _layout\n }\n this._layout.width = parentContentWidth\n this._lines.push({\n text: lineText,\n layout: this.getRender().measureText(this, lineText)\n })\n // 根据lineheihgt更新height\n this._layout.height = this._lines.length * this.renderStyles.lineHeight\n }\n }\n\n getInnerText() {\n return this.children\n }\n\n setInnerText(val) {\n if (val === undefined) return\n if (val === this.children) return\n this.children = val\n this.getLayer().reflowElement(this)\n }\n}\n","import View from './view'\nimport STYLES from './constants'\nimport { isExact, isAuto, isWX } from './utils'\nimport { getImage } from './weapp-adapter'\n\nexport default class $Image extends View {\n\n constructor(options, children) {\n super(options, children)\n this.type = 'image'\n this._imageInfo = {\n width: 0,\n height: 0,\n sx: 0,\n sy: 0,\n swidth: 0,\n sheight: 0,\n dx: 0,\n dy: 0,\n dwidth: 0,\n dheight: 0\n }\n this.debugColor = 'blue'\n this._image = null\n this._layout = null\n }\n\n init() {\n super.init()\n if(this.options && this.options.attrs && this.options.attrs.timeout){\n setTimeout(() => {\n this._loadImage()\n },this.options.attrs.timeout || 0)\n }else{\n this._loadImage()\n }\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawImage(this)\n this.getRender()._drawBox(this)\n }\n\n _loadImage() {\n const { mode } = this.options.attrs\n\n return new Promise((resolve, reject) => {\n this.getRender().getImageInstance(this.options.attrs.src)\n .then(({ info, image }) => {\n this._imageInfo = info\n this._image = image\n resolve()\n\n this._layoutImage()\n\n if (this.isVisible()) {\n // if (mode === 'aspectFill' || mode === 'aspectFit') {\n // // this.getLayer().onElementChange(this)\n // this.getLayer().repaint(this)\n // } else {\n // // 重新布局绘制\n this.getLayer().reflowElement(this)\n // }\n }\n\n // call load callback\n if (this.options.on && this.options.on.load) {\n this.options.on.load(this)\n }\n })\n .catch(err => {\n // call error callback\n if (this.options.on && this.options.on.error) {\n this.options.on.error(err)\n }\n })\n })\n }\n\n // 计算图片布局\n _layoutImage() {\n const { contentWidth, contentHeight } = this.renderStyles\n const { mode } = this.options.attrs\n const { width, height } = this.styles\n const { width: imageW, height: imageH } = this._imageInfo\n // 根据用户设置判断图片宽高,目前支持widthfix、heightfix、平铺\n let w = contentWidth\n let h = contentHeight\n if (!isAuto(width) && isAuto(height)) {\n // width fix\n w = contentWidth\n h = getHeightByWidth(w, imageW, imageH)\n } else if (!isAuto(height) && isAuto(width)) {\n // height fix\n h = contentHeight\n w = getWidthByHeight(h, imageW, imageH)\n } else if (isAuto(width) && isAuto(height)) {\n // auto\n w = imageW\n h = imageH\n } else if (mode === 'aspectFill') {\n // 填充\n if ((w / h) > (imageW / imageH)) {\n this._imageInfo.swidth = imageW\n this._imageInfo.sheight = getHeightByWidth(imageW, w, h)\n this._imageInfo.sx = 0\n this._imageInfo.sy = (imageH - this._imageInfo.sheight) / 2\n } else {\n this._imageInfo.sheight = imageH\n this._imageInfo.swidth = getWidthByHeight(imageH, contentWidth, contentHeight)\n this._imageInfo.sy = 0\n this._imageInfo.sx = (imageW - this._imageInfo.swidth) / 2\n }\n } else if (mode === 'aspectFit') {\n if ((w / h) > (imageW / imageH)) {\n this._imageInfo.dwidth = getWidthByHeight(contentHeight, imageW, imageH)\n this._imageInfo.dheight = contentHeight\n this._imageInfo.dy = this.contentY\n this._imageInfo.dx = (contentWidth - this._imageInfo.dwidth) / 2 + this.contentX\n } else {\n this._imageInfo.dheight = getHeightByWidth(contentWidth, imageW, imageH)\n this._imageInfo.dwidth = contentWidth\n this._imageInfo.dx = this.contentX\n this._imageInfo.dy = (contentHeight - this._imageInfo.dheight) / 2 + this.contentY\n }\n } else {\n w = contentWidth\n h = contentHeight\n }\n this._layout = { width: w, height: h }\n }\n\n _measureLayout() {\n if (this._layout) {\n return this._layout\n } else {\n return {\n width: this.renderStyles.width,\n height: this.renderStyles.height\n }\n }\n }\n\n}\n\n\nfunction getWidthByHeight(height, originWidth, originHeight) {\n return height / originHeight * originWidth\n}\n\nfunction getHeightByWidth(width, originWidth, originHeight) {\n return width / originWidth * originHeight\n}\n","import TreeNode from './tree-node'\nimport { walkParent, walk } from './utils'\nconst events = ['click','touchstart','touchmove','touchend','mousewheel']\nexport default class EventManager {\n\n constructor({ simulateClick = true }) {\n this.EVENTS = events\n this.clear()\n this.touchStartEvent = null\n this.simulateClick = simulateClick // 是否模拟移动端点击事件\n }\n\n clear() {\n events.forEach(eventName => {\n this[`${eventName}Tree`] = new TreeNode()\n this[`${eventName}List`] = []\n })\n }\n\n click(x, y) {\n let event = new Event({ x, y, type: 'click' })\n this._emit(event)\n }\n\n touchstart(x, y) {\n let event = new Event({ x, y, type: 'touchstart' })\n this.touchStartEvent = event\n this._emit(event)\n }\n\n touchmove(x, y) {\n let event = new Event({ x, y, type: 'touchmove' })\n this._emit(event)\n }\n\n touchend(x, y) {\n let event = new Event({ x, y, type: 'touchend' })\n this._emit(event)\n this.checkClick(event)\n }\n\n mousewheel(x,y,deltaX,deltaY){\n let event = new Event({ x, y,deltaX,deltaY, type: 'mousewheel' })\n this._emit(event)\n }\n\n _emit(e) {\n let tree = this[`${e.type}Tree`]\n if(!tree) return\n\n /**\n * 遍历树,检查是否回调\n * 如果父级没有被触发,则子级也不需要检查,跳到下个同级节点\n * 执行capture回调,将on回调添加到stack\n */\n let callbackList = []\n let curArr = tree._getChildren()\n while (curArr.length) {\n walkArray(curArr, (node, callBreak, isEnd) => {\n if (node.element.isVisible() && this.isPointInElement(e.relativeX, e.relativeY, node.element)) {\n node.runCapture(e)\n callbackList.unshift(node)\n // 同级后面节点不需要执行了\n callBreak()\n curArr = node._getChildren()\n } else if (isEnd) {\n // 到最后一个还是没监测到,结束\n curArr = []\n }\n })\n }\n\n /**\n * 执行on回调,从子到父\n */\n for (let i = 0; i < callbackList.length; i++) {\n if (!e.currentTarget) e.currentTarget = callbackList[i].element\n callbackList[i].runCallback(e)\n if (e.cancelBubble) break\n }\n }\n\n // 待优化\n isPointInElement(x, y, element) {\n let a1 = x >= element.x\n let a2 = y >= element.y\n let a3 = (x <= (element.x + element.renderStyles.width))\n let a4 = (y <= (element.y + element.renderStyles.height))\n if (a1 && a2 && a3 && a4) {\n return true\n }\n return false\n }\n\n\n removeElement(element) {\n events.forEach(eventName => {\n this[`${eventName}List`] = this[`${eventName}List`].filter(item => {\n if (item.element === element) {\n item.remove()\n }\n return item.element !== element\n })\n })\n }\n\n addEventListener(type,callback,element,isCapture){\n const tree = this[`${type}Tree`]\n const list = this[`${type}List`]\n if(!tree){\n console.error('Unknown event name [' + type+']')\n }\n this.addCallback(callback,element,tree,list,isCapture)\n }\n\n /**\n * 不在文档流中,提到relativeTo同级\n * 根据element树的层级关系构建一个监听回调树模型,提高性能\n * 有新的监听时,查找应该挂载在哪个节点\n * 如果节点已经存在,复用原节点\n * @param {Function} callback\n * @param {Element} element\n * @param {Callback} tree\n * @param {Array} list\n * @param {Boolean} isCapture\n */\n addCallback(callback, element, tree, list, isCapture) {\n let parent = null\n let node = null\n // 寻找应该挂载的父节点\n let target = element\n for (let i = list.length - 1; i >= 0; i--) {\n // 寻找已存在节点\n if (element === list[i].element) {\n // 当前\n parent = list[i - 1]\n node = list[i]\n break\n }\n // 寻找应该挂载的父节点 通过对比当前父级最近的父级\n if (!element.isInFlow()) {\n target = element.relativeTo.parent\n if (!target) {\n break\n }\n }\n walkParent(target, (p, callBreak) => {\n if (p === list[i].element) {\n parent = list[i]\n callBreak()\n }\n })\n if (parent) {\n break\n }\n }\n\n // 如果不存在同样的元素节点\n if (!node) {\n node = new Callback(element, callback)\n }\n\n // 添加回调方法\n if (isCapture) {\n node.addCapture(callback)\n } else {\n node.addCallback(callback)\n }\n\n // 挂载节点\n if (parent) {\n // 用prepend是因为后来的层级上高于前面的,但是只有在absolute的元素才能感受到\n parent.prependChild(node)\n } else {\n tree.prependChild(node)\n }\n\n // 缓存到list\n list.push(node)\n }\n\n // 这里利用touchstart和touchend实现了移动端click事件\n checkClick(event) {\n if (this.touchStartEvent && this.simulateClick) {\n // 判断两点距离\n let { x: startx, y: starty } = this.touchStartEvent\n let { x: endx, y: endy } = event\n let distance = ((endy * endy + endx * endx) - (starty * starty + startx * startx))\n if (distance < 5 && distance > -5) {\n this.click(endx, endy)\n }\n }\n }\n}\n\nclass Event {\n constructor({ x, y, type,deltaX,deltaY }) {\n this.x = x\n this.y = y\n this.relativeX = x // scroll到每一层scrollview会不断变化\n this.relativeY = y\n this.type = type\n this.cancelBubble = false\n this.currentTarget = null // 第一个element\n\n if(type === 'mousewheel'){\n this.deltaX = deltaX\n this.deltaY = deltaY\n }\n }\n\n // 阻止冒泡\n stopPropagation() {\n this.cancelBubble = true\n }\n}\n\nclass Callback extends TreeNode {\n constructor(element) {\n super()\n this.element = element\n this.callbackList = []\n this.captureList = []\n }\n\n addCallback(callback) {\n this.callbackList.push(callback)\n }\n\n addCapture(callback) {\n this.captureList.push(callback)\n }\n\n runCallback(params) {\n this.callbackList.forEach(item => item.call(this.element,params))\n }\n\n runCapture(params) {\n this.captureList.forEach(item => item.call(this.element,params))\n }\n\n}\n\n\nfunction walkArray(arr, callback) {\n let _break = false\n const callBreak = () => _break = true\n for (let i = 0; i < arr.length; i++) {\n callback(arr[i], callBreak, i === arr.length - 1 ? true : false)\n if (_break) {\n break\n }\n }\n}\n","import { isExact, walk, isOuter, parseOuter, walkParent, isEndNode, isAuto, isWX, qSort3, getThrottle, floor } from './utils'\nimport TreeNode from './tree-node'\nimport STYLES from './constants'\nimport { getImage } from './weapp-adapter'\n\nconst angle = Math.PI / 2\n\n/**\n * 封装图形api\n */\nexport default class CanvasRender {\n constructor(layer) {\n this.layer = layer\n this.imageBus = {}\n this.isAnimate = false\n this.lastPaintTime = 0\n this.lastFrameComplete = false\n this.throttle = getThrottle(16)\n }\n\n isDebug(){\n return this.getLayer().options && this.getLayer().options.debug\n }\n\n getCtx() {\n return this.layer.ctx\n }\n\n getLayer() {\n return this.layer\n }\n\n _restore(callback) {\n this.getCtx().save()\n callback()\n this.getCtx().restore()\n }\n\n _path(callback) {\n this.getCtx().beginPath()\n callback()\n this.getCtx().closePath()\n }\n\n paint(element) {\n this.getCtx().save()\n\n element._paint(this.lastPaintTime)\n\n this.afterPaint(element)\n }\n\n afterPaint(element) {\n // 这里通过this.ctx栈实现了overflow\n // 第一步判断没有子元素,绘制完成即restore 有子元素需要子元素全部绘制完毕再restore\n if (!element.hasChildren() || element.type === 'text') {\n this.getCtx().restore()\n }\n\n // 如果到了层级的最后一个 释放父级的stack\n this._helpParentRestoreCtx(element)\n }\n\n _helpParentRestoreCtx(element) {\n if ((element.isVisible() && !isEndNode(element)) || (!element.isVisible() && element.next)) return\n this.getCtx().restore()\n let cur = element.parent\n while (cur && !cur.next) {\n // 如果父级也是同级最后一个,再闭合上一个\n this.getCtx().restore()\n cur = cur.parent\n }\n\n\n }\n\n topBorder({ x, y, borderRadius, w, h }) {\n // 左上角开始\n this.getCtx().moveTo(x, y + borderRadius)\n borderRadius && this.getCtx().arc(x + borderRadius, y + borderRadius, borderRadius, 2 * angle, 3 * angle)\n this.getCtx().lineTo(x + w - borderRadius, y)\n }\n\n rightBorder({ x, y, borderRadius, w, h }) {\n // 右上角\n // this.getCtx().moveTo(x + w - borderRadius, y)\n borderRadius && this.getCtx().arc(x + w - borderRadius, y + borderRadius, borderRadius, 3 * angle, 4 * angle)\n this.getCtx().lineTo(x + w, y + h - borderRadius)\n }\n\n bottomBorder({ x, y, borderRadius, w, h }) {\n // 右下角\n // this.getCtx().moveTo(x + w, y + h - borderRadius)\n borderRadius && this.getCtx().arc(x + w - borderRadius, y + h - borderRadius, borderRadius, 0, angle)\n this.getCtx().lineTo(x + borderRadius, y + h)\n }\n\n leftBorder({ x, y, borderRadius, w, h }) {\n // 左下角\n borderRadius && this.getCtx().arc(x + borderRadius, y + h - borderRadius, borderRadius, angle, angle * 2)\n this.getCtx().lineTo(x, y + borderRadius)\n }\n\n _drawBox(element) {\n if (!(element.renderStyles.borderColor || element.renderStyles.shadowBlur)) return\n const { contentWidth, contentHeight, paddingLeft, paddingTop, borderStyle,\n paddingRight, paddingBottom, shadowBlur, shadowColor, backgroundColor, shadowOffsetX, shadowOffsetY,\n borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth, borderWidth } = element.renderStyles\n\n let borderRadius = getBorderRadius(element)\n\n\n // 这里是计算画border的位置,起点位置是在线条中间,所以要考虑线条宽度\n let x = element.contentX - element.renderStyles.paddingLeft - borderLeftWidth / 2\n let y = element.contentY - element.renderStyles.paddingTop - borderTopWidth / 2\n let w = contentWidth + paddingLeft + paddingRight + (borderLeftWidth + borderRightWidth) / 2\n let h = contentHeight + paddingTop + paddingBottom + (borderTopWidth + borderBottomWidth) / 2\n\n this.getCtx().lineCap = element.renderStyles.lineCap\n this.getCtx().strokeStyle = element.renderStyles.borderColor\n this.getCtx().lineJoin = 'round'\n\n // 实现虚线\n if (borderStyle && borderStyle !== 'solid') {\n if (Array.isArray(borderStyle)) {\n this.getCtx().setLineDash(borderStyle)\n } else {\n this.getCtx().setLineDash([5, 5])\n }\n }\n\n const stroke = (borderWidth) => {\n // 有样式则绘制出来\n this.getCtx().lineWidth = borderWidth\n this.getCtx().stroke()\n }\n this._restore(() => {\n this._path(() => {\n\n if (element.renderStyles.borderTopWidth) {\n this.topBorder({ x, y, borderRadius: borderRadius ? borderRadius + (element.renderStyles.borderTopWidth / 2) : 0, w, h })\n // 判断borderwidth 如果都是一样宽,只需要最后一次性绘制,提高性能\n !borderWidth && stroke(element.renderStyles.borderTopWidth)\n }\n if (element.renderStyles.borderRightWidth) {\n this.getCtx().moveTo(x + w - borderRadius - (borderRadius ? (element.renderStyles.borderTopWidth / 2) : 0), y)\n this.rightBorder({ x, y, borderRadius: borderRadius ? borderRadius + element.renderStyles.borderRightWidth / 2 : 0, w, h })\n !borderWidth && stroke(element.renderStyles.borderRightWidth)\n }\n if (element.renderStyles.borderBottomWidth) {\n this.getCtx().moveTo(x + w, y + h - borderRadius - (borderRadius ? (element.renderStyles.borderRightWidth / 2) : 0))\n this.bottomBorder({ x, y, borderRadius: borderRadius ? borderRadius + (element.renderStyles.borderBottomWidth / 2) : 0, w, h })\n !borderWidth && stroke(element.renderStyles.borderBottomWidth)\n }\n if (element.renderStyles.borderLeftWidth) {\n this.getCtx().moveTo(x + borderRadius + (borderRadius ? (element.renderStyles.borderBottomWidth / 2) : 0), y + h)\n this.leftBorder({ x, y, borderRadius: borderRadius ? borderRadius + (element.renderStyles.borderLeftWidth / 2) : 0, w, h })\n stroke(element.renderStyles.borderLeftWidth)\n }\n })\n })\n\n }\n\n _drawBackground(element) {\n const { backgroundColor, contentWidth, contentHeight, shadowColor, shadowBlur,\n paddingLeft, paddingRight, paddingTop, paddingBottom, opacity, shadowOffsetX, shadowOffsetY,\n borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = element.renderStyles\n const ctx = this.getCtx()\n\n let borderRadius = getBorderRadius(element)\n\n\n // 这里是计算画border的位置,起点位置是在线条中间,所以要考虑线条宽度\n let x = element.contentX - element.renderStyles.paddingLeft - borderLeftWidth\n let y = element.contentY - element.renderStyles.paddingTop - borderTopWidth\n let w = contentWidth + paddingLeft + paddingRight + (borderLeftWidth + borderRightWidth)\n let h = contentHeight + paddingTop + paddingBottom + (borderTopWidth + borderBottomWidth)\n\n if (isExact(opacity)) {\n // 绘制透明图\n ctx.globalAlpha = opacity\n }\n\n // 绘制boxshadow\n // 需要在clip之前\n if (shadowColor && shadowBlur) {\n this._restore(() => {\n this._path(() => {\n this.topBorder({ x, y, borderRadius, w, h })\n this.rightBorder({ x, y, borderRadius, w, h })\n this.bottomBorder({ x, y, borderRadius, w, h })\n this.leftBorder({ x, y, borderRadius, w, h })\n })\n if (isExact(shadowOffsetX)) {\n this.getCtx().shadowOffsetX = shadowOffsetX\n }\n if (isExact(shadowOffsetY)) {\n this.getCtx().shadowOffsetY = shadowOffsetY\n }\n this.getCtx().shadowBlur = shadowBlur\n this.getCtx().shadowColor = shadowColor\n this.getCtx().fillStyle = shadowColor\n this.getCtx().fill()\n })\n }\n\n this._clip(element)\n\n\n\n // draw background\n if (backgroundColor) {\n this.getCtx().fillStyle = this._parseBackground(backgroundColor, element)\n this.getCtx().fillRect(element.contentX - paddingLeft, element.contentY - paddingTop, contentWidth + paddingLeft + paddingRight, contentHeight + paddingTop + paddingBottom)\n }\n\n // for debug\n if (this.isDebug()) {\n this.getCtx().strokeStyle = element.debugColor || 'green'\n this.getCtx().strokeRect(element.contentX, element.contentY, element.renderStyles.contentWidth, element.renderStyles.contentHeight)\n // ctx.strokeStyle = '#fff'\n // ctx.strokeText(`${parseInt(this.contentX)} ${parseInt(this.contentY)} ${contentWidth} ${contentHeight}`, this.contentX + 100, this.contentY + 10)\n\n //\n }\n }\n\n _clip(element) {\n if (element.renderStyles.overflow !== 'hidden') return\n const { contentWidth, contentHeight, paddingLeft, paddingTop,\n paddingRight, paddingBottom, shadowBlur, shadowColor, backgroundColor,\n borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = element.renderStyles\n\n const angle = Math.PI / 2\n\n let borderRadius = getBorderRadius(element)\n\n // 为了把border也切进去\n let x = element.contentX - element.renderStyles.paddingLeft - borderLeftWidth\n let y = element.contentY - element.renderStyles.paddingTop - borderTopWidth\n let w = contentWidth + paddingLeft + paddingRight + borderLeftWidth + borderRightWidth\n let h = contentHeight + paddingTop + paddingBottom + borderTopWidth + borderBottomWidth\n\n this._path(() => {\n this.topBorder({ x, y, borderRadius, w, h })\n this.rightBorder({ x, y, borderRadius, w, h })\n this.bottomBorder({ x, y, borderRadius, w, h })\n this.leftBorder({ x, y, borderRadius, w, h })\n })\n\n\n this.getCtx().clip()\n\n }\n\n _parseBackground(color, element) {\n if (Array.isArray(color)) {\n const gradient = this.getCtx().createLinearGradient(element.contentX, element.contentY, element.contentX+element.renderStyles.contentWidth, element.contentY+element.renderStyles.contentHeight)\n for (let i = 0; i < color.length; i++) {\n if (i === 0) {\n gradient.addColorStop(0, color[0])\n } else {\n gradient.addColorStop(i / (color.length - 1), color[i])\n }\n }\n return gradient\n } else {\n return color\n }\n }\n\n\n _drawText(element) {\n const { color, contentWidth, lineHeight, textAlign, textIndent, textDecoration } = element.renderStyles\n let x = element.contentX\n this.getCtx().fillStyle = color\n this.getCtx().textAlign = textAlign\n this.getCtx().font = element._getFont()\n this.getCtx().textBaseline = 'middle'\n if (textAlign === STYLES.TEXT_ALIGN.RIGHT) {\n x = element.contentX + contentWidth\n } else if (textAlign === STYLES.TEXT_ALIGN.CENTER) {\n x = element.contentX + (contentWidth / 2)\n }\n let _x = x\n let _y = 0\n element._lines.forEach((line, index) => {\n if (index === 0 && textIndent) {\n // 第一行实现textIndent\n _x = x + textIndent\n } else {\n _x = x\n }\n _y = (element.contentY + ((lineHeight) / 2) + lineHeight * index) + 0.5\n if(this.isDebug()){\n this.getCtx().fillRect(_x,_y,2,2)\n }\n this.getCtx().fillText(line.text, _x, _y)\n if (isWX() && element.renderStyles.fontWeight !== 400) {\n // 小程序 字体加粗不生效\n const offset = element.renderStyles.fontSize * 0.001\n this.getCtx().fillText(line.text, _x - offset, _y)\n }\n // draw decoration\n if (textDecoration) {\n const decorationType = textDecoration[0]\n _y += 1\n this._restore(() => {\n this._path(() => {\n let decorationY = _y\n if (decorationType === 'underline') {\n decorationY = _y + element._layout.fontHeight / 2\n } else if (decorationType === 'line-through') {\n decorationY = _y\n }\n this.getCtx().moveTo(_x, decorationY)\n this.getCtx().lineTo(_x + line.layout.width, decorationY)\n })\n this.getCtx().strokeStyle = color\n this.getCtx().stroke()\n })\n }\n })\n }\n\n /**\n * @param {String} text\n * @return {Object}\n */\n measureText(element, text) {\n let w = 0\n let h = 0\n this._restore(() => {\n this.getCtx().font = element._getFont()\n const { width,actualBoundingBoxAscent } = this.getCtx().measureText(text)\n w = width\n h = actualBoundingBoxAscent || element.renderStyles.fontSize * 0.7\n })\n return {\n width: w,\n fontHeight:h+1\n }\n }\n\n _drawImage(element) {\n if (!element._image) return\n const { contentWidth, contentHeight } = element.renderStyles\n const { mode } = element.options.attrs\n const { sx, sy, swidth, sheight, dx, dy, dwidth, dheight, width: imageW, height: imageH } = element._imageInfo\n if (mode === 'aspectFill') {\n this.getCtx().drawImage(element._image, sx, sy, swidth, sheight, element.contentX, element.contentY, contentWidth, contentHeight)\n } else if (mode === 'aspectFit') {\n this.getCtx().drawImage(element._image, 0, 0, imageW, imageH, dx, dy, dwidth, dheight)\n } else {\n this.getCtx().drawImage(element._image, element.contentX, element.contentY, contentWidth, contentHeight)\n }\n }\n\n _drawScroll(element) {\n this.getCtx().translate(element.currentScrollX, element.currentScrollY)\n }\n\n /**\n * 这里应该保证onload src等接口\n */\n getImageInstance(src) {\n let image = null\n\n // 同样的路径返回缓存\n if (this.imageBus[src]) {\n image = this.imageBus[src]\n } else {\n\n if (isWX()) {\n if (this.getCanvas()) {\n image = this.getCanvas().createImage()\n } else {\n console.warn('小程序请使用设置canvas参数以创建图片')\n image = getImage(src)\n }\n } else {\n image = new Image()\n }\n\n if (src) {\n this.imageBus[src] = new Promise((resolve, reject) => {\n image.onload = (e) => {\n resolve({\n image: isWX() && !this.getCanvas() ? e.image : image,\n info: {\n width: isWX() ? image.width : e.target.width,\n height: isWX() ? image.height : e.target.height\n }\n })\n }\n image.onerror = (err) => {\n reject(err)\n }\n })\n }\n\n image.src = src\n }\n return this.imageBus[src]\n }\n\n render(node) {\n this.lastFrameComplete = false\n this.lastPaintTime = Date.now()\n if (!node.parent) {\n // root\n this.getCtx().clearRect(0, 0, this.getLayer().options.width, this.getLayer().options.height)\n } else {\n this.getCtx().clearRect(node.x, node.y, node.renderStyles.width, node.renderStyles.height)\n }\n let element = null\n walk(node, (renderNode, callContinue, callNext) => {\n if (renderNode.isVisible()) {\n // 可见的才渲染\n this.paint(renderNode)\n } else {\n // 跳过整个子节点\n callNext()\n this._helpParentRestoreCtx(renderNode)\n }\n })\n if (isWX()) {\n // 兼容小程序\n this.getCtx().draw && this.getCtx().draw()\n }\n\n this.lastFrameComplete = true\n\n }\n\n renderFPS() {\n\n }\n\n readyToRender(element) {\n\n // this.element = generateRenderTree(element)\n this.element = element\n\n const options = this.getLayer().options\n\n this.lastPaintTime = Date.now()\n\n if (options && options.animate) {\n this.animate()\n } else {\n this.render(this.element)\n }\n\n }\n\n requestRepaint(element) {\n if (this.isAnimate) return\n // 如果已经有frame在排队等待了 忽略\n // if(!this.lastFrameComplete) return\n // let nextFrameTime = Date.now() - this.lastPaintTime\n // if(nextFrameTime < 16){\n // setTimeout(() => this.render(this.element),nextFrameTime)\n // }else{\n this.render(this.element)\n // }\n\n }\n\n // could be null\n getCanvas() {\n const options = this.getLayer().options\n return options && options.canvas || null\n }\n\n _animate(preTime) {\n const now = Date.now()\n this.render(this.element)\n if (!this.isAnimate) return\n window.requestAnimationFrame(() => this._animate(now))\n }\n\n /**\n * 不建议使用了\n */\n animate() {\n this.isAnimate = true\n window.requestAnimationFrame(() => this._animate())\n }\n\n stopAnimate() {\n this.isAnimate = false\n }\n\n // 所有副作用完成\n // 图片加载异步请求\n onEffectFinished() {\n const list = Object.keys(this.imageBus).map(key => {\n return this.imageBus[key]\n })\n return Promise.all(list)\n }\n\n\n\n}\n\nfunction getBorderRadius(element) {\n const { paddingWidth, paddingHeight } = element.renderStyles\n let { borderRadius } = element.renderStyles\n if (borderRadius * 2 > paddingWidth) {\n // 如果大于一半,则角不是90度,统一限制最大为一半\n borderRadius = paddingWidth / 2\n }\n if (borderRadius * 2 > paddingHeight) {\n borderRadius = paddingHeight / 2\n }\n if (borderRadius < 0) borderRadius = 0\n return floor(borderRadius)\n}\n\n// function generateRenderTree(element){\n// const _root = new RenderNode(element)\n// let preZ = 0\n// let pivotZ = 0\n// let cur = null\n// let stack = [_root]\n// while(stack.length){\n// cur = stack.pop()\n// if(cur.element.hasChildren()){\n// cur.children = cur.element._getChildren().map(item => new RenderNode(item))\n// // sort by zIndex\n// cur.children = qSort3(cur.children,(pre,pivot) => {\n// preZ = pre.element.renderStyles.zIndex || 0\n// pivotZ = pivot.element.renderStyles.zIndex || 0\n// return preZ - pivotZ\n// })\n// Array.prototype.push.apply(stack,cur.children)\n// }\n// }\n// TreeNode.connectChildren(_root)\n// return _root\n// }\n\n// class RenderNode extends TreeNode {\n// constructor(element){\n// super()\n// this.element = element\n// }\n// }\n","import { isWX } from \"./utils\"\n\n// 只支持小程序最新的支持同层渲染的canvas api,\n// 不用了\nexport function getImage(url) {\n const instance = {onload: () => {}}\n new Promise((resolve, reject) => {\n wx.downloadFile({\n url:url,\n success(res) {\n wx.getImageInfo({\n src: res.tempFilePath,\n success(res1) {\n resolve({\n target: {\n width: res1.width,\n height: res1.height\n },\n image: res.tempFilePath\n })\n }\n })\n },\n fail(err) {\n reject(err)\n }\n })\n })\n .then((res) => {\n instance.onload(res)\n })\n .catch(err => {\n\n })\n return instance\n}\n\n","import EventManager from './event-manager'\nimport { walk, breadthFirstSearch, breadthFirstSearchRight, walkParent, isWX } from './utils'\nimport TreeNode from './tree-node'\nimport CanvasRender from './canvas-render'\nexport default class Layer {\n constructor(ctx, options) {\n this.ctx = ctx\n this.node = null\n this.isAnimate = false\n this.nodeList = []\n this.p2cList = []\n this.c2pList = []\n this.renderList = []\n this.options = options\n this.eventManager = new EventManager(options)\n this.render = new CanvasRender(this)\n }\n\n update(ctx, options) {\n this.ctx = ctx\n this.options = options\n this.options.renderStyles = options\n this.node.container = this.options\n }\n\n mountNode(node) {\n this.node = node\n this.node.root = this.node\n this.node.layer = this\n this.node.container = this.options\n // 事件也清空一下,重新挂载\n this.eventManager.clear()\n this.initRender()\n }\n\n initRender() {\n // for 打印耗时\n const startTime = Date.now()\n\n TreeNode.connectChildren(this.node)\n this.initP2CList()\n this.initC2PList()\n\n this.flow()\n\n // flow 完成后监听effect完成\n this.render.onEffectFinished()\n .then((res) => this.lifecycle('onEffectSuccess', res))\n .catch((res) => this.lifecycle('onEffectFail', res))\n // .finally((res) => this.lifecycle('onEffectFinished', res))\n\n this.repaint()\n\n console.log(`渲染${this.p2cList.length}个元素 耗时 ${(Date.now() - startTime)} ms`)\n }\n\n initP2CList() {\n // 广度优先\n this.p2cList = breadthFirstSearch(this.node)\n }\n\n initC2PList() {\n this.c2pList = breadthFirstSearchRight(this.node)\n }\n\n\n flow(node = this.node) {\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i].init()\n }\n\n this.reflow()\n }\n\n initPaintList() {\n // 这里实现index\n this.renderList = this.nodeList\n }\n\n reflow(node = this.node) {\n\n for (let i = 0; i < this.c2pList.length; i++) {\n this.c2pList[i]._initWidthHeight()\n }\n\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i]._initPosition()\n }\n }\n\n reflowElement(element) {\n // 如果有line,则需要重第一个开始\n let target = element\n while (target && target.line) {\n target = target.parent\n }\n const p2cList = breadthFirstSearch(target)\n for (let i = 0; i < p2cList.length; i++) {\n p2cList[i]._initStyles()\n }\n\n // 所有子元素\n const children = breadthFirstSearchRight(target)\n for (let i = 0; i < children.length; i++) {\n children[i]._initWidthHeight()\n }\n\n if (!element.isInFlow()) {\n for (let i = 0; i < p2cList.length; i++) {\n p2cList[i]._initPosition()\n }\n this.repaint()\n } else {\n this.onElementChange(target)\n }\n\n\n }\n\n onElementRemove(element) {\n this.eventManager.removeElement(element)\n this.initC2PList()\n this.initP2CList()\n this.reflowElement(element)\n }\n\n onElementAdd(element) {\n TreeNode.connectChildren(element)\n this.initC2PList()\n this.initP2CList()\n breadthFirstSearch(element).forEach(item => item.init())\n this.reflowElement(element)\n }\n\n // 元素变化后调用,尽可能少重排重绘\n onElementChange(element) {\n\n walkParent(element, (parent, callbreak) => {\n parent._initWidthHeight()\n if (parent.type === 'scroll-view') callbreak()\n })\n\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i]._initPosition()\n }\n this.repaint()\n }\n\n callBeforePaint() {\n for (let i = 0; i < this.p2cList.length; i++) {\n this.p2cList[i].beforePaint && this.p2cList[i].beforePaint()\n }\n }\n\n /**\n * 可以给定element,则只会重绘element所在的区域\n * @param {Element} element\n */\n repaint(element = this.node) {\n if (isWX()) {\n // 微信环境下始终重绘整个树\n element = this.node\n }\n if (!element.isInFlow()) element = this.node\n\n this.callBeforePaint()\n\n this.render.readyToRender(this.node)\n }\n\n animate() {\n console.warn('use [animate] option instead!')\n }\n\n getElementBy() {\n return this.node.getElementBy(...arguments)\n }\n\n lifecycle(name, arg) {\n if (this.options.lifecycle) {\n this.options.lifecycle[name] && this.options.lifecycle[name](arg)\n }\n }\n\n}\n\n\n","import View from './view'\nimport { easeInOutElastic, isExact, isAuto, floor } from './utils'\nimport STYLES from './constants'\n\nexport default class ScrollView extends View {\n\n constructor(options, children) {\n const { styles, ...rest } = options\n super(rest, children)\n this.options.styles = {\n direction: styles.direction || 'y'\n }\n // 外面包裹一层容器,内层的滚动\n options.styles.overflow = 'hidden'\n this.type = 'scroll-view'\n this._scrollView = new View(options, [this])\n this._scrollView.type = 'scroll-view-container'\n this.visibleIndex = null\n this.renderOnDemand = options.attrs && options.attrs.renderOnDemand || false\n return this._scrollView\n }\n\n _getDefaultStyles() {\n return {\n ...STYLES.DEFAULT_STYLES,\n direction: 'y',\n }\n }\n\n beforePaint() {\n this.initChildrenVisible()\n }\n\n _initWidthHeight() {\n super._initWidthHeight()\n // 这里需要父级款高度,但是外层必须是exact\n this.initScroll()\n }\n\n _paint() {\n this.getRender()._drawBackground(this)\n this.getRender()._drawScroll(this)\n this.getRender()._drawBox(this)\n }\n\n init() {\n super.init()\n this.addEventListener()\n const { height, width } = this._scrollView.styles\n const { direction } = this.styles\n if (direction.match('y')) {\n if (isAuto(height)) {\n // 必须设置\n console.error('scroll-view 必须设置明确的高度')\n } else {\n this.styles.height = 'auto'\n this.renderStyles.height = 'auto'\n }\n }\n if (direction.match('x')) {\n if (isAuto(width)) {\n // 必须设置\n console.error('scroll-view 必须设置明确的宽度')\n } else {\n this.styles.width = 'auto'\n this.renderStyles.width = 'auto'\n }\n }\n }\n\n addEventListener() {\n // 监听滚动\n this.currentScrollX = 0\n this.currentScrollY = 0\n let direction = this.styles.direction\n let startX = 0\n let startY = 0\n let lastStartX = 0\n let lastStartY = 0\n let startMove = false\n let offsetX = 0\n let offsetY = 0\n let speedX = 0\n let speedY = 0\n let glideInterval = null\n let resistanceX = 1\n let resistanceY = 1\n\n this.getLayer().eventManager.EVENTS.forEach(eventName => {\n this.getLayer().eventManager.addEventListener(eventName, (e) => {\n if (direction.match('y')) {\n e.relativeY -= this.currentScrollY\n }\n if (direction.match('x')) {\n e.relativeX -= this.currentScrollX\n }\n }, this._scrollView, true)\n })\n\n this.getLayer().eventManager.addEventListener('mousewheel', (e) => {\n if (!this.scrollBy(e.deltaX, e.deltaY)) {\n this.scrollTo({ x: e.deltaX <= 0 ? this.maxScrollX : 0, y: e.deltaY <= 0 ? this.maxScrollY : 0 })\n } else {\n e.stopPropagation()\n }\n }, this._scrollView)\n\n this.getLayer().eventManager.addEventListener('touchstart', (e) => {\n e.stopPropagation()\n startX = e.x\n startY = e.y\n lastStartX = startX\n lastStartY = startY\n startMove = true\n clearInterval(glideInterval)\n }, this._scrollView)\n this.getLayer().eventManager.addEventListener('touchmove', (e) => {\n if (startMove) {\n e.stopPropagation()\n offsetX = (e.x - startX)\n offsetY = (e.y - startY)\n if (this.scrollBy(offsetX, offsetY)) {\n lastStartX = startX\n lastStartY = startY\n startX = e.x\n startY = e.y\n }\n }\n }, this._scrollView)\n this.getLayer().eventManager.addEventListener('touchend', (e) => {\n if (startMove) {\n startMove = false\n\n speedX = (e.x - lastStartX)\n speedY = (e.y - lastStartY)\n resistanceX = -speedX * 0.02\n resistanceY = -speedY * 0.02\n clearInterval(glideInterval)\n glideInterval = setInterval(() => {\n if (!this.scrollBy(speedX, speedY)) {\n this.scrollTo(this.currentScrollX + speedX, this.currentScrollY + speedY)\n clearInterval(glideInterval)\n }\n speedX += resistanceX\n speedY += resistanceY\n if (speedX * speedX <= 0.05 && speedY * speedY <= 0.05) {\n speedX = 0\n speedY = 0\n clearInterval(glideInterval)\n }\n }, 16)\n }\n }, this._scrollView)\n }\n\n initScroll() {\n const { contentWidth: offsetWidth, contentHeight: offsetHeight } = this._scrollView.renderStyles\n const { width: scrollWidth, height: scrollHeight, direction } = this.renderStyles\n this.maxScrollX = scrollWidth - offsetWidth\n this.maxScrollY = scrollHeight - offsetHeight\n }\n\n calcScrollBoundX(offsetX) {\n if ((- this.currentScrollX - offsetX) > this.maxScrollX) {\n return false\n } else if (this.currentScrollX + offsetX > 0) {\n return false\n }\n\n return true\n }\n\n calcScrollBoundY(offsetY) {\n if ((- this.currentScrollY - offsetY) > this.maxScrollY) {\n return false\n } else if (this.currentScrollY + offsetY > 0) {\n return false\n }\n\n return true\n }\n\n scrollByX(offsetX) {\n if (!this.renderStyles.direction.match('x')) return false\n if (this.calcScrollBoundX(offsetX)) {\n this.currentScrollX += offsetX\n return true\n } else {\n return false\n }\n }\n\n scrollByY(offsetY) {\n if (!this.renderStyles.direction.match('y')) return false\n if (this.calcScrollBoundY(offsetY)) {\n this.currentScrollY += floor(offsetY)\n this.calcChildrenVisible()\n // this.getLayer().repaint(this._scrollView)\n return true\n } else {\n return false\n }\n }\n\n scrollBy(offsetX, offsetY) {\n // 这里要两个都运行,所以不要用短路\n if (this.scrollByX(offsetX) | this.scrollByY(offsetY)) {\n this.getRender().requestRepaint(this._scrollView)\n return true\n }\n return false\n }\n\n scrollTo({ x, y }) {\n if (isExact(x) && this.maxScrollX > 0) {\n x = x\n if (x > this.maxScrollX) x = this.maxScrollX\n this.currentScrollX = -floor(x)\n }\n if (isExact(y) && this.maxScrollY > 0) {\n y = y\n if (y > this.maxScrollY) y = this.maxScrollY\n this.currentScrollY = -floor(y)\n }\n this.initChildrenVisible()\n this.getRender().requestRepaint(this._scrollView)\n }\n\n // TODO:\n initChildrenVisible() {\n if (!this.renderOnDemand) return\n\n // console.log('==============')\n const children = this._getChildrenInFlow()\n // 左\n for (let i = 0; i < children.length; i++) {\n if (this.isElementInViewport(children[i])) {\n this.visibleIndex = [i, -1]\n break\n } else {\n children[i].visible = false\n }\n }\n\n // 右\n for (let i = children.length - 1; i >= 0; i--) {\n if (this.isElementInViewport(children[i])) {\n this.visibleIndex[1] = i\n break\n } else {\n children[i].visible = false\n }\n }\n\n // 中间\n for (let i = this.visibleIndex[0]; i <= this.visibleIndex[1]; i++) {\n children[i].visible = true\n }\n }\n\n // 只用计算两头\n // 数据量时能显著提高效率\n // 滚动太快会有问题,暂时使用上面的init\n calcChildrenVisible() {\n if (!this.renderOnDemand) return\n const children = this._getChildrenInFlow()\n const head = generateSiblingNodeIndex(this.visibleIndex[0], 5)\n const foot = generateSiblingNodeIndex(this.visibleIndex[1], 5)\n let visibleIndex = []\n for (let i = head[0]; i <= head[head.length - 1]; i++) {\n if (children[i]) {\n if (this.isElementInViewport(children[i])) {\n children[i].visible = true\n if (!visibleIndex.length) {\n visibleIndex.push(i)\n }\n } else {\n children[i].visible = false\n }\n }\n }\n for (let i = foot[foot.length - 1]; i >= foot[0]; i--) {\n if (children[i]) {\n if (this.isElementInViewport(children[i])) {\n children[i].visible = true\n if (visibleIndex.length === 1) {\n visibleIndex.push(i)\n }\n } else {\n children[i].visible = false\n }\n }\n }\n this.visibleIndex = visibleIndex\n if (this.visibleIndex.length < 2) {\n this.initChildrenVisible()\n }\n }\n\n isElementInViewport(element) {\n if (this.styles.direction.match('y')) {\n return ((element.y + element.renderStyles.height + this.currentScrollY) > this._scrollView.contentY)\n && ((element.y + this.currentScrollY) < this._scrollView.contentY + this._scrollView.renderStyles.contentHeight)\n } else {\n return true\n // return ((element.x + element.renderStyles.width + this.currentScroll) > this._scrollView.contentX)\n // && ((element.x + this.currentScroll) < this._scrollView.contentX + this._scrollView.renderStyles.contentWidth)\n }\n }\n\n}\n\n\nfunction generateSiblingNodeIndex(index, offset) {\n let start = index - offset\n let end = index + offset\n let list = []\n for (let i = start; i <= end; i++) {\n list.push(i)\n }\n return list\n}\n","import View from './view'\nimport Text from './text'\nimport Image from './image'\nimport Layer from './layer'\nimport ScrollView from './scroll-view'\n\n/**\n * 生成一个element tree\n * @param {String} name\n * @param {Function} options\n */\n\nconst elementFactory = {}\n//\nregisterComponent('view', (options, children) => new View(options, children))\nregisterComponent('text', (options, children) => new Text(options, children))\nregisterComponent('image', (options, children) => new Image(options, children))\nregisterComponent('scroll-view', (options, children) => new ScrollView(options, children))\nregisterComponent('scrollview', (options, children) => new ScrollView(options, children))\n\nexport function createElement(model) {\n // 生成树\n function c(name, options = {}, children = []) {\n // if (arguments.length < 3) {\n // throw Error(`Element [${name}]: need 3 argument but get 2`)\n // }\n let _element = null\n let _children = children\n if (elementFactory[name]) {\n if (typeof children === 'string' && name !== 'text') {\n // 支持text简写\n _children = [new Text({}, children)]\n } else if (!Array.isArray(children) && name !== 'text') {\n throw Error(`Element [${name}]:Children must be type of Array!`)\n }\n _element = elementFactory[name](options, _children, c)\n } else {\n throw Error(`Unknown tag name [${name}] !`)\n }\n return _element\n }\n const _model = model(c)\n // 挂载children\n return _model\n}\n\nexport function createLayer(ctx, options) {\n return new Layer(ctx, options)\n}\n\n// 注册全局组件\nexport function registerComponent(name, factory) {\n if (elementFactory[name]) {\n throw Error(`Already exist tag name [${name}] !`)\n }\n elementFactory[name] = factory\n}\n\n\n\n\n\n","\nimport { createElement, createLayer, registerComponent } from './create-element'\nimport px from './px'\nimport './weapp-adapter'\nimport View from './view'\nimport Text from './text'\nimport Image from './image'\nimport Layer from './layer'\nimport ScrollView from './scroll-view'\nimport { mergeOptions } from './utils'\n\n\nconst ef = {\n createLayer,\n createElement,\n component: registerComponent,\n View,\n Text,\n Image,\n Layer,\n ScrollView,\n mergeOptions\n}\n\n\n\nexport default ef\n\n"],"names":["DISPLAY","BLOCK","INLINE_BLOCK","INLINE","FLEX","NONE","WIDTH","AUTO","OUTER","FLEX_DIRECTION","ROW","COLUMN","POSITION","ABSOLUTE","FIXED","RELATIVE","STATIC","DEFAULT_STYLES","display","fontSize","fontWeight","fontFamily","color","paddingTop","paddingBottom","paddingLeft","paddingRight","marginTop","marginBottom","marginLeft","marginRight","height","borderRadius","lineCap","flexDirection","verticalAlign","textAlign","justifyContent","alignItems","whiteSpace","zIndex","visible","position","TEXT_ALIGN","LEFT","RIGHT","CENTER","isExact","num","isAuto","isOuter","match","parseOuter","_n","parseInt","replace","isNaN","walk","element","callback","_continue","_next","_callContinue","_callNext","stack","push","length","item","pop","children","_getChildren","i","walkParent","cur","stop","callbreak","parent","isWX","Boolean","wx","getSystemInfoSync","err","breadthFirstSearch","node","nodes","queue","unshift","shift","_generateRender","breadthFirstSearchRight","reverse","mergeKeys","floor","val","Line","[object Object]","this","width","contentWidth","y","doorClosed","outerWidth","container","elements","start","end","offsetX","id","Math","random","el","initHeight","styles","Infinity","renderStyles","add","lineHeight","right","_getContainerLayout","contentX","x","getPreLine","initLayout","getOffsetY","line","refreshWidthHeight","next","closeLine","refreshXAlign","pre","_getPreLayout","contentY","KEY","STYLES","contentHeight","FlexBox","super","exactValue","flexTotal","key","calcFlex","flex","containerWidth","forEach","child","_refreshContentWithLayout","alignSelf","TreeNode","hasChildren","filter","map","index","_setParent","_setSibling","connectChildren","root","Array","isArray","treeNode","Error","indexOf","splice","removeChild","_completeFlex","isInFlow","_completeWidth","borderWidth","borderLeftWidth","borderRightWidth","borderBottomWidth","borderTopWidth","overflow","_completeBorder","_completeFont","padding","margin","_completePaddingMargin","Element","options","Object","assign","attrs","on","render","_initStyles","initEvent","keys","eventName","getLayer","eventManager","EVENTS","includes","addEventListener","removeElement","layer","mountNode","_getDefaultStyles","_getParentStyles","_completeStyles","_initRenderStyles","parentWidth","parentHeight","paddingWidth","paddingHeight","_getTotalBorderWidth","_getTotalBorderHeight","_InFlexBox","_bindFlexBox","relativeTo","findRelativeTo","curStyles","extendStyles","completeStyles","ctx","layout","_measureLayout","_refreshLayoutWithContent","_bindLine","refreshElementPosition","top","bottom","left","canIEnter","bind","_getChildrenInFlow","value","appendChild","onElementAdd","prependChild","onElementRemove","append","prepend","_needReflow","reflowElement","getRender","requestRepaint","View","type","getCtx","getCanvas","_drawBackground","_drawBox","Text","_layout","_lines","debugColor","_drawText","measureText","_calcLine","textWidth","textHeight","parentContentWidth","text","lineIndex","lineText","lastLayout","maxLine","substring","undefined","$Image","_imageInfo","sx","sy","swidth","sheight","dx","dy","dwidth","dheight","_image","init","timeout","setTimeout","_loadImage","_drawImage","mode","Promise","resolve","reject","getImageInstance","src","then","info","image","_layoutImage","isVisible","load","catch","error","imageW","imageH","w","h","getHeightByWidth","getWidthByHeight","originWidth","originHeight","events","EventManager","simulateClick","clear","touchStartEvent","event","Event","_emit","checkClick","deltaX","deltaY","e","tree","callbackList","curArr","walkArray","callBreak","isEnd","isPointInElement","relativeX","relativeY","runCapture","currentTarget","runCallback","cancelBubble","a1","a2","a3","a4","remove","isCapture","list","console","addCallback","target","p","Callback","addCapture","startx","starty","endx","endy","distance","click","captureList","params","call","arr","_break","angle","PI","CanvasRender","imageBus","isAnimate","lastPaintTime","lastFrameComplete","throttle","threshold","timer","fn","getThrottle","debug","save","restore","beginPath","closePath","_paint","afterPaint","_helpParentRestoreCtx","moveTo","arc","lineTo","borderColor","shadowBlur","borderStyle","shadowColor","backgroundColor","shadowOffsetX","shadowOffsetY","getBorderRadius","strokeStyle","lineJoin","setLineDash","stroke","lineWidth","_restore","_path","topBorder","rightBorder","bottomBorder","leftBorder","opacity","globalAlpha","fillStyle","fill","_clip","_parseBackground","fillRect","isDebug","strokeRect","clip","gradient","createLinearGradient","addColorStop","textIndent","textDecoration","font","_getFont","textBaseline","_x","_y","fillText","offset","decorationType","decorationY","fontHeight","actualBoundingBoxAscent","drawImage","translate","currentScrollX","currentScrollY","createImage","warn","url","instance","onload","downloadFile","res","getImageInfo","tempFilePath","res1","getImage","Image","onerror","Date","now","clearRect","renderNode","callContinue","callNext","paint","draw","animate","canvas","preTime","window","requestAnimationFrame","_animate","all","Layer","nodeList","p2cList","c2pList","renderList","initRender","startTime","initP2CList","initC2PList","flow","onEffectFinished","lifecycle","repaint","log","reflow","_initWidthHeight","_initPosition","onElementChange","beforePaint","callBeforePaint","readyToRender","getElementBy","arguments","name","arg","ScrollView","rest","direction","_scrollView","visibleIndex","renderOnDemand","initChildrenVisible","initScroll","_drawScroll","startX","startY","lastStartX","lastStartY","startMove","offsetY","speedX","speedY","glideInterval","resistanceX","resistanceY","scrollBy","stopPropagation","scrollTo","maxScrollX","maxScrollY","clearInterval","setInterval","offsetWidth","offsetHeight","scrollWidth","scrollHeight","calcScrollBoundX","calcScrollBoundY","calcChildrenVisible","scrollByX","scrollByY","isElementInViewport","head","generateSiblingNodeIndex","foot","elementFactory","registerComponent","factory","createLayer","createElement","model","c","_element","_children","component","mergeOptions","mergedOptions"],"mappings":"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"} \ No newline at end of file diff --git a/example/custom-render.html b/example/custom-render.html new file mode 100644 index 0000000..3b2138d --- /dev/null +++ b/example/custom-render.html @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/index.html b/example/index.html index 3d3db27..ff8c841 100644 --- a/example/index.html +++ b/example/index.html @@ -51,8 +51,9 @@ { title: 'Image 图片', desc: '图片缩放类型', url: 'image.html' }, { title: 'Components 组件库', desc: 'UI组件库示例', url: 'ui.html' }, { title: 'Event 事件', desc: '事件监听', url: 'event.html' }, + { title: 'Custom render 自定义render', desc: '自定义render,操作ctx绘图', url: 'custom-render.html' }, + { title: '"Dom" 操作element', desc: '类似修改dom的能力', url: 'change-element.html' }, { title: 'Demo', desc: '展示了滚动、事件、flex布局、文本换行对齐等能力', url: 'test.html' }, - { title: '操作element', desc: '类似修改dom的能力', url: 'change-element.html' }, { title: 'Test', desc: '测试用', url: 'test1.html' }, ] diff --git a/lib/view.js b/lib/view.js index d3346fa..1d40a37 100644 --- a/lib/view.js +++ b/lib/view.js @@ -17,8 +17,12 @@ export default class View extends Element { } _paint() { - this.getRender()._drawBackground(this) - this.getRender()._drawBox(this) + if(this.options.render){ + this.options.render(this.getRender().getCtx(),this.getRender().getCanvas(),this) + }else{ + this.getRender()._drawBackground(this) + this.getRender()._drawBox(this) + } }