Подборка 5 стильных фоновых анимаций для Тильда

1
Метеорный поток
Тонкие светящиеся линии, похожие на падающие метеоры или быстрые космические следы, скользят по чёрному фону по диагонали. Холодные синие, бирюзовые и фиолетовые вспышки создают ощущение скорости, глубины и космического движения.
<style>
#s3-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
}
#s3-wrap canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

<div id="s3-wrap"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
(function () {
  var wrap = document.getElementById('s3-wrap');
  if (!wrap) return;

  var scene = new THREE.Scene();
  var camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);

  var renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  wrap.appendChild(renderer.domElement);

  var uniforms = {
    iTime:       { value: 0 },
    iResolution: { value: new THREE.Vector2() }
  };

  var material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: 'void main(){gl_Position=vec4(position,1.0);}',
    fragmentShader: [
      'uniform float iTime;',
      'uniform vec2 iResolution;',
      '#define NUM_OCTAVES 3',
      'float rand(vec2 n){return fract(sin(dot(n,vec2(12.9898,4.1414)))*43758.5453);}',
      'float noise(vec2 p){',
      '  vec2 ip=floor(p),u=fract(p);',
      '  u=u*u*(3.0-2.0*u);',
      '  return pow(mix(mix(rand(ip),rand(ip+vec2(1,0)),u.x),mix(rand(ip+vec2(0,1)),rand(ip+vec2(1,1)),u.x),u.y),2.0);',
      '}',
      'float fbm(vec2 x){',
      '  float v=0.0,a=0.3;',
      '  vec2 shift=vec2(100);',
      '  mat2 rot=mat2(cos(0.5),sin(0.5),-sin(0.5),cos(0.5));',
      '  for(int i=0;i<NUM_OCTAVES;++i){v+=a*noise(x);x=rot*x*2.0+shift;a*=0.4;}',
      '  return v;',
      '}',
      'void main(){',
      '  vec2 shake=vec2(sin(iTime*1.2)*0.005,cos(iTime*2.1)*0.005);',
      '  vec2 p=((gl_FragCoord.xy+shake*iResolution.xy)-iResolution.xy*0.5)/iResolution.y*mat2(6.0,-4.0,4.0,6.0);',
      '  vec2 v;',
      '  vec4 o=vec4(0.0);',
      '  float f=2.0+fbm(p+vec2(iTime*5.0,0.0))*0.5;',
      '  for(float i=0.0;i<35.0;i++){',
      '    v=p+cos(i*i+(iTime+p.x*0.08)*0.025+i*vec2(13.0,11.0))*3.5+vec2(sin(iTime*3.0+i)*0.003,cos(iTime*3.5-i)*0.003);',
      '    float tailNoise=fbm(v+vec2(iTime*0.5,i))*0.3*(1.0-(i/35.0));',
      '    vec4 col=vec4(0.1+0.3*sin(i*0.2+iTime*0.4),0.3+0.5*cos(i*0.3+iTime*0.5),0.7+0.3*sin(i*0.4+iTime*0.3),1.0);',
      '    vec4 contrib=col*exp(sin(i*i+iTime*0.8))/length(max(v,vec2(v.x*f*0.015,v.y*1.5)));',
      '    float thin=smoothstep(0.0,1.0,i/35.0)*0.6;',
      '    o+=contrib*(1.0+tailNoise*0.8)*thin;',
      '  }',
      '  o=tanh(pow(o/100.0,vec4(1.6)));',
      '  gl_FragColor=o*1.5;',
      '}'
    ].join('\n')
  });

  var mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material);
  scene.add(mesh);

  function resize() {
    var rect = wrap.getBoundingClientRect();
    renderer.setSize(rect.width, rect.height);
    uniforms.iResolution.value.set(renderer.domElement.width, renderer.domElement.height);
  }

  var raf;
  function animate() {
    raf = requestAnimationFrame(animate);
    uniforms.iTime.value += 0.03;
    renderer.render(scene, camera);
  }

  new IntersectionObserver(function(entries) {
    if (entries[0].isIntersecting) {
      if (!raf) animate();
    } else {
      cancelAnimationFrame(raf);
      raf = null;
    }
  }, { threshold: 0 }).observe(wrap);

  window.addEventListener('resize', resize);
  resize();
  animate();
})();
</script>
2
Концентрические волны
Тонкие светящиеся кольца расходятся из центра, пульсируя и меняя цвет между красным, зелёным и синим. Геометричный, гипнотический эффект — напоминает звуковые волны или рябь на воде в неоновом свете.
Shader Animation
<style>
#s2-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
  border-radius: 24px;
}
#s2-wrap canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

