# CSS魔术师Houdini
这一块写的有点简陋了,有时间再补一补 demo1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.el{
--elUnit:500px;
height:var(--elUnit);
width: var(--elUnit);
--arcColor:yellowgreen;
--background-canvas: (ctx,geom)=>{
ctx.strokeStyle = `var(--arcColor)`;
ctx.lineWidth = 4;
ctx.beginPath();
ctx.arc(200,200,50,0,2*Math.PI);
ctx.stroke();
ctx.closePath();
};
background: paint(background-canvas);
}
</style>
</head>
<body>
<div class="el"></div>
<script>
if (CSS in window || !CSS.paintWorklet) {
console.error('您的浏览器不支持houdini');
} else {
CSS.paintWorklet.addModule('./arc.js');
}
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
art.js
registerPaint('background-canvas',class {
static get inputProperties() {
return ['--background-canvas'];
}
paint(ctx,geom,properties) {
eval(properties.get('--background-canvas').toString())(ctx,geom,properties)
}
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
demo2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body{
background: #000;
color:#fff;
}
body::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
--star-density:1;
--star-opacity:1;
background-image:paint(yd-sky);
animation: shine 1s linear alternate infinite;
}
@keyframes shine {
from{
opacity: 1;
}
to{
opacity: 0.2;
}
}
</style>
</head>
<body>
<script>
if (CSS in window || !CSS.paintWorklet) {
console.error('您的浏览器不支持houdini');
} else {
CSS.paintWorklet.addModule('./sky.js');
}
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
sky.js
registerPaint('yd-sky',class {
constructor() {
this.stars = [];
}
static get inputProperties() {
return ['--star-density','--star-opacity'];
}
addStars(xMax, yMax, starDensity) {
let starsNum = Math.round((xMax + yMax) * starDensity);
for( let i = 0; i <= starsNum; i++) {
const x = Math.floor(Math.random()*xMax + 1);
const y = Math.floor(Math.random()*xMax + 1);
const hue = Math.floor(Math.random()*360 + 1);
const opacityOne = Math.floor(Math.random()*9 + 1);
const opacityTwo = Math.floor(Math.random()*9 + 1);
const size = Math.floor(Math.random()*2 + 1);
this.stars.push(
{x,y,hue,opacityOne,opacityTwo,size}
)
}
}
paint(ctx,geom,properties) {
let xMax = geom.width;
let yMax = geom.height;
let starDensity = properties.get('--star-density');
let starOpacity = properties.get('--star-opacity');
ctx.fillRect(0,0,xMax,yMax);
this.addStars(xMax, yMax, starDensity);
const stars = this.stars;
for(let star of stars) {
const opacity = ('.' + (star.opacityOne + star.opacityTwo))*starOpacity
ctx.fillStyle = `hsla(${star.hue},30%,80%,${opacity})`;
ctx.fillRect(star.x, star.y, star.size, star.size);
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36