EVANYOU尤大个人网站主页CANVAS三角彩带效果分析学习

尤雨溪网站三角彩带效果

效果:

源码

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <canvas></canvas></body><script>var c = document.getElementsByTagName('canvas')[0], x = c.getContext('2d'), pr = window.devicePixelRatio || 1, /*devicePixelRatio *devicePixelRatio = screenPhysicalPixels/deviceIndependentPixels *eg.iPhone4s,Resolution:960*640 * screenPhysicalPixels=640px * deviceIndependentPixels=320px * devicePixelRatio=640/320=2 *You need set diff-size imgs to fit the devicePixelRatio. */ w = window.innerWidth, h = window.innerHeight, f = 90, // InitialDistance q, z = Math.random, r = 0 u = Math.PI * 2, v = Math.cosc.width = w * prc.height = h * prx.scale(pr, pr) // Synchronization with devicePixelRatiox.globalAlpha = 0.6 // gloabalAlpha set or return the opacity-value of drawfunction i() { x.clearRect(0, 0, w, h) // clear all rect q = [{x: 0, y: h * .7 + f},{x: 0, y: h * .7 - f}] while(q[1].x < w + f)d(q[0], q[1]); // w + f}function d(i ,j) { x.beginPath() x.moveTo(i.x, i.y) x.lineTo(j.x, j.y) var k = j.x + (z() * 2 - 0.25) * f, // x->[-0.25 * f, 1.75 * f] // x_average = 0.75 * 90 = 67.5 // number_rects = 1080 / 67.5 = 16 n = y(j.y) /*When k < 0: *The first rect will be invisable, it is in the window's left. *So we can see the first line on the window sometimes changes the initial position. */ x.lineTo(k ,n) x.closePath() r -= u / -50 x.fillStyle = '#' + (v(r) * 127 + 128 << 16 | v(r + u / 3) * 127 + 128 << 8 | v(r + u / 3 * 2) * 127 + 128).toString(16) /*ColorSelectionAlgorithm * v=Math.cos,u=2*Math.Pi,r = n * Math.PI/25(n=0,1,2...) * (R,G,B)=>Hexadecimal === (R << 16|G << 8|B).toString(16) * 0xFFFFFF = 16777215 * It's equate to: * R = cos(r)*127+128 * G = cos(r+2*PI/3)*127+128 * B = cos(r+4*PI/3)*127+128 * 128 << 16 === 128 * (2 ** 16) */ x.fill() q[0] = q[1] // old point -> new q[0] q[1] = {x: k, y: n} // new point(k, n) -> new q[1] // constant line}function y(p) { var t = p + (z() * 2 - 1.1) * f return (t > h || t < 0) ? y(p) : t // y->[-1.1, 0.9)}document.onclick = ii()</script><style>html, body { overflow: hidden; margin: 0;}canvas { position: absolute; top: 0; left: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; /*pointer-events *DefaultValue: Auto *Inheritable: Yes *Animated: No *Computed: Appoint *Value: * auto * none--element will never be the target of mouse-events *Ins: *BasicSupport:IE(11.0+)FF(3.6+)Chrome(4.0+)Safari(6.0)Opera(15.0) */}</style></html>

技巧点

  1. 为了适应不同物理大小及缩放比例屏幕, 保证像素一致性:
  • 画布大小 = innerWidth * devicePixelRatio
  • canvas缩放变换 x.scale(devicePixelRatio, devicePixelRatio)
  1. 颜色区间取值算法
  • 颜色递减因子 r -= Math.PI * 2 / -50, 负的360度*五十分之一, 从1->0
  • x.fillStyle = ‘#‘ + (cos(r) * 127 + 128 << 16 | cos(r + Math.PI / 3) * 127 + 128 << 8 | cos(r + Math.PI / 3 * 2) * 127 + 128).toString(16)

随便取一组:

#fd334e#fb275d#f61c6d#ef137d#e60b8d#dc069d#d002ac#c401ba#b601c8#a703d4#9708e0#870ee9#7816f1#681ff7#582bfc#4937fe#3b45fe#2f53fd#2362f9#1972f4

调色是项艺术,自行追究.

  1. 三角形点算法
function y(p) { var t = p + (z() * 2 - 1.1) * f return (t > h || t < 0) ? y(p) : t // y->[-1.1, 0.9)}

相关文章