<div id="s2-wrap"></div>

<script>
(function () {
  var wrap = document.getElementById('s2-wrap');
  if (!wrap) return;

  var camera = new THREE.Camera();
  camera.position.z = 1;

  var scene = new THREE.Scene();
  var geometry = new THREE.PlaneGeometry(2, 2);

  var uniforms = {
    time:       { type: 'f',  value: 1.0 },
    resolution: { type: 'v2', value: new THREE.Vector2() }
  };

  var material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: [
      'void main() {',
      '  gl_Position = vec4(position, 1.0);',
      '}'
    ].join('\n'),
    fragmentShader: [
      '#define TWO_PI 6.2831853072',
      '#define PI 3.14159265359',
      'precision highp float;',
      'uniform vec2 resolution;',
      'uniform float time;',
      'void main(void) {',
      '  vec2 uv = (gl_FragCoord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y);',
      '  float t = time * 0.05;',
      '  float lineWidth = 0.002;',
      '  vec3 color = vec3(0.0);',
      '  for(int j = 0; j < 3; j++){',
      '    for(int i = 0; i < 5; i++){',
      '      color[j] += lineWidth * float(i*i) / abs(fract(t - 0.01*float(j) + float(i)*0.01)*5.0 - length(uv) + mod(uv.x+uv.y, 0.2));',
      '    }',
      '  }',
      '  gl_FragColor = vec4(color[0], color[1], color[2], 1.0);',
      '}'
    ].join('\n')
  });

  var mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  var renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  wrap.appendChild(renderer.domElement);

  function resize() {
    var rect = wrap.getBoundingClientRect();
    renderer.setSize(rect.width, rect.height);
    uniforms.resolution.value.x = renderer.domElement.width;
    uniforms.resolution.value.y = renderer.domElement.height;
  }

  var raf;
  function animate() {
    raf = requestAnimationFrame(animate);
    uniforms.time.value += 0.05;
    renderer.render(scene, camera);
  }

  new IntersectionObserver(function(entries) {
    if (entries[0].isIntersecting) {
      if (!raf) animate();
    } else {
      cancelAnimationFrame(raf);
      raf = null;
    }
  }, { threshold: 0 }).observe(wrap);

  window.addEventListener('resize', resize);
  resize();
  animate();
})();
</script>
3
Плазменные линии
Светящиеся кривые линии фиолетово-синих оттенков волнообразно текут по тёмному фону. Вдоль каждой линии движутся яркие точки-частицы, усиливая ощущение потока энергии или данных.
<style>
#s4-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
  border-radius: 24px;
}
#s4-wrap canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

<div id="s4-wrap">
  <canvas id="s4-canvas"></canvas>
</div>

<script>
(function () {
  var canvas = document.getElementById('s4-canvas');
  var wrap = document.getElementById('s4-wrap');
  if (!canvas || !wrap) return;

  var gl = canvas.getContext('webgl');
  if (!gl) return;

  var VS = [
    'attribute vec4 aVertexPosition;',
    'void main(){gl_Position=aVertexPosition;}'
  ].join('\n');

  var FS = [
    'precision highp float;',
    'uniform vec2 iResolution;',
    'uniform float iTime;',
    'const float overallSpeed=0.2;',
    'const float gridSmoothWidth=0.015;',
    'const float axisWidth=0.05;',
    'const float majorLineWidth=0.025;',
    'const float minorLineWidth=0.0125;',
    'const float majorLineFrequency=5.0;',
    'const float minorLineFrequency=1.0;',
    'const float scale=5.0;',
    'const vec4 lineColor=vec4(0.4,0.2,0.8,1.0);',
    'const float minLineWidth=0.01;',
    'const float maxLineWidth=0.2;',
    'const float lineSpeed=1.0*overallSpeed;',
    'const float lineAmplitude=1.0;',
    'const float lineFrequency=0.2;',
    'const float warpSpeed=0.2*overallSpeed;',
    'const float warpFrequency=0.5;',
    'const float warpAmplitude=1.0;',
    'const float offsetFrequency=0.5;',
    'const float offsetSpeed=1.33*overallSpeed;',
    'const float minOffsetSpread=0.6;',
    'const float maxOffsetSpread=2.0;',
    '#define drawCircle(pos,radius,coord) smoothstep(radius+gridSmoothWidth,radius,length(coord-(pos)))',
    '#define drawSmoothLine(pos,halfWidth,t) smoothstep(halfWidth,0.0,abs(pos-(t)))',
    '#define drawCrispLine(pos,halfWidth,t) smoothstep(halfWidth+gridSmoothWidth,halfWidth,abs(pos-(t)))',
    '#define drawPeriodicLine(freq,width,t) drawCrispLine(freq/2.0,width,abs(mod(t,freq)-(freq)/2.0))',
    'float random(float t){return(cos(t)+cos(t*1.3+1.3)+cos(t*1.4+1.4))/3.0;}',
    'float getPlasmaY(float x,float hf,float offset){return random(x*lineFrequency+iTime*lineSpeed)*hf*lineAmplitude+offset;}',
    'void main(){',
    '  vec2 uv=gl_FragCoord.xy/iResolution.xy;',
    '  vec2 space=(gl_FragCoord.xy-iResolution.xy/2.0)/iResolution.x*2.0*scale;',
    '  float hf=1.0-(cos(uv.x*6.28)*0.5+0.5);',
    '  float vf=1.0-(cos(uv.y*6.28)*0.5+0.5);',
    '  space.y+=random(space.x*warpFrequency+iTime*warpSpeed)*warpAmplitude*(0.5+hf);',
    '  space.x+=random(space.y*warpFrequency+iTime*warpSpeed+2.0)*warpAmplitude*hf;',
    '  vec4 lines=vec4(0.0);',
    '  vec4 bgColor1=vec4(0.1,0.1,0.3,1.0);',
    '  vec4 bgColor2=vec4(0.3,0.1,0.5,1.0);',
    '  for(int l=0;l<16;l++){',
    '    float nli=float(l)/16.0;',
    '    float ot=iTime*offsetSpeed;',
    '    float op=float(l)+space.x*offsetFrequency;',
    '    float rand=random(op+ot)*0.5+0.5;',
    '    float hw=mix(minLineWidth,maxLineWidth,rand*hf)/2.0;',
    '    float offset=random(op+ot*(1.0+nli))*mix(minOffsetSpread,maxOffsetSpread,hf);',
    '    float lp=getPlasmaY(space.x,hf,offset);',
    '    float line=drawSmoothLine(lp,hw,space.y)/2.0+drawCrispLine(lp,hw*0.15,space.y);',
    '    float cx=mod(float(l)+iTime*lineSpeed,25.0)-12.0;',
    '    vec2 cp=vec2(cx,getPlasmaY(cx,hf,offset));',
    '    float circle=drawCircle(cp,0.01,space)*4.0;',
    '    line=line+circle;',
    '    lines+=line*lineColor*rand;',
    '  }',
    '  vec4 fragColor=mix(bgColor1,bgColor2,uv.x);',
    '  fragColor*=vf;',
    '  fragColor.a=1.0;',
    '  fragColor+=lines;',
    '  gl_FragColor=fragColor;',
    '}'
  ].join('\n');

  function loadShader(type, src) {
    var s = gl.createShader(type);
    gl.shaderSource(s, src);
    gl.compileShader(s);
    if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
      gl.deleteShader(s);
      return null;
    }
    return s;
  }

  var prog = gl.createProgram();
  gl.attachShader(prog, loadShader(gl.VERTEX_SHADER, VS));
  gl.attachShader(prog, loadShader(gl.FRAGMENT_SHADER, FS));
  gl.linkProgram(prog);

  var buf = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buf);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1, 1,-1, -1,1, 1,1]), gl.STATIC_DRAW);

  var aPos = gl.getAttribLocation(prog, 'aVertexPosition');
  var uRes = gl.getUniformLocation(prog, 'iResolution');
  var uTime = gl.getUniformLocation(prog, 'iTime');

  function resize() {
    var rect = wrap.getBoundingClientRect();
    canvas.width = rect.width;
    canvas.height = rect.height;
    gl.viewport(0, 0, canvas.width, canvas.height);
  }

  var startTime = Date.now();
  var raf;

  function draw() {
    var t = (Date.now() - startTime) / 1000;
    gl.clearColor(0, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.useProgram(prog);
    gl.bindBuffer(gl.ARRAY_BUFFER, buf);
    gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(aPos);
    gl.uniform2f(uRes, canvas.width, canvas.height);
    gl.uniform1f(uTime, t);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
    raf = requestAnimationFrame(draw);
  }

  new IntersectionObserver(function(entries) {
    if (entries[0].isIntersecting) { if (!raf) draw(); }
    else { cancelAnimationFrame(raf); raf = null; }
  }, { threshold: 0 }).observe(wrap);

  window.addEventListener('resize', resize);
  resize();
  draw();
})();
</script>
4
RGB-волна
Одна плавная синусоидальная линия пересекает экран по диагонали снизу. В центре она белая и яркая, а к краям расщепляется на чистые красный, зелёный и синий — как свет, проходящий сквозь призму.
Design is Everything
Unleashing creativity through bold visuals, seamless interfaces, and limitless possibilities.
<style>
#s5-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
}
#s5-wrap canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

