孔明灯特效源码
一个有意思的小玩意儿,孔明灯<div class="moon"></div>
<style>
@keyframes rotateAnimationX {
0% {
transform: rotateX(0deg) rotateZ(0deg);
}
25% {
transform: rotateX(5deg) rotateZ(5deg);
}
50% {
transform: rotateX(0deg) rotateZ(0deg);
}
75% {
transform: rotateX(-5deg) rotateZ(-5deg);
}
100% {
transform: rotateX(0deg) rotateZ(0deg);
}
}
@keyframes rotateAnimationY {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
@keyframes shape {
0% {
background: radial-gradient(at 50% 90%, yellow 10%, #ffae00 40%, red);
}
50% {
background: radial-gradient(at 50% 90%, yellow 20%, #ffae00 50%, red);
}
100% {
background: radial-gradient(at 50% 90%, yellow 10%, #ffae00 40%, red);
}
}
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
background: linear-gradient(to bottom, #000022, #000033);
}
.moon {
width: 200px;
height: 200px;
border-radius: 50%;
background: radial-gradient(circle at center, #f6f6f6, #e5e5e5);
box-shadow: 0 0 30px 10px rgba(255, 255, 255, 0.5);
position: absolute;
top: 100px;
left: 300px;
}
</style>
<script>
var blessings = [
"心想事成",
"平安健康",
"万事如意",
"吉祥如意",
"阖家欢乐",
"财源广进",
];
class Light {
constructor(s) {
const w = 200,
h = 400;
this.scale = s;
this.lightWidth = w;
this.lightHeight = h;
this.faceWidth = this.lightWidth / 2;
this.faceHeight = this.lightHeight / 2;
this.faceTop = 0;
this.sin60Width = this.faceWidth * Math.sin(60 * (Math.PI / 180));
this.faceCenter = this.lightWidth / 2 - this.faceWidth / 2;
this.fireWidth = this.faceWidth * 0.4;
this.fireHeight = this.fireWidth * 2;
this.isUpdate = true;
this.isRotate = this.scale > .4 ? true : false;
this.init();
}
init() {
const wrap = this.initWrap();
const light = this.initLight();
const fire = this.initFire();
wrap.appendChild(light);
light.appendChild(fire);
const body = document.getElementsByTagName("body");
body.appendChild(wrap);
}
initWrap() {
const wrap = document.createElement("div");
wrap.className = "light-wrap";
wrap.style.position = "fixed";
wrap.style.zIndex = this.lightHeight + this.lightWidth;
let top = parseInt(Math.random() * window.innerHeight);
let left = parseInt(Math.random() * window.innerWidth);
wrap.style.top = top + "px";
wrap.style.left = left + "px";
wrap.style.transform = `scale(${this.scale})`
wrap.style.height = this.lightHeight + "px";
wrap.style.width = this.lightWidth + "px";
const update = () => {
const step = 0.2;
top - step * 2 > -this.lightHeight
? (top -= step * 2)
: (top = window.innerHeight);
left - step > -this.lightWidth
? (left -= step)
: (left = window.innerHeight);
wrap.style.top = top + "px";
wrap.style.left = left + "px";
setTimeout(update, 1000 / 30);
};
if (this.isUpdate) {
update();
}
return wrap;
}
initLight() {
const light = document.createElement("div");
light.className = "light";
light.style.height = this.lightHeight + "px";
light.style.width = this.lightWidth + "px";
light.style.position = "relative";
light.style.perspective = this.faceWidth * 10 + "px";
light.style.perspectiveOrigin = `center ${this.lightHeight / 2}px`;
light.style.transformStyle = "preserve-3d";
light.style.position = "relative";
light.style.animation = `rotateAnimationX ${
parseInt(Math.random() * 10) + 5
}s linear infinite`;
for (let i = 0; i < 6; i++) {
const face = this.initFace(i * 60, i);
light.appendChild(face);
}
return light;
}
initFace(deg, _i) {
const face = document.createElement("div");
face.className = "face";
face.style.height = this.faceHeight + "px";
face.style.width = this.faceWidth + "px";
face.style.transformStyle = "preserve-3d";
face.style.position = "absolute";
face.style.top = 0;
face.style.left = this.faceCenter + "px";
face.style.transformOrigin = `50% 50% ${this.sin60Width}px`;
face.style.transform = `translateZ(${
-1 * this.sin60Width
}px) rotateY(${deg}deg)`;
const rotate = () => {
deg++;
face.style.transform = `translateZ(${
-1 * this.sin60Width
}px) rotateY(${deg}deg)`;
setTimeout(rotate, 1000 / 30);
};
this.isRotate && rotate();
const faceTop = this.initFaceTop();
const faceSqure = this.initFaceSqure(_i);
const faceLine = this.initFaceLine();
face.appendChild(faceTop);
face.appendChild(faceSqure);
face.appendChild(faceLine);
return face;
}
initFaceTop() {
const faceTop = document.createElement("div");
faceTop.className = "face-top";
faceTop.style.width = this.faceWidth + "px";
faceTop.style.height =
this.sin60Width / Math.cos(30 * (Math.PI / 180)) + "px";
faceTop.style.background = `radial-gradient(at 50% 90%, yellow 10%, #ffae00 40%, red)`;
faceTop.style.transform = `rotateX(-60deg)`;
faceTop.style.transformOrigin = `0 100%`;
faceTop.style.clipPath = `polygon(50% 0%, 0% 100%, 100% 100%)`;
return faceTop;
}
initFaceSqure(_i) {
const faceSqure = document.createElement("div");
faceSqure.className = "face-squre";
faceSqure.style.height = this.faceHeight + "px";
faceSqure.style.width = this.faceWidth + "px";
faceSqure.style.background = `radial-gradient(at 50% 70%, #0d0034 10%, #381460 40%, red)`;
faceSqure.style.animation = `shape 2s linear infinite`;
const word = this.initWord(_i);
faceSqure.appendChild(word);
return faceSqure;
}
initWord(_i) {
const word = document.createElement("div");
word.className = "word";
word.innerText = blessings;
word.style.height = "100%";
word.style.width = "100%";
word.style.textAlign = "center";
word.style.writingMode = "vertical-rl";
word.style.lineHeight = this.faceWidth + "px";
word.style.transform = "scaleX(-1)";
word.style.letterSpacing = "2px";
word.style.fontFamily = "楷体";
word.style.fontWeight = "bold";
word.style.userSelect = 'none'
word.style.color = 'rgb(126 0 0)'
word.style.fontSize = parseInt(this.faceWidth / 4) + "px";
return word;
}
initFaceLine() {
const faceLine = document.createElement("div");
faceLine.className = "face-line";
faceLine.style.width = this.faceWidth + "px";
faceLine.style.height =
this.sin60Width / Math.cos(30 * (Math.PI / 180)) + "px";
faceLine.style.background = `linear-gradient(to right, transparent 48%, black 48%, transparent 52%)`;
faceLine.style.transform = `rotateX(60deg)`;
faceLine.style.transformOrigin = `0 0`;
return faceLine;
}
initFire() {
const fire = document.createElement("div");
fire.className = "fire";
fire.style.position = `absolute`;
fire.style.top =
this.faceHeight + this.faceWidth - 0.2 * this.faceWidth + "px";
fire.style.left = this.lightWidth / 2 - this.fireWidth / 2 + "px";
fire.style.width = this.fireWidth + "px";
fire.style.height = this.fireHeight + "px";
fire.style.perspective = this.faceWidth * 10 + "px";
fire.style.perspectiveOrigin = `center ${this.faceHeight}px`;
fire.style.transformStyle = `preserve-3d`;
const firEItem = this.initFireItem(30);
fire.appendChild(firEItem);
return fire;
}
initFireItem(d) {
const fireItem = document.createElement("div");
fireItem.style.position = `absolute`;
fireItem.style.height = `100%`;
fireItem.style.width = `100%`;
fireItem.style.background = `radial-gradient(at 50% 80%, yellow 10%, #8B0000 20%, transparent 40%, transparent)`;
fireItem.style.transform = `rotateY(${d}deg)`;
return fireItem;
}
}
const lightList = []
for (let i = 0; i < 18; i++) {
lightList.push(Math.random() * (.8 - .2) + .2)
}
lightList.sort().forEach(i => new Light(i))
</script>
页:
[1]