文字旋转分解合成动画效果

代码语言:html

所属分类:动画

代码描述:文字旋转分解合成动画效果

代码标签: 合成 动画 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<style>
body {
  margin: 0;
}

.hidden-warning {
  display: none
}

canvas {
  width: 100vw;
  height: 100vh;
}
</style>

</head>
<body translate="no">
<p class="hidden-warning">The browser you're in doesn't support OffscreenCanvas yet, </p>
<canvas></canvas>

<script>
/**
 * (This module doesn't support being used in a <script> tag)
 * https://github.com/gre/bezier-easing
 * BezierEasing - use bezier curve for transition easing function
 * by Gaëtan Renaudeau 2014 - 2015 – MIT License
 */
const BezierEasing = (() => {var r = 4,n = .001,t = 1e-7,u = 10,e = 11,o = 1 / (e - 1),i = "function" == typeof Float32Array;function f(r, n) {return 1 - 3 * n + 3 * r;}function a(r, n) {return 3 * n - 6 * r;}function c(r) {return 3 * r;}function v(r, n, t) {return ((f(n, t) * r + a(n, t)) * r + c(n)) * r;}function s(r, n, t) {return 3 * f(n, t) * r * r + 2 * a(n, t) * r + c(n);}function w(r) {return r;}return function (f, a, c, l) {if (!(0 <= f && f <= 1 && 0 <= c && c <= 1)) throw new Error("bezier x values must be in [0, 1] range");if (f === a && c === l) return w;for (var y = i ? new Float32Array(e) : new Array(e), b = 0; b < e; ++b) y[b] = v(b * o, f, c);function h(i) {for (var a = 0, w = 1, l = e - 1; w !== l && y[w] <= i; ++w) a += o;var b = a + (i - y[--w]) / (y[w + 1] - y[w]) * o,h = s(b, f, c);return h >= n ? function (n, t, u, e) {for (var o = 0; o < r; ++o) {var i = s(t, u, e);if (0 === i) return t;t -= (v(t, u, e) - n) / i;}return t;}(i, b, f, c) : 0 === h ? b : function (r, n, e, o, i) {var f,a,c = 0;do {(f = v(a = n + (e - n) / 2, o, i) - r) > 0 ? e = a : n = a;} while (Math.abs(f) > t && ++c < u);return a;}(i, a, a + o, f, c);}return function (r) {return 0 === r ? 0 : 1 === r ? 1 : v(h(r), a, l);};};})();

if (typeof OffscreenCanvas === 'undefined') {
  document.querySelector('.hidden-warning').classList.remove('hidden-warning');
}

const random = {
  value() {return Math.random();},
  range(min, max) {
    return min + this.value() * (max - min);
  },
  floorRange(min, max) {
    return Math.floor(this.range(min, max));
  } };


const rotationEasing = BezierEasing(0.9, 0.25, 0.1, 0.75);

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const width = canvas.width = canvas.clientWidth;
const height = canvas.height = canvas.clientHeight;

const helloTiles = generateTiles('hello');
const worldTiles = generateTiles('world', textCtx => {
  textCtx.fillStyle = 'white';
});

frame();

function frame(timestamp = 0) {
  requestAnimationFrame(frame);

  const t = timestamp / 400;

  ctx.clearRect(0, 0, width, height);
  ctx.save();

  let rotationT = t % (Math.PI * 2);
  const extra = rotationT > Math.PI ? Math.PI : 0;
  rotationT =
  rotationEasing((rotationT - extra) / Math.PI) * Math.PI + extra;

  ctx.translate(width / 2, height / 2);
  ctx.rotate(rotationT);
  ctx.translate(-width / 2, -height / 2);

  ctx.fillStyle = 'black';
  ctx.fillRect(
  width / -2,
  height / 2,
  width * 2,
  height * 2);


  const helloT = cubicInOut(Math.cos(t - Math.PI) / 2 + 0.5);
  drawTiles(helloTiles, helloT);

  ctx.save();
  ctx.translate(width / 2, height / 2);
  ctx.rotate(Math.PI);
  ctx.translate(width / -2, height / -2);
  const worldT = cubicInOut(Math.cos(t) / 2 + 0.5);
  drawTiles(worldTiles, worldT);
  ctx.restore();

  ctx.restore();
}

function generateTiles(text, styleFn, tilesX = 15, tilesY = 7) {
  const textCanvas = new OffscreenCanvas(300, 75);
  const textCtx = textCanvas.getContext('2d');

  const textWidth = textCtx.canvas.width;
  const textHeight = textCtx.canvas.height;

  const tileWidth = textWidth / tilesX;
  const tileHeight = textHeight / tilesY;

  const verticalLines = [[0, 0]];
  for (let i = 1; i < tilesX; i++) {
    const topX = tileWidth * i + random.range(-0.5, 0.5) * tileWidth * 0.8;
    const bottomX =
    tileWidth * i + random.range(-0.5, 0.5) * tileWidth * 0.8;
    verticalLines.push([topX, bottomX]);
  }
  verticalLines.push([textWidth, textWidth]);

  const horizontalLines = [[0, 0]];
  for (let i = 1; i < tilesY; i++) {
    const leftY =
    tileHeight * i + random.range(-0.5, 0.5) * tileHeight * 0.8;
    const rightY =
.........完整代码请登录后点击上方下载按钮下载查看

网友评论0