vue-hover-effect
Version:
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
43 lines (35 loc) • 6.04 kB
JavaScript
(function(c,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("vue"),require("three"),require("gsap")):typeof define=="function"&&define.amd?define(["exports","vue","three","gsap"],a):(c=typeof globalThis<"u"?globalThis:c||self,a(c.VueHoverEffect={},c.Vue,c.THREE,c.gsap))})(this,function(c,a,D,R){"use strict";function U(t){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const e in t)if(e!=="default"){const s=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(n,e,s.get?s:{enumerable:!0,get:()=>t[e]})}}return n.default=t,Object.freeze(n)}const i=U(D);function z(t){console.log("%c Hover effect (Single) by Robin Delaporte – https://github.com/robin-dela/hover-effect","color: #bada55; font-size: 0.8rem");function n(...r){return r.find(o=>o!==void 0)}const e=t.parent,s=t.displacementImage,x=t.image1,y=t.image2;if(!e){console.warn("SingleHoverEffect: no parent element provided.");return}if(!s||!x||!y){console.warn("SingleHoverEffect: displacementImage/image1/image2 missing.");return}const f=n(t.imagesRatio,1),F=n(t.intensity1,t.intensity,1),w=n(t.intensity2,t.intensity,1),p=n(t.angle,Math.PI/4),C=n(t.angle1,p),q=n(t.angle2,-p*3),k=n(t.speedIn,t.speed,1.6),A=n(t.speedOut,t.speed,1.2),G=n(t.hover,!0),T=n(t.easing,"expo.out"),N=n(t.video,!1),H=new i.Scene,S=new i.OrthographicCamera(e.offsetWidth/-2,e.offsetWidth/2,e.offsetHeight/2,e.offsetHeight/-2,1,1e3);S.position.z=1;const v=new i.WebGLRenderer({alpha:!0,antialias:!1});v.setPixelRatio(window.devicePixelRatio),v.setClearColor(16777215,0),v.setSize(e.offsetWidth,e.offsetHeight),e.appendChild(v.domElement);function m(){v.render(H,S)}const B=`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,_=`
varying vec2 vUv;
uniform float dispFactor;
uniform sampler2D disp;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform float angle1;
uniform float angle2;
uniform float intensity1;
uniform float intensity2;
uniform vec4 res;
mat2 getRotM(float angle){
float s = sin(angle);
float c = cos(angle);
return mat2(c, -s, s, c);
}
void main(){
// displacement
vec4 dispTex = texture2D(disp, vUv);
vec2 dispVec = dispTex.rg;
// Simple approach
vec2 uv = vUv;
vec2 distortedPos1 = uv + getRotM(angle1) * dispVec * intensity1 * dispFactor;
vec2 distortedPos2 = uv + getRotM(angle2) * dispVec * intensity2 * (1.0 - dispFactor);
vec4 _texture1 = texture2D(texture1, distortedPos1);
vec4 _texture2 = texture2D(texture2, distortedPos2);
gl_FragColor = mix(_texture1, _texture2, dispFactor);
}
`,E=new i.TextureLoader;E.crossOrigin="";const L=E.load(s,m);L.magFilter=L.minFilter=i.LinearFilter;let l,d;if(N){const r=document.createElement("video");r.autoplay=!0,r.loop=!0,r.muted=!0,r.src=x,r.load();const o=document.createElement("video");o.autoplay=!0,o.loop=!0,o.muted=!0,o.src=y,o.load(),l=new i.VideoTexture(r),d=new i.VideoTexture(o),l.magFilter=l.minFilter=i.LinearFilter,d.magFilter=d.minFilter=i.LinearFilter,r.addEventListener("loadeddata",()=>{r.play(),l=new i.VideoTexture(r),l.magFilter=l.minFilter=i.LinearFilter,h.uniforms.texture1.value=l}),o.addEventListener("loadeddata",()=>{o.play(),d=new i.VideoTexture(o),d.magFilter=d.minFilter=i.LinearFilter,h.uniforms.texture2.value=d}),requestAnimationFrame(function u(){requestAnimationFrame(u),v.render(H,S)})}else l=E.load(x,m),d=E.load(y,m),l.magFilter=l.minFilter=i.LinearFilter,d.magFilter=d.minFilter=i.LinearFilter;let O=1,b=1;function V(r,o){const u=r||e.offsetWidth,g=o||e.offsetHeight;g/u<f?(O=1,b=g/u/f):(O=u/g*f,b=1)}V();const h=new i.ShaderMaterial({uniforms:{dispFactor:{value:0},disp:{value:L},texture1:{value:l},texture2:{value:d},angle1:{value:C},angle2:{value:q},intensity1:{value:F},intensity2:{value:w},res:{value:new i.Vector4(e.offsetWidth,e.offsetHeight,O,b)}},vertexShader:B,fragmentShader:_,transparent:!0,opacity:1}),$=new i.PlaneGeometry(e.offsetWidth,e.offsetHeight,1),M=new i.Mesh($,h);H.add(M);function I(){R.to(h.uniforms.dispFactor,{duration:k,value:1,ease:T,onUpdate:m,onComplete:m})}function P(){R.to(h.uniforms.dispFactor,{duration:A,value:0,ease:T,onUpdate:m,onComplete:m})}G&&(e.addEventListener("mouseenter",I),e.addEventListener("mouseleave",P),e.addEventListener("touchstart",I),e.addEventListener("touchend",P));function W(r,o){const u=r||e.offsetWidth,g=o||e.offsetHeight;v.setSize(u,g),V(u,g),h.uniforms.res.value.set(u,g,O,b),M.geometry=new i.PlaneGeometry(u,g,1),m()}return window.addEventListener("resize",()=>W()),{next:I,previous:P,resize:W}}const j=a.defineComponent({__name:"SingleHoverEffect",props:{hoverOptions:{default:()=>({image1:"/lib-images/images/Img22.webp",image2:"/lib-images/images/Img21.webp",displacementImage:"/lib-images/displacements/3.webp",hover:!0,speedIn:.8,speedOut:.8})},distortionClass:{default:""}},setup(t){const n=a.ref(null);let e,s;a.onMounted(()=>{n.value&&(e=z({...t.hoverOptions,parent:n.value,image1:t.hoverOptions.image1,image2:t.hoverOptions.image2,displacementImage:t.hoverOptions.displacementImage,hover:t.hoverOptions.hover,speedIn:t.hoverOptions.speedIn,speedOut:t.hoverOptions.speedOut}),window.ResizeObserver&&(s=new ResizeObserver(f=>{var F,w;for(const p of f)p.target===n.value&&(e==null||e.resize((F=p.target)==null?void 0:F.clientWidth,(w=p.target)==null?void 0:w.clientHeight))}),s.observe(n.value)))});function x(){e==null||e.next()}function y(){e==null||e.previous()}return a.onUnmounted(()=>{e=void 0,s&&n.value&&(s.unobserve(n.value),s.disconnect())}),(f,F)=>(a.openBlock(),a.createElementBlock(a.Fragment,null,[a.createElementVNode("div",{ref_key:"container",ref:n,class:a.normalizeClass(["distortion-container",f.distortionClass])},null,2),a.renderSlot(f.$slots,"controllers",{funcs:{goNext:x,goPrev:y}})],64))}});c.SingleHoverEffect=j,c.createSingleHoverEffect=z,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});