canvas实现数字毛发生长动画效果代码

代码语言:html

所属分类:动画

代码描述:canvas实现数字毛发生长动画效果代码,毛发生长形成一个数字。

代码标签: canvas实 数字 毛发 生长 动画

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

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  
  
  
<style>
*, *::before, *::after {
    margin: 0;
    padding: 0;
    border: 0;
    box-sizing: border-box;
}

*:focus {
    outline: none;
}

body {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

canvas {
    touch-action: none;
}
</style>


  
  
</head>

<body translate="no">
  <script>

    const imageSrc = 'data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMwaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA5LjEtYzAwMiA3OS5hNmE2Mzk2OGEsIDIwMjQvMDMvMDYtMTE6NTI6MDUgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyNS4xMSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjI5NzRDODY3MEUzMTFFRjkzQzQ5OUVFNjc0OTI0NDQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjI5NzRDODc3MEUzMTFFRjkzQzQ5OUVFNjc0OTI0NDQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2Mjk3NEM4NDcwRTMxMUVGOTNDNDk5RUU2NzQ5MjQ0NCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2Mjk3NEM4NTcwRTMxMUVGOTNDNDk5RUU2NzQ5MjQ0NCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/uAA5BZG9iZQBkwAAAAAH/2wCEABsaGikdKUEmJkFCLy8v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';

</script>
  
      <script id="rendered-js" >
//---

'use strict';

//---

console.clear();

//---

let w = 0;
let h = 0;

let renderIteration = 0;
let animationFrame = null;
let isTouchDevice = false;

const dpr = Math.max(1, window.devicePixelRatio);
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d', { alpha: false, willReadFrequently: true });

let imageSource = null;
const canvasSource = document.createElement('canvas');
const contextSource = canvasSource.getContext('2d', { alpha: false, willReadFrequently: true });

const border = { left: 0, top: 0, right: w, bottom: h };
const center = { x: 0, y: 0 };

let imageData = null;
let data = null;

let imageDataSource = null;
let dataSource = null;

//---

const sectorTiles = 20;
let sectorSizeX = 0;
let sectorSizeY = 0;
let sectors = new Map();
let sectorsX = 0;
let sectorsY = 0;

//---

let boidHolder = [];
let boidCount = 2048;
let boidIndex = 0;
const boidRadius = 6;
const boidDiameter = boidRadius * 2;
const boidDiameterSquared = boidDiameter * boidDiameter;
let boidSpeed = 1;
const boidSpeedMin = 0;
const boidSpeedMax = 2.5;
const boidRadialSpeed = Math.PI / 60;
const boidVision = 50;
const boidVisionSquared = boidVision * boidVision;

const boidRadialSpeedMin = Math.PI / 10;
const boidRadialSpeedMax = Math.PI / 60;
const boidRepulsionDistance = 100;
const boidRepulsionDistanceSquared = boidRepulsionDistance * boidRepulsionDistance;

let boidCounterMax = 0;
let boidOffsetMax = 0;

//---

let pointerInitialPos = { x: -boidRepulsionDistance, y: -boidRepulsionDistance };
let pointer = { x: 0, y: 0 };
let pointerPos = { x: 0, y: 0 };
let pointerDownButton = -1;
let pointerActive = false;

//---

function init() {

  isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;

  //---

  if (isTouchDevice === true) {

    boidCount *= 0.75;

    canvas.addEventListener('touchmove', cursorMoveHandler, false);
    canvas.addEventListener('touchend', cursorLeaveHandler, false);
    canvas.addEventListener('touchcancel ', cursorLeaveHandler, false);

  } else {

    canvas.addEventListener('pointermove', cursorMoveHandler, false);
    canvas.addEventListener('pointerdown', cursorDownHandler, false);
    canvas.addEventListener('pointerup', cursorUpHandler, false);
    canvas.addEventListener('pointerleave', cursorLeaveHandler, false);

  }

  //---

  document.body.appendChild(canvas);

  //---

  // canvasSource.style.pointerEvents = 'none';
  // canvasSource.style.position = 'absolute';
  // canvasSource.style.top = '0';
  // canvasSource.style.left = '0';
  // canvasSource.style.opacity = '0.25';

  document.body.appendChild(canvasSource);

  //---

  imageSource = new Image();
  imageSource.src = imageSrc;
  imageSource.onload = () => {

    window.addEventListener('resize', onResize, false);

    restart();

  };

}

function onResize(event) {

  restart();

}

function restart() {

  const innerWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  const innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

  //---

  w = innerWidth;
  h = innerHeight;

  //---

  canvas.width = w * dpr;
  canvas.height = h * dpr;

  canvasSource.width = w * dpr;
  canvasSource.height = h * dpr;

  //---

  const imageAspectRatio = imageSource.width / imageSource.height;
  const canvasAspectRatio = w / h;

  let drawWidth = 0;
  let drawHeight = 0;

  if (canvasAspectRatio > imageAspectRatio) {

    drawWidth = w;
    drawHeight = w / imageAspectRatio;

  } else {

    drawHeight = h;
    drawWidth = h * imageAspectRatio;

  }

  const offsetX = (w - drawWidth) * 0.5;
  const offsetY = (h - drawHeight) * 0.5;

  contextSource.drawImage(imageSource, offsetX, offsetY, drawWidth, drawHeight);

  //---

  imageData = context.getImageData(0, 0, w, h);
  data = imageData.data;

  imageDataSource = contextSource.getImageData(0, 0, w, h);
  dataSource = imageDataSource.data;

  //---

  sectorSizeX = Math.floor(w / sectorTiles);
  sectorSizeY = Math.floor(h / sectorTiles);
  sectors = new Map();
  sectorsX = Math.ceil(w / sectorSizeX);
  sectorsY = Math.ceil(h / sectorSizeY);

  //---

  border.right = w - 1;
  border.bottom = h - 1;

  center.x = w / 2;
  center.y = h / 2;

  pointerPos.x = pointerInitialPos.x;
  pointerPos.y = pointerInitialPos.y;
  pointer.x = pointerInitialPos.x;
  pointer.y = pointerInitialPos.y;

  //---

  boidCounterMax = Math.round(Math.min(w, h) / 48);

  //---

  removeBoids();
  createBoids();

  //---

  if (animationFrame != null) {

    cancelAnimFrame(animationFrame);

  }

  render();

}

//---

function removeBoids() {

  boidIndex = 0;
  boidHolder = [];

}

function createBoids() {

  for (let i = 0; i < boidCount; i++) {

    const boid = createBoid(0, 0, 0, i);

    boidHolder.push(boid);

  }

}

function createBoid(x, y, heading = Math.random() * 2 * Math.PI - Math.PI, id = 0) {

  const boid = {};

  resetBoid(boid, x, y, heading);

  boid.id = id;

  return boid;

}

function activateBoids() {

  for (let i = 0; i < 16; i++) {

    activateBoid();

  }

}

function activateBoid() {

  const angle = Math.random() * Math.PI * 2;

  const distance = Math.random() * (Math.min(w, h) * 0.5);

  const x = center.x + Math.cos(angle) * distance;
  const y = center.y + Math.sin(angle) * distance;

  const color = getPixel(x | 0, y | 0);

  if (color.r < 55 && color.g < 55 && color.b < 55 || distance .........完整代码请登录后点击上方下载按钮下载查看

网友评论0