<div id="s5-wrap">
  <canvas id="s5-canvas"></canvas>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
(function () {
  var wrap = document.getElementById('s5-wrap');
  var canvas = document.getElementById('s5-canvas');
  if (!wrap || !canvas) return;

  var scene = new THREE.Scene();
  var camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, -1);

  var renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setClearColor(new THREE.Color(0x000000));

    var uniforms = {
      resolution:  { value: [wrap.clientWidth, wrap.clientHeight] },
      time:        { value: 0.0 },
      xScale:      { value: 0.8 },
      yScale:      { value: 0.4 },
      distortion:  { value: 0.25 }
    };

  var VS = [
    'attribute vec3 position;',
    'void main(){gl_Position=vec4(position,1.0);}'
  ].join('\n');

  var FS = [
    'precision highp float;',
    'uniform vec2 resolution;',
    'uniform float time;',
    'uniform float xScale;',
    'uniform float yScale;',
    'uniform float distortion;',
    'void main(){',
    '  vec2 p=(gl_FragCoord.xy*2.0-resolution)/min(resolution.x,resolution.y);',
    '  p.y += 0.55;',
    '  float d=length(p)*distortion;',
    '  float rx=p.x*(1.0+d);',
    '  float gx=p.x;',
    '  float bx=p.x*(1.0-d);',
    '  float r=0.05/abs(p.y+sin((rx+time)*xScale)*yScale);',
    '  float g=0.05/abs(p.y+sin((gx+time)*xScale)*yScale);',
    '  float b=0.05/abs(p.y+sin((bx+time)*xScale)*yScale);',
    '  gl_FragColor=vec4(r,g,b,1.0);',
    '}'
  ].join('\n');

  var positions = new THREE.BufferAttribute(new Float32Array([
    -1,-1,0,  1,-1,0, -1,1,0,
     1,-1,0, -1, 1,0,  1,1,0
  ]), 3);

  var geometry = new THREE.BufferGeometry();
  geometry.setAttribute('position', positions);

  var material = new THREE.RawShaderMaterial({
    vertexShader: VS,
    fragmentShader: FS,
    uniforms: uniforms,
    side: THREE.DoubleSide
  });

  scene.add(new THREE.Mesh(geometry, material));

  function resize() {
    var rect = wrap.getBoundingClientRect();
    renderer.setSize(rect.width, rect.height, false);
    uniforms.resolution.value = [renderer.domElement.width, renderer.domElement.height];
  }

  var raf;
  function animate() {
    raf = requestAnimationFrame(animate);
    uniforms.time.value += 0.01;
    renderer.render(scene, camera);
  }

  new IntersectionObserver(function(entries) {
    if (entries[0].isIntersecting) { if (!raf) animate(); }
    else { cancelAnimationFrame(raf); raf = null; }
  }, { threshold: 0 }).observe(wrap);

  window.addEventListener('resize', resize);
  resize();
  animate();
})();
</script>
5
Живая сетка точек
Регулярная сетка из сотен точек анимируется волновым движением — каждая точка поднимается и опускается по синусоиде, создавая эффект ряби на поверхности воды. Минималистично и элегантно.
Dotted Surface
<style>
#dot-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
}
#dot-wrap canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

<div id="dot-wrap"></div>

<script>
(function () {
  var wrap = document.getElementById('dot-wrap');
  if (!wrap) return;

  var SEPARATION = 150, AMOUNTX = 40, AMOUNTY = 60;

  var scene = new THREE.Scene();
  scene.fog = new THREE.Fog(0xffffff, 2000, 10000);

  var rect = wrap.getBoundingClientRect();
  var camera = new THREE.PerspectiveCamera(60, rect.width / rect.height, 1, 10000);
  camera.position.set(0, 355, 1220);

  var renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setSize(rect.width, rect.height);
  renderer.setClearColor(0xffffff, 0);
  wrap.appendChild(renderer.domElement);

  var positions = [], colors = [];

  for (var ix = 0; ix < AMOUNTX; ix++) {
    for (var iy = 0; iy < AMOUNTY; iy++) {
      positions.push(ix * SEPARATION - (AMOUNTX * SEPARATION) / 2, 0, iy * SEPARATION - (AMOUNTY * SEPARATION) / 2);
      colors.push(200, 200, 200);
    }
  }

  var geometry = new THREE.BufferGeometry();
  geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
  geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

  var material = new THREE.PointsMaterial({
    size: 8, vertexColors: true, transparent: true, opacity: 0.8, sizeAttenuation: true
  });

  scene.add(new THREE.Points(geometry, material));

  var count = 0, raf;

  function animate() {
    raf = requestAnimationFrame(animate);
    var pos = geometry.attributes.position.array;
    var i = 0;
    for (var ix = 0; ix < AMOUNTX; ix++) {
      for (var iy = 0; iy < AMOUNTY; iy++) {
        pos[i * 3 + 1] = Math.sin((ix + count) * 0.3) * 50 + Math.sin((iy + count) * 0.5) * 50;
        i++;
      }
    }
    geometry.attributes.position.needsUpdate = true;
    renderer.render(scene, camera);
    count += 0.1;
  }

  function resize() {
    var r = wrap.getBoundingClientRect();
    camera.aspect = r.width / r.height;
    camera.updateProjectionMatrix();
    renderer.setSize(r.width, r.height);
  }

  new IntersectionObserver(function(entries) {
    if (entries[0].isIntersecting) { if (!raf) animate(); }
    else { cancelAnimationFrame(raf); raf = null; }
  }, { threshold: 0 }).observe(wrap);

  window.addEventListener('resize', resize);
  resize();
  animate();
})();
</script>
Инструкция:
  1. В блок T123 добавили код.
  2. Код можно закинуть в ИИ, и спросить, как поменять тот или оной параметр (цвет, скорость, размер и так далее).
Больше кода для Tilda в ТГ-канале
Поблагодари за код - подпишись https://t.me/breeze_tilda