使用canvas實(shí)現(xiàn)鯉魚(yú)躍龍門(mén)的動(dòng)畫(huà)效果
廢話不多說(shuō),先看效果圖:

實(shí)現(xiàn)代碼與思路如下:
第一步 添加canvas畫(huà)布
<body style="background-color: rgb(216, 249, 250);margin: 0px;">
<canvas id="tutorial" width="1520" height="699"></canvas>
<div class="text">
<p>鯉魚(yú)躍龍門(mén)</p>
<p>沖呀!</p>
</div>
</body>
第二步 獲取canvas元素
let canvas = document.getElementById("tutorial");
//檢查支持性
if (canvas.getContext) {
var ctx = canvas.getContext("2d"); // 獲取渲染上下文
// ToDo ...
}
第三步 關(guān)于白云部分的繪制和動(dòng)畫(huà)
- 白云的繪制
用position數(shù)組統(tǒng)一設(shè)置白云的位置
var img = new Image();
img.src = "./public/cloud.svg";
var position = [{ x: 20, y: 520 }, { x: 350, y: 560 }, { x: 650, y: 490 }, { x: 930, y: 550 }, { x: 1230, y: 570 }]; //設(shè)置白云的位置
img.onload = function () {
// 開(kāi)始動(dòng)畫(huà)
for (let i = 0; i < position.length; i++) {
ctx.drawImage(img, position[i].x, position[i].y); // 每個(gè)圖片間隔300像素
}
};
- 白云的動(dòng)畫(huà)
整體的思路就是,結(jié)合周期定時(shí)器動(dòng)態(tài)設(shè)置globalAlpha屬性去控制元素的顯示與隱藏。
// 淡入淡出動(dòng)畫(huà)
function fadeInOut(index) {
var opacity = 1; // 初始透明度為1
var increasing = true;
// 每隔10毫秒執(zhí)行一次淡入淡出效果
var intervalId = setInterval(function () {
var randomNum = Math.random();
if (increasing) {
opacity += randomNum * 0.01; // 透明度逐漸增加
if (opacity >= 1) {
increasing = false; // 達(dá)到最大透明度后開(kāi)始減少
}
} else {
opacity -= randomNum * 0.01; // 透明度逐漸減小
if (opacity <= 0) {
// increasing = true;
clearInterval(intervalId); // 透明度減小到0后清除定時(shí)器
setTimeout(() => fadeInOut(index), 100); // 等待100ms后重新執(zhí)行淡入淡出
}
}
imageOpacities[index] = opacity; // 更新圖片透明度
drawImage(); // 重新繪制
}, 60);
}
// 繪制圖片
function drawImage() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save(); // 保存當(dāng)前繪制狀態(tài)
// 繪制之前的內(nèi)容
ctx.beginPath();
ctx.moveTo(75, 25);
//二次貝塞爾曲線
ctx.quadraticCurveTo(25, 25, 25, 62.5);
ctx.quadraticCurveTo(25, 100, 50, 100);
ctx.quadraticCurveTo(50, 120, 30, 125);
ctx.quadraticCurveTo(60, 120, 65, 100);
ctx.quadraticCurveTo(125, 100, 125, 62.5);
ctx.quadraticCurveTo(125, 25, 75, 25);
ctx.stroke();
ctx.drawImage(imgDoor, 250, -120);
// ctx.drawImage(imgFish, 1150, 450, 200, 200);
for (let i = 0; i < position.length; i++) {
ctx.globalAlpha = imageOpacities[i];
ctx.drawImage(img, position[i].x, position[i].y); // 每個(gè)圖片間隔300像素
}
// 繪制魚(yú)
ctx.globalAlpha = fishOpacity;
ctx.drawImage(imgFish, fishX, fishY, fishWidth, fishHeight);
ctx.globalAlpha = 1 - fishOpacity;
ctx.drawImage(imgDragon, 250, 100, 600, 600);
ctx.restore(); // 恢復(fù)之前保存的繪制狀態(tài)
}
//用處
img.onload = function () {
// 開(kāi)始動(dòng)畫(huà)
position.forEach((item, index) => {
fadeInOut(index);
});
};
第四步 關(guān)于魚(yú)的繪制和動(dòng)畫(huà)
// Fish 圖片的初始位置和大小
var fishX = 1150;
var fishY = 450;
var fishWidth = 200;
var fishHeight = 200;
// 魚(yú)的透明度
var fishOpacity = 1;
// 跳躍動(dòng)畫(huà)
function jumpAnimation() {
var startY = fishY;
var startx = fishX;
var maxHeight = startY - 150; // 魚(yú)的最高跳躍高度
var speed = 2; // 跳躍速度
var gravity = 0.1; // 重力加速度
var isRising = true; // 是否處于上升狀態(tài)
var jumpInterval = setInterval(function () {
// 魚(yú)上升
if (isRising) {
fishY -= speed;
fishX -= speed + 3;
if (fishY <= maxHeight) {
isRising = false;
}
}
// 魚(yú)下落
else {
fishY += speed;
fishX -= speed + 3;
if (fishY >= startY) {
clearInterval(jumpInterval);
// 開(kāi)始消失效果
fadeOut();
}
}
drawImage(); // 重新繪制魚(yú)
}, 30);
}
// 消失效果
function fadeOut() {
var opacityDecrement = 0.05; // 透明度減少的步長(zhǎng)
var fadeInterval = setInterval(function () {
fishOpacity -= opacityDecrement; // 透明度逐漸減小
if (fishOpacity <= 0) {
fishOpacity = 0;
clearInterval(fadeInterval);
}
drawImage(); // 重新繪制魚(yú)
}, 50);
}
//用處
imgFish.onload = function () {
// 圖片加載完成后開(kāi)始動(dòng)畫(huà)
setTimeout(function () {
jumpAnimation(); // 1秒后開(kāi)始跳躍動(dòng)畫(huà)
}, 1000);
};
第五步 關(guān)于對(duì)文字的樣式
<style>
.text {
position: absolute;
top: 28px;
left: 25px;
}
p {
text-align: center;
margin: 10px;
}
</style>
就這,over over ~
以上就是使用canvas實(shí)現(xiàn)鯉魚(yú)躍龍門(mén)的動(dòng)畫(huà)效果的詳細(xì)內(nèi)容,更多關(guān)于canvas鯉魚(yú)躍龍門(mén)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript reduce和reduceRight詳解
這篇文章主要介紹了JavaScript reduce和reduceRight的高級(jí)用法詳解的相關(guān)資料,需要的朋友可以參考下2016-10-10
D3.js的基礎(chǔ)部分之?dāng)?shù)組的處理數(shù)組的排序和求值(v3版本)
這篇文章主要介紹了D3.js的基礎(chǔ)部分之?dāng)?shù)組的處理數(shù)組的排序和求值(v3版本) ,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
淺談移動(dòng)端之js touch事件 手勢(shì)滑動(dòng)事件
這篇文章主要和大家聊一聊移動(dòng)端之js touch事件,即手指的滑動(dòng)事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
js實(shí)現(xiàn)快速分享功能(你的文章分享工具)
這是一款簡(jiǎn)單易用的文章分享工具,您只需將下面的html代碼拷貝到模板中就可以實(shí)現(xiàn)文章快速分享功能,具體的實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-06-06
淺談JS正則表達(dá)式的RegExp對(duì)象和括號(hào)的使用
下面小編就為大家?guī)?lái)一篇淺談JS正則表達(dá)式的RegExp對(duì)象和括號(hào)的使用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
小程序云開(kāi)發(fā)如何實(shí)現(xiàn)圖片上傳及發(fā)表文字
這篇文章主要為大家詳細(xì)介紹了小程序云開(kāi)發(fā)教程,如何實(shí)現(xiàn)圖片上傳及發(fā)表文字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
JavaScript判斷表單中多選框checkbox選中個(gè)數(shù)的方法
這篇文章主要介紹了JavaScript判斷表單中多選框checkbox選中個(gè)數(shù)的方法,涉及javascript針對(duì)checkbox復(fù)選框的遍歷與判斷技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08

