Within Oasen we experimented with a water ripple effect on mouse over as a small tweak within our website, our developer Marnix tried all the different movements and timings. You can check the end result on http://oasen.nl
-
-
Save AnoRebel/1a33c80cdce1fb71937f93f53d0d790d to your computer and use it in GitHub Desktop.
Mouse hover water effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas id="canvas"></canvas> | |
<div id="wrapper"> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const rippleSettings = { | |
maxSize: 100, | |
animationSpeed: 5, | |
strokeColor: [148, 217, 255], | |
}; | |
const canvasSettings = { | |
blur: 8, | |
ratio: 1, | |
}; | |
function Coords(x, y) { | |
this.x = x || null; | |
this.y = y || null; | |
} | |
const Ripple = function Ripple(x, y, circleSize, ctx) { | |
this.position = new Coords(x, y); | |
this.circleSize = circleSize; | |
this.maxSize = rippleSettings.maxSize; | |
this.opacity = 1; | |
this.ctx = ctx; | |
this.strokeColor = `rgba(${Math.floor(rippleSettings.strokeColor[0])}, | |
${Math.floor(rippleSettings.strokeColor[1])}, | |
${Math.floor(rippleSettings.strokeColor[2])}, | |
${this.opacity})`; | |
this.animationSpeed = rippleSettings.animationSpeed; | |
this.opacityStep = (this.animationSpeed / (this.maxSize - circleSize)) / 2; | |
}; | |
Ripple.prototype = { | |
update: function update() { | |
this.circleSize = this.circleSize + this.animationSpeed; | |
this.opacity = this.opacity - this.opacityStep; | |
this.strokeColor = `rgba(${Math.floor(rippleSettings.strokeColor[0])}, | |
${Math.floor(rippleSettings.strokeColor[1])}, | |
${Math.floor(rippleSettings.strokeColor[2])}, | |
${this.opacity})`; | |
}, | |
draw: function draw() { | |
this.ctx.beginPath(); | |
this.ctx.strokeStyle = this.strokeColor; | |
this.ctx.arc(this.position.x, this.position.y, this.circleSize, 0, | |
2 * Math.PI); | |
this.ctx.stroke(); | |
}, | |
setStatus: function setStatus(status) { | |
this.status = status; | |
}, | |
}; | |
const canvas = document.querySelector('#canvas'); | |
const ctx = canvas.getContext('2d'); | |
const ripples = []; | |
const height = document.body.clientHeight; | |
const width = document.body.clientWidth; | |
const rippleStartStatus = 'start'; | |
const isIE11 = !!window.MSInputMethodContext && !!document.documentMode; | |
canvas.style.filter = `blur(${canvasSettings.blur}px)`; | |
canvas.width = width * canvasSettings.ratio; | |
canvas.height = height * canvasSettings.ratio; | |
canvas.style.width = `${width}px`; | |
canvas.style.height = `${height}px`; | |
let animationFrame; | |
// Add GUI settings | |
const addGuiSettings = () => { | |
const gui = new dat.GUI(); | |
gui.add(rippleSettings, 'maxSize', 0, 1000).step(1); | |
gui.add(rippleSettings, 'animationSpeed', 1, 30).step(1); | |
gui.addColor(rippleSettings, 'strokeColor'); | |
const blur = gui.add(canvasSettings, 'blur', 0, 20).step(1); | |
blur.onChange((value) => { | |
canvas.style.filter = `blur(${value}px)`; | |
}); | |
}; | |
addGuiSettings(); | |
// Function which is executed on mouse hover on canvas | |
const canvasMouseOver = (e) => { | |
const x = e.clientX * canvasSettings.ratio; | |
const y = e.clientY * canvasSettings.ratio; | |
ripples.unshift(new Ripple(x, y, 2, ctx)); | |
}; | |
const animation = () => { | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
const length = ripples.length; | |
for (let i = length - 1; i >= 0; i -= 1) { | |
const r = ripples[i]; | |
r.update(); | |
r.draw(); | |
if (r.opacity <= 0) { | |
ripples[i] = null; | |
delete ripples[i]; | |
ripples.pop(); | |
} | |
} | |
animationFrame = window.requestAnimationFrame(animation); | |
}; | |
animation(); | |
canvas.addEventListener('mousemove', canvasMouseOver); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body, #canvas { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
} | |
body { | |
background-color: #26b4f4; | |
} | |
#wrapper { | |
position: absolute; | |
top: 0; | |
width: 100%; | |
height: 100%; | |
pointer-events: none; | |
} | |
#menu { | |
width: 100%; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment