5 305 Text / Codepen

Жидкий текст при наведении

При hover на текст его фон становится текучим, как жидкость.

HTML

Текст в виде SVG
<div class="mask">
    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1040 205.1" style="enable-background:new 0 0 1040 205.1;" xml:space="preserve">
        <style type="text/css">
          .st0 {
            fill-rule: evenodd;
            clip-rule: evenodd;
          }
        </style>
        <g>
          <g>
            <path
              class="st0"
              d="M108.7,155.2l24.8,23.3c-2.1,3.1-4.9,6.2-8.3,9.2c-10.2,8.8-26.2,16.4-48.5,16.4C33.4,204.1,1,174.8,1,131.2
                  c0-43.3,32.4-72.6,75.7-72.6c29.8,0,48.4,13.2,56.8,25.5l-28.7,26.7c-5.5-8-14.3-13.2-26.1-13.2c-18.3,0-32.4,12.6-32.4,33.6
                  c0,3.7,0.4,7.2,1.3,10.4c1.5,5.9,4.4,10.8,8.2,14.5c5,4.9,11.6,8,19.1,8.7c1.2,0.1,2.5,0.2,3.8,0.2c10.5,0,18.7-4.6,24.2-11.1
                  c0.7-0.8,1.3-1.6,1.8-2.4L108.7,155.2z"
            />
            <path
              class="st0"
              d="M239.9,59.4v42.5c-2.6-0.6-6.3-1.2-10.9-1.2c-11.5,0-26.7,4.9-32.4,12.6v88.3h-44.2V63.1h44.2V80
                  C205.8,68.8,223.3,59.4,239.9,59.4z"
            />
            <path
              class="st0"
              d="M381.7,181.7c-9.3,9.7-21.1,16.9-34.5,20.4l0.7-0.1L381.7,181.7z"
            />
            <path
              class="st0"
              d="M539.8,92.8c-8.7-26-34.4-34.1-61.4-34.1c-21.2,0-45,6.3-62.8,21.5l7.2,12.6l8.6,15.2
                  c11.2-9.5,25.5-14.6,39.3-14.6c17.8,0,28.1,8,28.1,20.1v16.6c-8.3-10.3-24.7-16.1-43-16.1c-7.1,0-14.8,1.2-21.9,4.1
                  c-14,5.7-25.7,18-25.7,40.3c0,24.8,16.7,39,34.1,43.8c0.7,0.2,1.4,0.4,2.1,0.5c3.8,0.9,7.7,1.3,11.4,1.3c4.3,0,8.5-0.4,12.5-1.2
                  c1.8-0.3,3.5-0.7,5.2-1.2c10.6-2.8,19.6-8.1,25.2-14.9v13.8h44.1V114C542.9,105.9,541.8,98.8,539.8,92.8z M498.8,165.1
                  c-4.6,6.6-14.9,10-24.7,10c-11.8,0-22.1-5.2-22.1-16.1c0-10.9,10.3-16.1,22.1-16.1c9.8,0,20.1,3.4,24.7,9.8V165.1z"
            />
            <path
              class="st0"
              d="M605.3,201.1c-5.9-2.5-10.7-6.2-14.1-11.1C595.1,194.7,599.9,198.5,605.3,201.1z"
            />
            <path
              class="st0"
              d="M656.2,101.5h-28.1v19.6c-1.4-0.1-2.8-0.2-4.2-0.2c-18.2,0-33.7,11.5-39.6,27.5v-46.9h-22.9V63.1h22.9V25.2
                  h43.9v37.9h28.1V101.5z"
            />
            <path
              class="st0"
              d="M660.2,195.9c-2.8,2.6-6.9,4.9-12.4,6.6c-5.1,1.5-11.3,2.5-18.7,2.6c12-1.5,22.4-7.9,29.1-17.2L660.2,195.9z"
            />
            <path
              class="st0"
              d="M725.5,26.2c0,14-11.2,25.5-25.2,25.5s-25.2-11.5-25.2-25.5S686.3,1,700.3,1S725.5,12.2,725.5,26.2z"
            />
            <polygon
              class="st0"
              points="891.5,63.1 879.4,93.8 873.7,108.5 837,201.6 790,201.6 760.2,125.9 747.6,93.8 735.6,63.1 782,63.1
                  792.9,93.8 802.1,119.5 813.2,150.9 825.8,115.8 833.8,93.8 844.8,63.1         "
            />
            <path
              class="st0"
              d="M939.8,116.6c1.4-8,6.3-18.3,18-22.2c3-1,6.5-1.6,10.4-1.6c20.3,0,27.5,14.1,28.7,23.8H939.8z M968.2,204l2,0
                  c21.2,0,44.1-6,57.9-18.4l-18.6-27.5c-7.7,7.5-24.6,11.8-34.4,11.8c-20.1,0-32.1-11.8-34.7-24.7h98.6v-9.5
                  c0-47-29.8-77.2-70.8-77.2c-28.1,0-50.7,13.6-63.2,34.1c-2,3.3-3.8,6.8-5.2,10.5c-3.4,8.6-5.3,18-5.3,27.9
                  c0,44.3,31.8,71.9,73.5,72.8L968.2,204z"
            />
          </g>
        </g>
        <polyline
          class="st0"
          points="678.2,201.4 678.2,63.1 722.3,63.1 722.3,201.4 "
        />
        <path
          class="st0"
          d="M395.3,135.8c0-10-1.3-19.2-3.8-27.5c-1.7-5.6-3.9-10.8-6.6-15.5c-12.1-21.6-33.9-34.1-60.4-34.1
          c-9.1,0-17.7,1.4-25.5,4.1c-25.9,11.5-43.9,37.5-43.9,67.8c0,37.8,28.1,69,64.5,73.5c3,0.4,6,0.5,9,0.5c6.4,0,12.7-0.8,18.6-2.4
          c13.3-3.5,25.2-10.7,34.5-20.4l-15.9-23.5c-7.7,7.5-24.7,11.8-34.4,11.8c-20.1,0-32.1-11.8-34.7-24.7h98.6V135.8z M296.1,116.6
          c1.7-10,9.2-23.8,28.4-23.8c6.4,0,11.5,1.4,15.5,3.6c8.7,4.8,12.4,13.5,13.1,20.2H296.1z"
        />
        <path
          class="st0"
          d="M658.1,187.8c-6.7,9.3-17.1,15.8-29.1,17.2h0c-1.7,0.2-3.4,0.3-5.2,0.3c-6.6,0-12.9-1.5-18.5-4.2
          c-5.5-2.7-10.3-6.5-14.1-11.1c0,0,0,0,0-0.1c-4.6-6.5-7-15.1-7-25.6v-15.9c6-16.1,21.4-27.5,39.6-27.5c1.4,0,2.8,0.1,4.2,0.2V152
          c0,7.1,3.6,12.6,9.8,13.8c0.8,0.1,1.6,0.2,2.5,0.2c4.9,0,9.7-1.7,11.2-3.4l1.9,7.4L658.1,187.8z"
        />
      </svg>
</div>

SCSS

body {
    position: fixed;
    height: 100%;
  overflow: hidden;
}

canvas {
    position: absolute;
    width: 100%;
    height: 100vh;
    top: 0;
    left: 0;
}

.mask {
    position: absolute;
    z-index: 2;
    background: white;
    height: 100vh;
    width: 100vw;
    mix-blend-mode: screen;
    /* display: none; */
}

svg {
    width: 90%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

JS

var vertex = `
        attribute vec2 uv;
        attribute vec2 position;
        varying vec2 vUv;
        void main() {
                vUv = uv;
                gl_Position = vec4(position, 0, 1);
        }
`;
var fragment = `
        precision highp float;
        precision highp int;
        uniform sampler2D tWater;
        uniform sampler2D tFlow;
        uniform float uTime;
        varying vec2 vUv;
        uniform vec4 res;
        uniform vec2 img;

        vec2 centeredAspectRatio(vec2 uvs, vec2 factor){
                return uvs * factor - factor /2. + 0.5;
        }

        void main() {

            // R and G values are velocity in the x and y direction
            // B value is the velocity length
            vec3 flow = texture2D(tFlow, vUv).rgb;

            vec2 uv = .5 * gl_FragCoord.xy / res.xy ;

            // vec2 uv = .5 * gl_FragCoord.xy / res.xy ;
            vec2 myUV = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV -= flow.xy * (0.15 * 1.2);

            vec2 myUV2 = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV2 -= flow.xy * (0.125 * 1.2);

            vec2 myUV3 = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV3 -= flow.xy * (0.10 * 1.4);

            vec3 tex = texture2D(tWater, myUV).rgb;
            vec3 tex2 = texture2D(tWater, myUV2).rgb;
            vec3 tex3 = texture2D(tWater, myUV3).rgb;

            gl_FragColor = vec4(tex.r, tex2.g, tex3.b, 1.0);
        }
`;
{
    var _size = [2048, 1638];
    var renderer = new ogl.Renderer({ dpr: 2 });
    var gl = renderer.gl;
    document.body.appendChild(gl.canvas);

    // Variable inputs to control flowmap
    var aspect = 1;
    var mouse = new ogl.Vec2(-1);
    var velocity = new ogl.Vec2();
    function resize() {
        gl.canvas.width = window.innerWidth * 2.0;
        gl.canvas.height = window.innerHeight * 2.0;
        gl.canvas.style.width = window.innerWidth + "px";
        gl.canvas.style.height = window.innerHeight + "px";

        var a1, a2;
        var imageAspect = _size[1] / _size[0];
        if (window.innerHeight / window.innerWidth < imageAspect) {
            a1 = 1;
            a2 = window.innerHeight / window.innerWidth / imageAspect;
        } else {
            a1 = window.innerWidth / window.innerHeight * imageAspect;
            a2 = 1;
        }
        mesh.program.uniforms.res.value = new ogl.Vec4(
            window.innerWidth,
            window.innerHeight,
            a1,
            a2
        );

        renderer.setSize(window.innerWidth, window.innerHeight);
        aspect = window.innerWidth / window.innerHeight;
    }
    var flowmap = new ogl.Flowmap(gl, {
        falloff: 0.3,
        dissipation: 0.92,
        alpha: 0.5
    });
    // Triangle that includes -1 to 1 range for 'position', and 0 to 1 range for 'uv'.
    var geometry = new ogl.Geometry(gl, {
        position: {
            size: 2,
            dаta: new Float32Array([-1, -1, 3, -1, -1, 3])
        },
        uv: { size: 2, dаta: new Float32Array([0, 0, 2, 0, 0, 2]) }
    });
    var texture = new ogl.Texture(gl, {
        minFilter: gl.LINEAR,
        magFilter: gl.LINEAR
    });
    var img = new Image();
    img.onload = () => (texture.image = img);
    img.crossOrigin = "Anonymous";
    img.src = "https://images.unsplash.com/photo-1485778282426-7d501b522bb4?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ";

    var a1, a2;
    var imageAspect = _size[1] / _size[0];
    if (window.innerHeight / window.innerWidth < imageAspect) {
        a1 = 1;
        a2 = window.innerHeight / window.innerWidth / imageAspect;
    } else {
        a1 = window.innerWidth / window.innerHeight * imageAspect;
        a2 = 1;
    }

    var program = new ogl.Program(gl, {
        vertex,
        fragment,
        uniforms: {
            uTime: { value: 0 },
            tWater: { value: texture },
            res: {
                value: new ogl.Vec4(window.innerWidth, window.innerHeight, a1, a2)
            },
            img: { value: new ogl.Vec2(_size[1], _size[0]) },
            // Note that the uniform is applied without using an object and value property
            // This is because the class alternates this texture between two render targets
            // and updates the value property after each render.
            tFlow: flowmap.uniform
        }
    });
    var mesh = new ogl.Mesh(gl, { geometry, program });

    window.addEventListener("resize", resize, false);
    resize();

    // Create handlers to get mouse position and velocity
    var isTouchCapable = "ontouchstart" in window;
    if (isTouchCapable) {
        window.addEventListener("touchstart", updateMouse, false);
        window.addEventListener("touchmove", updateMouse, { passive: false });
    } else {
        window.addEventListener("mousemove", updateMouse, false);
    }
    var lastTime;
    var lastMouse = new ogl.Vec2();
    function updateMouse(e) {
        e.preventDefault();
    
        if (e.changedTouches && e.changedTouches.length) {
            e.x = e.changedTouches[0].pageX;
            e.y = e.changedTouches[0].pageY;
        }
        if (e.x === undefined) {
            e.x = e.pageX;
            e.y = e.pageY;
        }
        // Get mouse value in 0 to 1 range, with y flipped
        mouse.set(e.x / gl.renderer.width, 1.0 - e.y / gl.renderer.height);
        // Calculate velocity
        if (!lastTime) {
            // First frame
            lastTime = performance.now();
            lastMouse.set(e.x, e.y);
        }

        var deltaX = e.x - lastMouse.x;
        var deltaY = e.y - lastMouse.y;

        lastMouse.set(e.x, e.y);

        var time = performance.now();

        // Avoid dividing by 0
        var delta = Math.max(10.4, time - lastTime);
        lastTime = time;
        velocity.x = deltaX / delta;
        velocity.y = deltaY / delta;
        // Flag update to prevent hanging velocity values when not moving
        velocity.needsUpdate = true;
    }
    requestAnimationFrame(update);
    function update(t) {
        requestAnimationFrame(update);
        // Reset velocity when mouse not moving
        if (!velocity.needsUpdate) {
            mouse.set(-1);
            velocity.set(0);
        }
        velocity.needsUpdate = false;
        // Update flowmap inputs
        flowmap.aspect = aspect;
        flowmap.mouse.copy(mouse);
        // Ease velocity input, slower when fading out
        flowmap.velocity.lerp(velocity, velocity.len ? 0.15 : 0.1);
        flowmap.update();
        program.uniforms.uTime.value = t * 0.01;
        renderer.render({ scene: mesh });
    }
}

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи