1import{z as Y,r as _,l as A,x as O,S as B,O as U,W as k,X as E,Y as R,Z as I,$ as T,a0 as G,a1 as L,L as M,I as W,a2 as j,P as N,K as q,a as H,o as V,_ as K}from"#entry";const Z=["data-grid","data-mouse","data-strength","data-relaxation"],$=` 2varying vec2 vUv; 3void main() { 4 vUv = uv; 5 gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 6} 7`,J=` 8uniform float time; 9uniform sampler2D uDataTexture; 10uniform sampler2D uTexture; 11varying vec2 vUv; 12 13void main() { 14 vec4 offset = texture2D(uDataTexture, vUv); 15 vec4 color = texture2D(uTexture, vUv - 0.02 * offset.rg); 16 gl_FragColor = color; 17} 18`,Q=Y({__name:"ShowreelCanvas",props:{videoSrc:{type:String,default:"/videos/showreel.mp4"},grid:{type:Number,default:75},mouse:{type:Number,default:.15},strength:{type:Number,default:.1},relaxation:{type:Number,default:.9}},emits:["click"],setup(h,{emit:y}){const p=h,S=y,b=o=>S("click",o),d=_(null);let u=null;A(()=>{d.value&&(u=new z({dom:d.value,videoSrc:p.videoSrc,settings:{...p}}))}),O(()=>{u?.destroy(),u=null});const l=(o,t,e)=>Math.max(t,Math.min(o,e));class z{constructor(t){this.scene=new B,this.plane=null,this.material=null,this.video=null,this.videoTexture=null,this.dataTexture=null,this.frameId=null,this.resizeObserver=null,this.bounds=null,this.width=0,this.height=0,this.videoAspect=16/9,this.size=0,this.time=0,this.isPlaying=!0,this.mouse={x:0,y:0,prevX:0,prevY:0,vX:0,vY:0},this.frameCount=0,this.renderFrame=()=>{this.isPlaying&&(this.frameId=requestAnimationFrame(this.renderFrame),this.time+=.05,this.updateDataTexture(),this.videoTexture&&(this.videoTexture.needsUpdate=!0),this.material&&(this.material.uniforms.time.value=this.time),this.renderer.render(this.scene,this.camera))},this.onMouseMove=e=>{if(!this.bounds)return;const i=(e.clientX-this.bounds.left)/this.bounds.width,a=(e.clientY-this.bounds.top)/this.bounds.height;this.mouse.x=l(i,0,1),this.mouse.y=l(a,0,1),this.mouse.vX=this.mouse.x-this.mouse.prevX,this.mouse.vY=this.mouse.y-this.mouse.prevY,this.mouse.prevX=this.mouse.x,this.mouse.prevY=this.mouse.y},this.container=t.dom,this.videoSrc=t.videoSrc,this.settings=t.settings,this.updateBounds(),this.width=this.container.clientWidth,this.height=this.container.clientHeight,this.camera=new U(-this.width/2,this.width/2,this.height/2,-this.height/2,-1e3,1e3),this.camera.position.set(0,0,2),this.renderer=new k({antialias:!0,alpha:!0}),this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.renderer.setSize(this.width,this.height,!1),this.renderer.setClearColor(0,0),this.container.appendChild(this.renderer.domElement),window.addEventListener("mousemove",this.onMouseMove,{passive:!0}),"ResizeObserver"in window&&(this.resizeObserver=new ResizeObserver(()=>{this.resize(),this.updateBounds()}),this.resizeObserver.observe(this.container)),this.setupVideo().then(()=>{this.addObjects(),this.resize(),this.renderFrame()})}destroy(){this.isPlaying=!1,this.frameId&&cancelAnimationFrame(this.frameId),window.removeEventListener("mousemove",this.onMouseMove),this.resizeObserver?.disconnect(),this.plane&&this.scene.remove(this.plane),this.material?.dispose(),this.videoTexture?.dispose(),this.dataTexture?.dispose(),this.renderer.dispose(),this.video&&(this.video.pause(),this.video.removeAttribute("src"),this.video.load()),this.video=null,this.container.contains(this.renderer.domElement)&&this.container.removeChild(this.renderer.domElement)}setupVideo(){return new Promise(t=>{const e=document.createElement("video");e.src=this.videoSrc,e.loop=!0,e.muted=!0,e.playsInline=!0,e.autoplay=!0,e.crossOrigin="anonymous",e.style.display="none",e.addEventListener("loadeddata",()=>{e.videoWidth&&e.videoHeight&&(this.videoAspect=e.videoWidth/e.videoHeight),t()},{once:!0}),e.play().catch(()=>{}),this.video=e})}regenerateGrid(){this.size=Math.max(2,Math.floor(this.settings.grid));const t=this.size*this.size*4,e=new Float32Array(t);for(let i=0;i<t;i+=4)e[i]=Math.random()*255-125,e[i+1]=Math.random()*255-125,e[i+2]=0,e[i+3]=1;this.dataTexture=new E(e,this.size,this.size,R,I),this.dataTexture.magFilter=T,this.dataTexture.minFilter=T,this.dataTexture.needsUpdate=!0,this.material&&(this.material.uniforms.uDataTexture.value=this.dataTexture)}addObjects(){if(!this.video)return;this.regenerateGrid(),this.videoTexture=new G(this.video),this.videoTexture.colorSpace
18=L,this.videoTexture.minFilter=M,this.videoTexture.magFilter=M,this.videoTexture.generateMipmaps=!1,this.material=new W({uniforms:{time:{value:0},uTexture:{value:this.videoTexture},uDataTexture:{value:this.dataTexture}},vertexShader:$,fragmentShader:J,transparent:!0,side:j});const t=new N(1,1);this.plane=new q(t,this.material),this.scene.add(this.plane),this.updatePlaneScale()}resize(){this.width=this.container.clientWidth,this.height=this.container.clientHeight,this.renderer.setSize(this.width,this.height,!1),this.camera.left=-this.width/2,this.camera.right=this.width/2,this.camera.top=this.height/2,this.camera.bottom=-this.height/2,this.camera.updateProjectionMatrix(),this.updatePlaneScale()}updatePlaneScale(){if(!this.plane)return;const t=this.width/this.height;let e,i;t>this.videoAspect?(e=this.width,i=e/this.videoAspect):(i=this.height,e=i*this.videoAspect),this.plane.scale.set(e,i,1)}updateBounds(){this.bounds=this.container.getBoundingClientRect()}updateDataTexture(){if(!this.dataTexture||(this.frameCount++,this.frameCount%2!==0))return;const{relaxation:t,mouse:e,strength:i}=this.settings,a=this.dataTexture.image.data;for(let s=0;s<a.length;s+=4)a[s]*=t,a[s+1]*=t;const m=this.size*this.mouse.x,c=this.size*(1-this.mouse.y),r=this.size*e,F=r*r,C=Math.max(0,Math.floor(m-r)),D=Math.min(this.size,Math.ceil(m+r)),P=Math.max(0,Math.floor(c-r)),X=Math.min(this.size,Math.ceil(c+r));for(let s=P;s<X;s++)for(let n=C;n<D;n++){const f=m-n,x=c-s,v=f*f+x*x;if(v<F&&v>1e-4){const g=4*(n+this.size*s),w=l(r/Math.sqrt(v),0,10);a[g]+=i*100*this.mouse.vX*w,a[g+1]-=i*100*this.mouse.vY*w}}this.mouse.vX*=.9,this.mouse.vY*=.9,this.dataTexture.needsUpdate=!0}}return(o,t)=>(V(),H("div",{ref_key:"container",ref:d,class:"showreel-canvas","data-grid":h.grid,"data-mouse":h.mouse,"data-strength":h.strength,"data-relaxation":h.relaxation,onClick:b},null,8,Z))}}),te=K(Q,[["__scopeId","data-v-fb74fed1"]]);export{te as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.