Используются сookie
Для улучшения взаимодействия и аналитики
Оке!

Глитч-эффект фона по курсору

Модификатор
Главная / Контент-хаб / Глитч-эффект
Шаг 1
В zero-блоке добавляем HTML секцию, размещаем ее по центру (самым нижним слоем) и выставляем размеры 100% на 100% по window контейнеру
Шаг 2
Добавляем в HTML секцию код:
<!-- Глитч-трансформация фона -->
<!-- Источник: https://inkedx.ru/guides/glitch -->
<div id="glitch-background-effect">
  <div id="glitch-canvas-wrapper">
  </div>
</div>
Шаг 3
Создаем блок Т123 и вставляем в него код:
<!-- Глитч-анимация фона по курсору -->
<!-- Источник: https://inkedx.ru/guides/glitch -->

<style>
#glitch-background-effect {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}
#glitch-canvas-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
canvas {
  width: 100% !important;
  height: 100% !important;
}
</style>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ogl@0.0.64/dist/ogl.umd.js"></script>

<script type="module">
const imageResolution = [1650, 1200];

const vertShader = `
attribute vec2 position;
attribute vec2 uv;
varying vec2 vUv;
void main() {
  vUv = uv;
  gl_Position = vec4(position, 0, 1);
}
`;

const fragShader = `
precision highp float;
uniform sampler2D tWater;
uniform sampler2D tFlow;
uniform float uTime;
uniform vec4 resolution;
varying vec2 vUv;

void main() {
  vec3 flow = texture2D(tFlow, vUv).rgb;
  vec2 uvCoord = .5 * gl_FragCoord.xy / resolution.xy;
  vec2 baseUV = (uvCoord - 0.5) * resolution.zw + 0.5;
  
  vec3 colorR = texture2D(tWater, baseUV - flow.xy * 0.105).rgb;
  vec3 colorG = texture2D(tWater, baseUV - flow.xy * 0.0875).rgb;
  vec3 colorB = texture2D(tWater, baseUV - flow.xy * 0.07).rgb;
  
  gl_FragColor = vec4(colorR.r, colorG.g, colorB.b, 1.0);
}
`;

{
  const renderer = new ogl.Renderer({ dpr: 2 });
  const gl = renderer.gl;
  $(gl.canvas).appendTo('#glitch-canvas-wrapper');

  const mousePos = new ogl.Vec2(-1);
  const velocity = new ogl.Vec2();
  let aspectRatio = 1;

  function handleResize() {
    let scaleX, scaleY;
    const imageAspect = imageResolution[1] / imageResolution[0];
    if (window.innerHeight / window.innerWidth < imageAspect) {
      scaleX = 1;
      scaleY = window.innerHeight / window.innerWidth / imageAspect;
    } else {
      scaleX = (window.innerWidth / window.innerHeight) * imageAspect;
      scaleY = 1;
    }
    shaderProgram.uniforms.resolution.value = new ogl.Vec4(
      window.innerWidth,
      window.innerHeight,
      scaleX,
      scaleY
    );
    renderer.setSize(window.innerWidth, window.innerHeight);
    aspectRatio = window.innerWidth / window.innerHeight;
  }

  const flowmap = new ogl.Flowmap(gl, {
    falloff: 1.0,
    alpha: 0.25,
    dissipation: 0.95
  });

  const geometry = new ogl.Geometry(gl, {
    position: { size: 2, data: new Float32Array([-1, -1, 3, -1, -1, 3]) },
    uv: { size: 2, data: new Float32Array([0, 0, 2, 0, 0, 2]) }
  });

  const backgroundTexture = new ogl.Texture(gl, {
    minFilter: gl.LINEAR,
    magFilter: gl.LINEAR
  });

  const bgImage = new Image();
  bgImage.onload = () => (backgroundTexture.image = bgImage);
  bgImage.crossOrigin = 'anonymous';
  bgImage.src = "!МЕСТО ДЛЯ ССЫЛКИ!";

  let sX, sY;
  const imgAspect = imageResolution[1] / imageResolution[0];
  if (window.innerHeight / window.innerWidth < imgAspect) {
    sX = 1;
    sY = window.innerHeight / window.innerWidth / imgAspect;
  } else {
    sX = (window.innerWidth / window.innerHeight) * imgAspect;
    sY = 1;
  }

  const shaderProgram = new ogl.Program(gl, {
    vertex: vertShader,
    fragment: fragShader,
    uniforms: {
      uTime: { value: 0 },
      tWater: { value: backgroundTexture },
      tFlow: flowmap.uniform,
      resolution: { value: new ogl.Vec4(window.innerWidth, window.innerHeight, sX, sY) }
    }
  });

  const plane = new ogl.Mesh(gl, { geometry, program: shaderProgram });
  window.addEventListener('resize', handleResize);
  handleResize();

  const canvas = gl.canvas;
  const isTouch = 'ontouchstart' in window;

  if (!isTouch) {
    canvas.addEventListener('mousemove', onMouseMove, false);
  }

  let lastTime;
  const lastMouse = new ogl.Vec2();

  function onMouseMove(e) {
    e.preventDefault();
    const x = e.pageX || e.clientX;
    const y = e.pageY || e.clientY;
    mousePos.set(x / gl.renderer.width, 1.0 - y / gl.renderer.height);

    if (!lastTime) {
      lastTime = performance.now();
      lastMouse.set(x, y);
    }

    const dx = x - lastMouse.x;
    const dy = y - lastMouse.y;
    lastMouse.set(x, y);

    const now = performance.now();
    const delta = Math.max(10.4, now - lastTime);
    lastTime = now;

    velocity.x = dx / delta;
    velocity.y = dy / delta;
    velocity.needsUpdate = true;
  }

  requestAnimationFrame(loop);

  function loop(time) {
    requestAnimationFrame(loop);
    if (!velocity.needsUpdate) {
      mousePos.set(-1);
      velocity.set(0);
    }
    velocity.needsUpdate = false;

    flowmap.aspect = aspectRatio;
    flowmap.mouse.copy(mousePos);
    flowmap.velocity.lerp(velocity, velocity.len ? 0.15 : 0.1);
    flowmap.update();

    shaderProgram.uniforms.uTime.value = time * 0.01;
    renderer.render({ scene: plane });
  }
}
</script>
Шаг 4
Добавляем блок IM01, загружаем в него нужную картинку (на которой будет глитч-эффект)
Шаг 5
Опубликовываем страницу. Нажимаем правой кнопкой на картинку (которая опубликована с помощью блока IM01) и выбираем «Открыть в новой вкладке», нам нужна ссылка на эту картинку, ее вставляем в код (в блоке Т123).
Кавычки должны остаться!
Шаг 6
После того как вставили ссылку в блок Т123 выключаем видимость блока IM01
Шаг 7
Опубликовываем страницу еще раз. Наслаждаемся
Примечание
Важный момент!
Чтобы эффект работал, даже если сверху расположен контент — нужно выставить значение «NONE» для Pointer Events
Поблагодарить
Поддержать проект донатом
Хочешь следить за обновлениями?
Подписывайся на телеграм канал чтобы не пропустить новые гайды.