(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):(a=a||self,b(a.AxRevealHighlight={}))})(this,function(a){'use strict';function b(a,b){return b?new d(a):new e(a)}function c(){customElements.define(i.ElementName,i),customElements.define(j.ElementName,j),customElements.define(k.ElementName,k)}class d{constructor(a){if(!d.colorParser){const a=document.createElement("div");a.style.display="none !important",document.body.appendChild(a),d.colorParser=a,d.colorParserStyle=window.getComputedStyle(a)}this.el=a,this.style=window.getComputedStyle(a)}size(){return this.style.length}get(a){return this.style.getPropertyValue(a).trim()}getColor(a){return d.colorParser.style.color=this.get(a),d.colorParserStyle.color||"rgb(0, 0, 0)"}getNumber(a){// Length values in computed style will always in the unit of px
// Maybe NaN
return parseFloat(this.get(a))}}class e{constructor(a){this.el=a,this.style=a.computedStyleMap()}size(){return this.style.size}get(a){return this.style.get(a).toString()}getColor(a){return this.get(a)}getNumber(a){const b=this.style.get(a).value;return"number"==typeof b?b:parseFloat(b);// Maybe NaN
}}class f{constructor(a,c){this.pxRatio=window.devicePixelRatio||1,this.paintedWidth=0,this.paintedHeight=0,this.cachedRevealBitmap={radius:0,color:"",opacity:0,bitmaps:[]},this.cachedStyle={top:-1,left:-1,width:-1,height:-1,trueFillRadius:[0,0],color:"",opacity:1,borderStyle:"",borderWidth:1,fillMode:"",fillRadius:0,diffuse:!0,revealAnimateSpeed:0,revealReleasedAccelerateRate:0},this.mouseUpClientX=null,this.mouseUpClientY=null,this.mouseDownAnimateStartFrame=null,this.mouseDownAnimateCurrentFrame=null,this.mouseDownAnimateReleasedFrame=null,this.mouseDownAnimateLogicFrame=null,this.mousePressed=!1,this.mouseReleased=!1,this.currentFrameId=-1,this.cachedFrameId=-2,this.cacheCanvasPaintingStyle=()=>{var a=Math.round;if(this.currentFrameId===this.cachedFrameId)return;const c=!!document.documentElement.dataset.revealCompat,d=b(this.canvas,c);if(0===d.size())return;const e=this.canvas.getBoundingClientRect(),f=d.getColor("--reveal-color"),g=f.match(/\((\d+,\s*\d+,\s*\d+)[\s\S]*?\)/),h={top:a(e.top),left:a(e.left),width:a(e.width),height:a(e.height),color:g&&1<g.length?g[1]:"0, 0, 0",opacity:d.getNumber("--reveal-opacity"),borderStyle:d.get("--reveal-border-style"),borderWidth:d.getNumber("--reveal-border-width"),fillMode:d.get("--reveal-fill-mode"),fillRadius:d.getNumber("--reveal-fill-radius"),diffuse:"true"===d.get("--reveal-diffuse"),revealAnimateSpeed:d.getNumber("--reveal-animate-speed"),revealReleasedAccelerateRate:d.getNumber("--reveal-released-accelerate-rate")},{width:i,height:j,fillMode:k,fillRadius:l}=h;let m=[0,0];switch(k){case"none":break;case"relative":m=[i,j].sort((c,a)=>c-a).map(a=>a*l);break;case"absolute":m=[l,l];break;default:throw new SyntaxError("The value of `--reveal-border-style` must be `relative`, `absolute` or `none`!");}this.cachedStyle=Object.assign({},h,{trueFillRadius:m}),this.cachedFrameId=this.currentFrameId},this.cacheRevealBitmaps=()=>{if(!this.ctx)return;const{color:a,opacity:b,trueFillRadius:c}=this.cachedStyle,d=c[1],e=2*d,f=this.cachedRevealBitmap;if(d!==f.radius||a!=f.color||b!=f.opacity){this.cachedRevealBitmap={radius:d,color:a,opacity:b,bitmaps:[]},this.revealCanvas.width=e*this.pxRatio,this.revealCanvas.height=e*this.pxRatio;for(const f of[0,1]){// 0 means border, 1 means fill.
const g=this.revealCanvas.getContext("2d");if(!g)return;g.setTransform(this.pxRatio,0,0,this.pxRatio,0,0);const h=0===f?b:.5*b,i=g.createRadialGradient(d,d,0,d,d,c[f]);i.addColorStop(0,`rgba(${a}, ${h})`),i.addColorStop(1,`rgba(${a}, 0.0)`),g.fillStyle=i,g.clearRect(0,0,e,e),g.fillRect(0,0,e,e);const j=g.getImageData(0,0,e*this.pxRatio,e*this.pxRatio);this.cachedRevealBitmap.bitmaps.push(j)}}},this.mouseInCanvas=()=>{this.cacheCanvasPaintingStyle();const{top:a,left:b,width:c,height:d}=this.cachedStyle,e=this._store.clientX-b,f=this._store.clientY-a;return 0<e&&0<f&&e<c&&f<d},this.getAnimateGrd=(a,b)=>{if(!this.ctx)return;const{color:c,opacity:d}=this.cachedStyle,e=d*(.2-a),f=d*(.1-.07*a),g=.1+.8*a,h=0>e?0:e,i=0>f?0:f,j=1<g?1:g;b.addColorStop(0,`rgba(${c},${h})`),b.addColorStop(.55*j,`rgba(${c},${i})`),b.addColorStop(j,`rgba(${c}, 0)`)},this.paint=a=>{const b=this._store,c=b.animationQueue.has(this),d=b.clientX===b.paintedClientX&&b.clientY===b.paintedClientY;if(d&&!c&&!a)return;if(!this.ctx)return;if(this.ctx.clearRect(0,0,this.paintedWidth,this.paintedHeight),b.dirty=!1,!b.mouseInBoundary&&!c)return;if(2>this.cachedRevealBitmap.bitmaps.length)return;this.cacheCanvasPaintingStyle(),this.cacheRevealBitmaps();const{top:e,left:f,width:g,height:h,trueFillRadius:i,borderStyle:j,borderWidth:k,fillMode:l}=this.cachedStyle;this.canvas.width=g*this.pxRatio,this.canvas.height=h*this.pxRatio,this.canvas.style.width=`${g}px`,this.canvas.style.height=`${h}px`,this.paintedWidth=g,this.paintedHeight=h;const m=this.mouseInCanvas();if(!m&&!this.cachedStyle.diffuse&&!c)return;let n=0,o=0,p=0,q=0;switch(j){case"full":n=k,o=k,p=g-2*k,q=h-2*k;break;case"half":n=0,o=k,p=g,q=h-2*k;break;case"none":n=0,o=0,p=g,q=h;break;default:throw new SyntaxError("The value of `--reveal-border-style` must be `full`, `half` or `none`!");}const r=b.clientX-f,s=b.clientY-e,t=this.cachedRevealBitmap.radius,u=r-t,v=s-t;if(isNaN(r)||isNaN(s))return;if(this.ctx.setTransform(this.pxRatio,0,0,this.pxRatio,0,0),b.mouseInBoundary&&("none"!==j&&(this.ctx.putImageData(this.cachedRevealBitmap.bitmaps[0],u*this.pxRatio,v*this.pxRatio),this.ctx.clearRect(n,o,p,q)),"none"!==l&&m&&this.ctx.putImageData(this.cachedRevealBitmap.bitmaps[1],u*this.pxRatio,v*this.pxRatio,(n-u)*this.pxRatio,(o-v)*this.pxRatio,p*this.pxRatio,q*this.pxRatio)),!this.mousePressed||!this.mouseDownAnimateLogicFrame)return;let w;w=this.mouseReleased&&this.mouseUpClientX&&this.mouseUpClientY?this.ctx.createRadialGradient(this.mouseUpClientX-f,this.mouseUpClientY-e,0,this.mouseUpClientX-f,this.mouseUpClientY-e,i[1]):this.ctx.createRadialGradient(r,s,0,r,s,i[1]),this.getAnimateGrd(this.mouseDownAnimateLogicFrame,w),this.ctx.fillStyle=w,this.ctx.fillRect(n,o,1.5*p,1.5*q)},this._store=a,this.canvas=c,this.ctx=c.getContext("2d"),this.revealCanvas=document.createElement("canvas")}}class g{constructor(a){// The current cursor position relative to window.
// The cursor position of painted reveal effect.
this.clientX=-1e3,this.clientY=-1e3,this.paintedClientX=-1e3,this.paintedClientY=-1e3,this.mouseInBoundary=!1,this.canvasList=[],this.animationQueue=new Set,this.animationFrame=null,this.dirty=!1,this.mouseUpClientX=null,this.mouseUpClientY=null,this.mouseDownAnimateStartFrame=null,this.mouseDownAnimateCurrentFrame=null,this.mouseDownAnimateReleasedFrame=null,this.mouseDownAnimateLogicFrame=null,this.mousePressed=!1,this.mouseReleased=!1,this.addReveal=a=>{const b=new f(this,a);b.cacheCanvasPaintingStyle(),b.cacheRevealBitmaps(),this.canvasList.push(b)},this.removeReveal=a=>{this.canvasList=this.canvasList.filter(b=>b&&b.canvas===a)},this.onPointerEnterBoundary=()=>{this.mouseInBoundary=!0,this.animationFrame||(this.animationFrame=window.requestAnimationFrame(this.paintAll))},this.onPointerLeaveBoundary=()=>{this.mouseInBoundary=!1,this.paintAll(0,!0)},this.paintAll=(a,b)=>{(b||this.mouseInBoundary||0!==this.animationQueue.size)&&(this.animationQueue.forEach(b=>{if(!a||b.currentFrameId===a)return;b.currentFrameId=a,null===b.mouseDownAnimateStartFrame&&(b.mouseDownAnimateStartFrame=a);const c=a-b.mouseDownAnimateStartFrame;b.mouseDownAnimateCurrentFrame=c;const d=b.cachedStyle.revealAnimateSpeed,e=b.cachedStyle.revealReleasedAccelerateRate;let f=c;b.mouseReleased&&b.mouseDownAnimateReleasedFrame&&(f+=(c-b.mouseDownAnimateReleasedFrame)*e),b.mouseDownAnimateLogicFrame=f/d,1<b.mouseDownAnimateLogicFrame&&this.cleanUpAnimation(b)}),this.canvasList.forEach(c=>{c.currentFrameId=a,c.paint(b)}),this.dirty=!0,this.paintedClientX=this.clientX,this.paintedClientY=this.clientY,this.animationFrame=this.mouseInBoundary||0!==this.animationQueue.size?window.requestAnimationFrame(this.paintAll):null)},this.resetAll=()=>{this.canvasList.forEach(a=>{a.paint()})},this.initializeAnimation=()=>{const a=this.canvasList.find(a=>a.mouseInCanvas());a&&(this.animationQueue.add(a),a.mouseDownAnimateStartFrame=null,a.mousePressed=!0,a.mouseReleased=!1)},this.switchAnimation=()=>{this.animationQueue.forEach(a=>{a.mouseReleased||(a.mouseReleased=!0,a.mouseDownAnimateReleasedFrame=a.mouseDownAnimateCurrentFrame,a.mouseUpClientX=this.clientX,a.mouseUpClientY=this.clientY)})},this.cleanUpAnimation=a=>{a.mouseUpClientX=null,a.mouseUpClientY=null,a.mouseDownAnimateStartFrame=null,a.mouseDownAnimateCurrentFrame=null,a.mouseDownAnimateReleasedFrame=null,a.mouseDownAnimateLogicFrame=null,a.mousePressed=!1,a.mouseReleased=!1,this.animationQueue.delete(a),a.paint(!0)},this.getRevealAnimationConfig=()=>this.canvasList.find(a=>a.mouseInCanvas())||null,this.id=a}}class h{constructor(){this._currentHashId=0,this._storage=[],this.newBoundary=()=>{const a=this._currentHashId++,b=new g(a);return this._storage.push(b),b},this.removeBoundary=a=>{this._storage=this._storage.filter(b=>b===a)}}}class i extends HTMLElement{constructor(){super(...arguments),this.stateManager=new h}}i.ElementName="ax-reveal-provider";class j extends HTMLElement{constructor(){super(...arguments),this.updatePointerPosition=a=>{this.waitForStorage(b=>{b.clientX=a.clientX,b.clientY=a.clientY})},this.handlePointerEnter=()=>this.waitForStorage(a=>a.onPointerEnterBoundary()),this.handlePointerLeave=()=>this.waitForStorage(a=>a.onPointerLeaveBoundary()),this.handlePointerMove=a=>this.updatePointerPosition(a),this.handlePointerUp=()=>this.waitForStorage(a=>a.switchAnimation()),this.handlePointerDown=a=>this.waitForStorage(b=>{this.updatePointerPosition(a),b.initializeAnimation()})}get storage(){return this._storage}set storage(a){const b=this._storage;b&&(this.dispatchEvent(new CustomEvent(j.removeStorageEvent,{detail:b})),j.stateManager.removeBoundary(b)),a&&(this._storage=a,this.dispatchEvent(new CustomEvent(j.attachStorageEvent,{detail:a}))),b&&a&&this.dispatchEvent(new CustomEvent(j.replaceStorageEvent,{detail:{old:b,new:a}}))}waitForStorage(a){this.storage===void 0?this.addEventListener(j.attachStorageEvent,()=>a(this.storage),{once:!0}):a(this.storage)}appendStorage(a=!1){if(!a&&this.storage)return;const b=this.closest(i.ElementName),c=b?b.stateManager:j.stateManager;this.storage=c.newBoundary()}connectedCallback(){this.appendStorage(!0),this.addEventListener("pointerenter",this.handlePointerEnter),this.addEventListener("pointerleave",this.handlePointerLeave),this.addEventListener("pointermove",this.handlePointerMove),this.addEventListener("pointerdown",this.handlePointerDown),this.addEventListener("pointerup",this.handlePointerUp)}disconnectedCallback(){this.storage=void 0}}j.ElementName="ax-reveal-bound",j.removeStorageEvent="removeStorage",j.attachStorageEvent="attachStorage",j.replaceStorageEvent="replaceStorage",j.stateManager=new h;class k extends HTMLElement{constructor(){super(),this.root=this.attachShadow({mode:"open"}),this.root.innerHTML=`
<div>
    <slot></slot>
    <canvas></canvas>
    </div>
<style>
    div { display: content; }
    canvas { top: 0; left: 0; pointer-events: none; width: 100%; height: 100%; position: absolute; }
    :host { display: inline-block; position: relative; }
    :host([block]) { display: block; }
    :host([inline-block]) { display: inline-block; }
    :host([flex]) { display: flex; }
    :host([inline-flex]) { display: inline-flex; }
    :host([grid]) { display: grid; }
    :host([inline-grid]) { display: inline-grid; }
    ::slotted(button) { outline:none; }
</style>`,this.canvas=this.root.querySelector("canvas")}adoptedCallback(){this.disconnectedCallback(),this.connectedCallback()}disconnectedCallback(){this.boundary&&this.boundary.waitForStorage(a=>a.removeReveal(this.canvas))}connectedCallback(){if(this.boundary=this.closest(j.ElementName),!this.boundary)throw new SyntaxError("You must use "+j.ElementName+" as the boundary of acrylic!");this.boundary.waitForStorage(a=>setTimeout(()=>a.addReveal(this.canvas),0))}}k.ElementName="ax-reveal",a.register=function(a=!1){if(window.CSS&&CSS.registerProperty)CSS.registerProperty({name:"--reveal-color",syntax:"<color>",initialValue:"rgb(0, 0, 0)",inherits:!0}),CSS.registerProperty({name:"--reveal-opacity",syntax:"<number>",initialValue:"0.26",inherits:!0}),CSS.registerProperty({name:"--reveal-border-style",syntax:"<custom-ident>",initialValue:"full",inherits:!0}),CSS.registerProperty({name:"--reveal-border-width",syntax:"<length>",initialValue:"1px",inherits:!0}),CSS.registerProperty({name:"--reveal-fill-mode",syntax:"<custom-ident>",initialValue:"relative",inherits:!0}),CSS.registerProperty({name:"--reveal-fill-radius",syntax:"<number>",initialValue:"1.5",inherits:!0}),CSS.registerProperty({name:"--reveal-diffuse",syntax:"<custom-ident>",initialValue:"true",inherits:!0}),CSS.registerProperty({name:"--reveal-animate-speed",syntax:"<number>",initialValue:"2000",inherits:!0}),CSS.registerProperty({name:"--reveal-released-accelerate-rate",syntax:"<number>",initialValue:"6",inherits:!0}),c();else if(a){const a=document.documentElement;a.dataset.revealCompat="true",a.style.setProperty("--reveal-color","rgb(0, 0, 0)"),a.style.setProperty("--reveal-opacity","0.26"),a.style.setProperty("--reveal-border-style","full"),a.style.setProperty("--reveal-border-width","1px"),a.style.setProperty("--reveal-fill-mode","relative"),a.style.setProperty("--reveal-fill-radius","1.5"),a.style.setProperty("--reveal-diffuse","true"),a.style.setProperty("--reveal-animate-speed","2000"),a.style.setProperty("--reveal-released-accelerate-rate","6"),c()}else console.warn("Your browser do NOT support `CSS.registerProperty` method, registration failed!"),console.warn("If you are the developer, try using `register(true)` to support old browsers.")},Object.defineProperty(a,"__esModule",{value:!0})});
