尤雨溪网站三角彩带效果
效果:
源码
<!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.cos
c.width = w * pr
c.height = h * pr
x.scale(pr, pr) // Synchronization with devicePixelRatio
x.globalAlpha = 0.6 // gloabalAlpha set or return the opacity-value of draw
function 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 = i
i()
</script>
<style>
html, body {
overflow: hidden;
margin: 0;
}
canvas {
position: absolute;
top: 0;
left: 0;
z-index: 0;
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>
技巧点
- 为了适应不同物理大小及缩放比例屏幕, 保证像素一致性:
- 画布大小 = innerWidth * devicePixelRatio
- canvas缩放变换 x.scale(devicePixelRatio, devicePixelRatio)
- 颜色区间取值算法
- 颜色递减因子
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
调色是项艺术,自行追究.
- 三角形点算法
function y(p) {
var t = p + (z() * 2 - 1.1) * f
return (t > h || t < 0) ? y(p) : t
// y->[-1.1, 0.9)
}