Skip to content

Instantly share code, notes, and snippets.

@rudrathegreat
Created January 12, 2021 05:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rudrathegreat/2fabab7b968a348681f55581c9109813 to your computer and use it in GitHub Desktop.
Save rudrathegreat/2fabab7b968a348681f55581c9109813 to your computer and use it in GitHub Desktop.
Mouse Interactions with JS
let mouseCursor = document.querySelector(".cursor");
var navList = document.querySelector(".nav-list");
var navListElements = navList.querySelectorAll(".nav-list li");
var heroText = document.querySelector(".hero h1");
var heroImg = document.querySelector(".hero .img");
window.addEventListener("mousemove", cursor);
function cursor(e) {
mouseCursor.style.top = e.pageY + 'px';
mouseCursor.style.left = e.pageX + 'px';
}
navListElements.forEach(link => {
link.addEventListener('mouseover', () => {
mouseCursor.classList.add('grow');
link.classList.add('hovered');
});
link.addEventListener('mouseleave', () => {
mouseCursor.classList.remove('grow');
link.classList.remove('hovered');
});
heroText.addEventListener('mouseover', () => {
mouseCursor.classList.add('showHeroTitleImg');
});
heroText.addEventListener('mouseleave', () => {
mouseCursor.classList.remove('showHeroTitleImg');
});
heroImg.addEventListener('mouseover', () => {
mouseCursor.classList.add('overlap');
});
heroImg.addEventListener('mouseleave', () => {
mouseCursor.classList.remove('overlap');
});
});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("three"),require("gsap/TweenMax")):"function"==typeof define&&define.amd?define(["three","gsap/TweenMax"],t):e.hoverEffect=t(e.THREE,e.TweenMax)}(this,function(e,t){return t=t&&t.hasOwnProperty("default")?t.default:t,function(n){function i(){for(var e=arguments,t=0;t<arguments.length;t++)if(void 0!==e[t])return e[t]}console.log("%c Hover effect by Robin Delaporte: https://github.com/robin-dela/hover-effect ","color: #bada55; font-size: 0.8rem");var r=n.parent,o=n.displacementImage,a=n.image1,s=n.image2,f=i(n.imagesRatio,1),d=i(n.intensity1,n.intensity,1),l=i(n.intensity2,n.intensity,1),u=i(n.angle,Math.PI/4),v=i(n.angle1,u),m=i(n.angle2,3*-u),c=i(n.speedIn,n.speed,1.6),p=i(n.speedOut,n.speed,1.2),g=i(n.hover,!0),h=i(n.easing,Expo.easeOut),y=i(n.video,!1);if(r)if(a&&s&&o){var x=new e.Scene,F=new e.OrthographicCamera(r.offsetWidth/-2,r.offsetWidth/2,r.offsetHeight/2,r.offsetHeight/-2,1,1e3);F.position.z=1;var w=new e.WebGLRenderer({antialias:!1,alpha:!0});w.setPixelRatio(2),w.setClearColor(16777215,0),w.setSize(r.offsetWidth,r.offsetHeight),r.appendChild(w.domElement);var L=function(){w.render(x,F)},H=new e.TextureLoader;H.crossOrigin="";var E,W,V=H.load(o,L);if(V.magFilter=V.minFilter=e.LinearFilter,y){var M=function(){requestAnimationFrame(M),w.render(x,F)};M(),(y=document.createElement("video")).autoplay=!0,y.loop=!0,y.src=a,y.load();var P=document.createElement("video");P.autoplay=!0,P.loop=!0,P.src=s,P.load();var R=new e.VideoTexture(y),T=new e.VideoTexture(P);R.magFilter=T.magFilter=e.LinearFilter,R.minFilter=T.minFilter=e.LinearFilter,P.addEventListener("loadeddata",function(){P.play(),(T=new e.VideoTexture(P)).magFilter=e.LinearFilter,T.minFilter=e.LinearFilter,C.uniforms.texture2.value=T},!1),y.addEventListener("loadeddata",function(){y.play(),(R=new e.VideoTexture(y)).magFilter=e.LinearFilter,R.minFilter=e.LinearFilter,C.uniforms.texture1.value=R},!1)}else R=H.load(a,L),T=H.load(s,L),R.magFilter=T.magFilter=e.LinearFilter,R.minFilter=T.minFilter=e.LinearFilter;var U=f;r.offsetHeight/r.offsetWidth<U?(E=1,W=r.offsetHeight/r.offsetWidth/U):(E=r.offsetWidth/r.offsetHeight*U,W=1);var C=new e.ShaderMaterial({uniforms:{intensity1:{type:"f",value:d},intensity2:{type:"f",value:l},dispFactor:{type:"f",value:0},angle1:{type:"f",value:v},angle2:{type:"f",value:m},texture1:{type:"t",value:R},texture2:{type:"t",value:T},disp:{type:"t",value:V},res:{type:"vec4",value:new e.Vector4(r.offsetWidth,r.offsetHeight,E,W)},dpr:{type:"f",value:window.devicePixelRatio}},vertexShader:"\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n",fragmentShader:"\nvarying vec2 vUv;\n\nuniform float dispFactor;\nuniform float dpr;\nuniform sampler2D disp;\n\nuniform sampler2D texture1;\nuniform sampler2D texture2;\nuniform float angle1;\nuniform float angle2;\nuniform float intensity1;\nuniform float intensity2;\nuniform vec4 res;\nuniform vec2 parent;\n\nmat2 getRotM(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec4 disp = texture2D(disp, vUv);\n vec2 dispVec = vec2(disp.r, disp.g);\n\n vec2 uv = 0.5 * gl_FragCoord.xy / (res.xy) ;\n vec2 myUV = (uv - vec2(0.5))*res.zw + vec2(0.5);\n\n\n vec2 distortedPosition1 = myUV + getRotM(angle1) * dispVec * intensity1 * dispFactor;\n vec2 distortedPosition2 = myUV + getRotM(angle2) * dispVec * intensity2 * (1.0 - dispFactor);\n vec4 _texture1 = texture2D(texture1, distortedPosition1);\n vec4 _texture2 = texture2D(texture2, distortedPosition2);\n gl_FragColor = mix(_texture1, _texture2, dispFactor);\n}\n",transparent:!0,opacity:1}),b=new e.PlaneBufferGeometry(r.offsetWidth,r.offsetHeight,1),D=new e.Mesh(b,C);x.add(D),g&&(r.addEventListener("mouseenter",_),r.addEventListener("touchstart",_),r.addEventListener("mouseleave",z),r.addEventListener("touchend",z)),window.addEventListener("resize",function(t){r.offsetHeight/r.offsetWidth<U?(E=1,W=r.offsetHeight/r.offsetWidth/U):(E=r.offsetWidth/r.offsetHeight*U,W=1),D.material.uniforms.res.value=new e.Vector4(r.offsetWidth,r.offsetHeight,E,W),w.setSize(r.offsetWidth,r.offsetHeight),L()}),this.next=_,this.previous=z}else console.warn("One or more images are missing");else console.warn("Parent missing");function _(){t.to(C.uniforms.dispFactor,c,{value:1,ease:h,onUpdate:L,onComplete:L})}function z(){t.to(C.uniforms.dispFactor,p,{value:0,ease:h,onUpdate:L,onComplete:L})}}});
// got file from https://github.com/robin-dela/hover-effect/blob/master/dist/hover-effect.umd.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script>
</head>
<body>
<script>
</script>
<header>
<div class="cursor">
<img src="https://cdn.pixabay.com/photo/2020/02/20/01/28/planets-4863647_960_720.jpg" alt="" class="cursor-img">
</div>
<nav>
<ul class="nav-list">
<li><a href="index.html">Home</a></li>
<li><a href="">About</a></li>
<li><a href="">Contacts</a></li>
</ul>
</nav>
</header>
<div class="hero">
<div class="grid">
<div class="grid-cell">
<h1 class="title">Lorem Ipsum</h1>
</div>
<div class="grid-cell img"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="hover.umd.js"></script>
<script src="app.js"></script>
<script>
var hoverDistort = new hoverEffect({
parent: document.querySelector('.img'),
intensity: 0.5,
image1: 'planet.jpg',
image2: 'moon.jpg',
displacementImage: '4.png'
});
$(document).ready(function() {
$('.img').hover(
function () {
anime.timeline({loop: false}).add({
targets: '.hero-title .letter',
translateX: [80,0],
translateZ: 0,
opacity: [0,1],
easing: "easeOutExpo",
duration: 1400,
delay: (el, i) => 100 + 40 * i
});
});
});
</script>
</body>
</html>
* {
margin:0;
padding:0;
}
html {
scroll-behavior:smooth;
font-family:sans-serif;
font-size:1.5em;
font-weight:700;
text-transform:uppercase;
background:#f3f4f5;
cursor:none;
overflow-x:hidden;
}
header {
width:100%;
height:10vh;
background:none;
}
nav {
width:100%;
height:100%;
}
.nav-list {
display:flex;
gap:5vw;
list-style:none;
height:100%;
margin-left:10%;
align-items:center;
}
.hovered a {
color:#f3f4f5 !important;
transition: color 0.2s ease-in-out;
}
a {
text-decoration:none;
color:black;
transition: color 0.2s ease-in-out;
cursor:none;
}
.cursor {
width:1rem;
height:1rem;
border-radius:50%;
position:absolute;
border:2px solid #333;
transform:translate(-50%, -50%);
pointer-events:none;
transition:all 0.3s ease;
transition-property:background, transform;
transform-origin:75% 75%;
z-index:-1;
}
.grow {
background:#333;
transform:scale(3);
transition:transform 0.2s ease-in-out, background 0.2 ease-out;
}
.hero {
width:100%;
height:90vh;
display:flex;
align-items:center;
justify-content:center;
}
.hero .grid {
display:grid;
width:80%;
grid-template-columns:repeat(2, 1fr);
grid-column-gap:3em;
}
.hero .grid-cell {
display:flex;
align-items:center;
}
.hero .title {
font-size:5em;
font-weight:900;
position:relative;
-webkit-text-stroke: 3px #222;
-webkit-text-fill-color: transparent;
-webkit-transition: 0.2s ease-in-out;
}
.overlap {
z-index:2;
transform:scale(3);
border:2px solid white;
transition:border 0.2s ease-out, transform 0.2s ease-in-out;
}
.hero img:hover {
transform:scale(1.05);
transition:transform 0.2s ease-in-out;
}
.hero img {
transition:transform 0.2s ease-in-out;
overflow-y:hidden;
}
.cursor-img {
opacity:0;
width:200px;
position:absolute;
top:50%;
left:50%;
transition:opacity 0.2s ease-in, transform 0.3s ease-in-out;
transform:translate(-50%, -50%);
transform-origin:75% 75%;
}
.showHeroTitleImg .cursor-img {
opacity:1;
transform:scale(3);
transition:opacity 0.2s ease-in, transform 0.3s ease;
transform-origin:75% 75%;
}
.hero .title:hover {
-webkit-text-stroke:3px #f3f4f5;
-webkit-transition: 0.2s ease-in-out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment