基于JavaScript實(shí)現(xiàn)新年賀卡特效
動(dòng)圖演示
一款超級(jí)炫酷的2022新年快樂(lè)html網(wǎng)頁(yè)特效,霓虹的城市夜景和絢爛的煙花很是特別,該html頁(yè)面還有交互效果,點(diǎn)擊鼠標(biāo)就會(huì)呈現(xiàn)煙花綻放的特效,唯美不過(guò)如此。圖片可以換成自己喜歡的夜景或人物都可以。?

主要代碼
圖片選擇引入:
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
font-family: Montserrat, sans-serif;
background-image: url(img/pexels-photo-219692.jpeg);
background-size: cover;
background-position: center;
}
css樣式
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
font-family: Montserrat, sans-serif;
background-image: url(img/pexels-photo-219692.jpeg);
background-size: cover;
background-position: center;
}
canvas {
mix-blend-mode: lighten;
cursor: pointer;
}
#hero {
display: inline;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
mix-blend-mode: color-dodge;
}
#year {
font-size: 30vw;
color: #d0d0d0;
font-weight: bold;
}
#timeleft {
color: #fbfbfb;
font-size: 2.5vw;
text-align: center;
font-family: Lora, serif;
}
Javascirpt
const canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
HalfPI = Math.PI / 2,
gravity = vector.create(0, 0.35),
year = document.getElementById('year'),
timeleft = document.getElementById('timeleft'),
newyear = new Date('01/01/2020');
let objects = [],
startFireworks = false,
newYearAlready = false;
function renderTimeLeft() {
let date = new Date();
let delta = Math.abs(newyear - date) / 1000;
let hours = Math.floor(delta / 3600) % 24;
delta -= hours * 3600;
let minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;
let seconds = Math.floor(delta % 60) + 1;
let string = '';
let DaysLeft = Math.floor((newyear - date) / (1000 * 60 * 60 * 24)),
HoursLeft = `${hours} ${hours > 1 ? 'hours' : 'hour'}`,
MinutesLeft = `${minutes} ${minutes > 1 ? 'minutes' : 'minute'}`,
SecondsLeft = `${seconds} ${seconds > 1 ? 'seconds' : 'second'}`;
if (hours > 0) string = `${HoursLeft} & ${MinutesLeft}`;else
if (minutes > 0) string = `${MinutesLeft} & ${SecondsLeft}`;else
string = `${SecondsLeft}`;
if (DaysLeft > 0) string = DaysLeft + ' days, ' + string;
string += ' until 2020';
timeleft.innerHTML = string;
}
renderTimeLeft();
setInterval(function () {
let date = new Date();
if (date >= newyear) {
if (!newYearAlready) {
year.innerHTML = '2022';
startFireworks = true;
timeleft.innerHTML = 'Happy New Year!';
}
newYearAlready = true;
} else renderTimeLeft();
}, 500);
document.body.appendChild(canvas);
function random255() {
return Math.floor(Math.random() * 100 + 155);
}
function randomColor() {
let r = random255(),
g = random255(),
b = random255();
return `rgb(${r}, ${g}, $)`;
}
class PhysicsBody {
constructor() {
objects.push(this);
}
PhysicsUpdate() {
this.lastPosition = this.position.duplicate();
this.position.addTo(this.velocity);
this.velocity.addTo(gravity);
}
deleteObject() {
objects[objects.indexOf(this)] = undefined;
}}
class firework extends PhysicsBody {
constructor() {
super();
this.position = vector.create(Math.random() * width, height);
let Velocity = vector.create(0, 0);
Velocity.setLength(Math.random() * 10 + 15);
Velocity.setAngle(Math.PI * 1.35 + Math.random() * Math.PI * 0.30);
this.velocity = Velocity;
this.trail = Math.floor(Math.random() * 4) != 1;
this.trailColor = this.trail ? randomColor() : undefined;
this.trailWidth = 2;
this.TimeCreated = new Date().getTime();
this.TimeExpired = this.TimeCreated + (Math.random() * 5 + 7) * 100;
this.BlastParticleCount = Math.floor(Math.random() * 50) + 25;
this.funky = Math.floor(Math.random() * 5) == 1;
this.exposionColor = randomColor();
}
draw() {
context.strokeStyle = this.trailColor;
context.lineWidth = this.trailWidth;
let p = this.position,
lp = this.lastPosition;
context.beginPath();
context.moveTo(lp.getX(), lp.getY());
context.lineTo(p.getX(), p.getY());
context.stroke();
}
funkyfire() {
var funky = this.funky;
for (var i = 0; i < Math.floor(Math.random() * 10); i++) {
new BlastParticle({ firework: this, funky });
}
}
explode() {
var funky = this.funky;
for (var i = 0; i < this.BlastParticleCount; i++) {
new BlastParticle({ firework: this, funky });
}
this.deleteObject();
}
checkExpire() {
let now = new Date().getTime();
if (now >= this.TimeExpired) this.explode();
}
render() {
if (this.trail) this.draw();
if (this.funky) this.funkyfire();
this.checkExpire();
}}
class BlastParticle extends PhysicsBody {
constructor({ firework, funky }) {
super();
this.position = firework.position.duplicate();
let Velocity = vector.create(0, 0);
if (!this.funky) {
Velocity.setLength(Math.random() * 6 + 2);
Velocity.setAngle(Math.random() * Math.PI * 2);
} else {
Velocity.setLength(Math.random() * 3 + 1);
Velocity.setAngle(firework.getAngle + Math.PI / 2 - Math.PI * 0.25 + Math.PI * .5);
}
this.velocity = Velocity;
this.color = firework.exposionColor;
this.particleSize = Math.random() * 4;
this.TimeCreated = new Date().getTime();
this.TimeExpired = this.TimeCreated + (Math.random() * 4 + 3.5) * 100;
}
draw() {
context.strokeStyle = this.color;
context.lineWidth = this.particleSize;
let p = this.position,
lp = this.lastPosition;
context.beginPath();
context.moveTo(lp.getX(), lp.getY());
context.lineTo(p.getX(), p.getY());
context.stroke();
}
checkExpire() {
let now = new Date().getTime();
if (now >= this.TimeExpired) this.deleteObject();
}
render() {
this.draw();
this.checkExpire();
}}
document.body.addEventListener('mousedown', function (e) {
let color = randomColor();
for (var i = 0; i < Math.floor(Math.random() * 20) + 25; i++) {
new BlastParticle({
firework: {
position: vector.create(e.pageX, e.pageY),
velocity: vector.create(0, 0),
exposionColor: color },
funky: false });
}
});
setInterval(function () {
if (!startFireworks) return;
for (var i = 0; i < Math.floor(Math.random() * 4); i++) {
new firework();
}
}, 500);
function cleanupObjects() {
objects = objects.filter(o => o != undefined);
}
function loop() {
context.fillStyle = 'rgba(0,0,0,0.085)';
context.fillRect(0, 0, width, height);
let unusedObjectCount = 0;
objects.map(o => {
if (!o) {unusedObjectCount++;return;}
o.PhysicsUpdate();
o.render();
});
if (unusedObjectCount > 100) cleanupObjects();
requestAnimationFrame(loop);
}
loop();
到此這篇關(guān)于基于JavaScript實(shí)現(xiàn)新年賀卡特效的文章就介紹到這了,更多相關(guān)JavaScript新年賀卡特效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js獲得當(dāng)前系統(tǒng)日期時(shí)間的方法
這篇文章主要介紹了js獲得當(dāng)前系統(tǒng)日期時(shí)間的方法,涉及javascript操作日期時(shí)間的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-05-05
JavaScript實(shí)現(xiàn)點(diǎn)擊出現(xiàn)子菜單效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)點(diǎn)擊出現(xiàn)子菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02
微信小程序動(dòng)態(tài)生成二維碼的實(shí)現(xiàn)代碼
這篇文章主要介紹了微信小程序動(dòng)態(tài)生成二維碼的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-07-07
bootstrap table表格客戶端分頁(yè)實(shí)例
這篇文章主要為大家詳細(xì)介紹了bootstrap table表格客戶端分頁(yè)實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
js showModalDialog 彈出對(duì)話框的簡(jiǎn)單實(shí)例(子窗體)
本篇文章主要是對(duì)js_showModalDialog彈出對(duì)話框的簡(jiǎn)單實(shí)例(子窗體) 進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01
JS數(shù)組操作大全對(duì)象數(shù)組根據(jù)某個(gè)相同的字段分組
這篇文章主要介紹了JS數(shù)組操作大全對(duì)象數(shù)組根據(jù)某個(gè)相同的字段分組,需要注意的是,在開發(fā)過(guò)程這種數(shù)組的處理函數(shù),應(yīng)當(dāng)被編寫到項(xiàng)目的公共工具函數(shù)庫(kù)中全局調(diào)用,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
OpenLayers3實(shí)現(xiàn)地圖鷹眼以及地圖比例尺的添加
這篇文章主要為大家詳細(xì)介紹了OpenLayers3實(shí)現(xiàn)地圖鷹眼以及地圖比例尺的添加,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
Javascript 正則表達(dá)式校驗(yàn)數(shù)字的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇Javascript 正則表達(dá)式校驗(yàn)數(shù)字的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
js改變img標(biāo)簽的src屬性在IE下沒(méi)反應(yīng)的解決方法
在Chrome FF里都能改變成功,但在IE下卻不行,網(wǎng)上搜了半天,大概了解了,這個(gè)是IE的一個(gè)bug,具體的解決方法如下,有類似問(wèn)題的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-07

