Skip to content

Instantly share code, notes, and snippets.

@AnoRebel
Forked from Usman2k19/index.html
Created January 31, 2025 10:16
Show Gist options
  • Save AnoRebel/1a33c80cdce1fb71937f93f53d0d790d to your computer and use it in GitHub Desktop.
Save AnoRebel/1a33c80cdce1fb71937f93f53d0d790d to your computer and use it in GitHub Desktop.

Revisions

  1. @Usman2k19 Usman2k19 created this gist Jan 8, 2023.
    3 changes: 3 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    <canvas id="canvas"></canvas>
    <div id="wrapper">
    </div>
    7 changes: 7 additions & 0 deletions mouse-hover-water-effect.markdown
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    Mouse hover water effect
    ------------------------
    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

    A [Pen](https://codepen.io/Usman2k19/pen/yLqgzvM) by [Usman2k19](https://codepen.io/Usman2k19) on [CodePen](https://codepen.io).

    [License](https://codepen.io/license/pen/yLqgzvM).
    116 changes: 116 additions & 0 deletions script.babel
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,116 @@
    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);
    1 change: 1 addition & 0 deletions scripts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    18 changes: 18 additions & 0 deletions style.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    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%;
    }