奔夢向前-代碼實現炫酷網頁特效-2020-04-28-8

下面是整體代碼,按鍵Ctrl+C複製,複製完粘貼到記事本里面,把.txt後綴改成.html然後打開就可以看到這個炫酷的特效了。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>編程特趣</title>
<style>
html,body {
    margin:0;
    padding:0;
    overflow:hidden;
    background-color:#000000
}
body {
    height:100vh;
    display:flex;
    align-items:center;
    justify-content:center;
}
.canvas {
    display:block;
    border-radius:50%;
}
.canvas-pattern {
    display:none;
}
</style>

</head>
<body>

<canvas class="canvas canvas-pattern js-canvas" width="500" height="500"></canvas>
<canvas class="canvas js-duplicate" width="500" height="500"></canvas>

<script type="text/javascript">
const canvas = document.querySelector('.js-canvas');
const ctx = canvas.getContext('2d');

const canvas2 = document.querySelector('.js-duplicate');
const ctx2 = canvas2.getContext('2d');

const dim = Math.min(window.innerWidth, window.innerHeight) * 0.95;
const w = dim;
const h = dim;
const midX = w >> 1;
const midY = h >> 1;

const PI = Math.PI;
const TO_RADIAN = PI / 180;

const maxDepth = 5;
const maxSpread = 90 * TO_RADIAN;

let autoAnimate = true;
let divergeAt = 0.5;
let spread = 45 * TO_RADIAN;
let tick = 0;

let autoSpeed = 0.004;
let autoTick = 0;

canvas.width = canvas2.width = w;
canvas.height = canvas2.height = h;

class Branch {
  constructor(position = {x : 0, y: 0}, length = 100, divergeAt = 0.5, angle = 0, depth = 0, spread = 45 * TO_RADIAN) {
    this.position = position;
    this.length = length;
    this.divergeAt = divergeAt;
    this.angle = angle;
    this.depth = depth;

    this.color = '#000';
    this.spread = spread;
    this.branches = [];

    this.grow();
  }

  grow() {
    if (!this.canBranch) {
      return;
    }

    this.branches = [];

    const nextLength = this.length * 0.75;
    const nextDepth = this.depth + 1;

    this.branches.push(
      new Branch(
        this.growPosition,
        nextLength,
        this.divergeAt,
        this.angle + this.spread,
        nextDepth,
        this.spread
      ),
      new Branch(
        this.growPosition,
        nextLength,
        this.divergeAt,
        this.angle - this.spread,
        nextDepth,
        this.spread
      )
    );
  }

  update(spread, divergeAt) {
    this.spread = spread;
    this.divergeAt = divergeAt;

    this.grow();
  }

  get growPosition() {
    const dl = this.length * this.divergeAt;

    return {
      x: this.position.x + (Math.cos(this.angle) * dl),
      y: this.position.y + (Math.sin(this.angle) * dl),
    };
  }

  get canBranch() {
    return this.depth < maxDepth;
  }
}

const rootBranch = new Branch(
  { x: midX, y: midY },
  midY * 0.5,
  divergeAt,
  -90 * TO_RADIAN,
  0,
  spread
);

const drawBranch = (branch, phase) => {
  const h = ~~(200 + (160 * phase));
  const l = 50 + ~~(((branch.depth / (maxDepth + 1))) * 50);

  const endX = branch.length;
  const endY = 0;
  const r = 2;

  ctx.save();

  ctx.strokeStyle = `hsl(${h}, 100%, ${l}%)`;
  ctx.translate(branch.position.x, branch.position.y);
  ctx.rotate(branch.angle);

  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(endX, endY);
  ctx.stroke();
  ctx.closePath();

  ctx.beginPath();
  ctx.fillStyle = `hsl(${h}, 100%, 50%)`;
  ctx.arc(endX, endY, r, 0, PI * 2, false);
  ctx.fill();
  ctx.closePath();

  ctx.restore();

  branch.branches.forEach((b) => {
    drawBranch(b, phase);
  });
};

const map = (value, start1, stop1, start2, stop2) => ((value - start1) / (stop1 - start1)) * (stop2 - start2) + start2;

const clear = () => {
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  ctx2.clearRect(0, 0, ctx2.canvas.width, ctx2.canvas.height);
};

const loop = () => {
  let phase = rootBranch.spread / maxSpread;

  clear(phase);

  if (autoAnimate) {
    phase = map(Math.sin(autoTick), -1, 1, 0, 1);

    spread = phase * maxSpread;
    divergeAt = map(Math.sin(autoTick), -1, 1, 0, 0.5);

    autoTick += autoSpeed;
  }

  rootBranch.update(spread, divergeAt);

  drawBranch(rootBranch, phase);

  const numSegments = 12;
  const angleInc = PI * 2 / numSegments;
  let angle = tick;

  for (let i = 0; i < numSegments; i++) {
    ctx2.save();
    ctx2.translate(midX, midY);
    ctx2.rotate(angle);
    ctx2.drawImage(canvas, -w / 2, -h / 2);
    ctx2.restore();
    angle += angleInc;
  }

  tick += 0.002;

  requestAnimationFrame(loop);
};

const onPointerMove = (e) => {
  if (autoAnimate) {
    return;
  }

  const target = (e.touches && e.touches.length) ? e.touches[0] : e;
  const { clientX: x, clientY: y } = target;

  const width = window.innerWidth;
  const height = window.innerHeight;

  spread = (x / width) * maxSpread;
  divergeAt = y / height;
};

document.body.addEventListener('mousemove', onPointerMove);
document.body.addEventListener('touchmove', onPointerMove);

document.addEventListener('mouseenter', () => {
  autoAnimate = false;
});

document.addEventListener('mouseleave', () => {
  autoAnimate = true;
});

loop();
</script>
</body>
</html>

一起來看效果!!!

網頁可以通過鼠標移動,可以讓這個網頁裏面的效果,改變、可以放大、也可以縮小,會有不一樣的效果。趕快來試試吧!

1、感謝你支持!如果大佬們把代碼按照圖片嘗試不顯示的話,可以切換兼容性的瀏覽器,例如:Google、搜狗瀏覽器、360瀏覽器,切記:不要使用windos自帶的瀏覽器,IE瀏覽器,最好是使用Google。
2、每天不斷學習編程提升自己的編程知識,繼續加油。
有情提示:上面說的都嘗試了,還是沒有出現以上圖片的效果,大家可以嘗試登陸賬號下載文件即可,祝你每天開心學編程。
3、奔夢向前祝你天天開心學編程,網頁設計本身就是屬於小白的入門課程,所以小白們你們可要加油!相信自己一定可以堅持學下去,學精他,到時候自己獨立製作一個屬於自己的網頁界面,分享給你自己的朋友。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章