使用canvas實(shí)現(xiàn)鯉魚躍龍門的動(dòng)畫效果
廢話不多說,先看效果圖:
實(shí)現(xiàn)代碼與思路如下:
第一步 添加canvas畫布
<body style="background-color: rgb(216, 249, 250);margin: 0px;"> <canvas id="tutorial" width="1520" height="699"></canvas> <div class="text"> <p>鯉魚躍龍門</p> <p>沖呀!</p> </div> </body>
第二步 獲取canvas元素
let canvas = document.getElementById("tutorial"); //檢查支持性 if (canvas.getContext) { var ctx = canvas.getContext("2d"); // 獲取渲染上下文 // ToDo ... }
第三步 關(guān)于白云部分的繪制和動(dòng)畫
- 白云的繪制
用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 () { // 開始動(dòng)畫 for (let i = 0; i < position.length; i++) { ctx.drawImage(img, position[i].x, position[i].y); // 每個(gè)圖片間隔300像素 } };
- 白云的動(dòng)畫
整體的思路就是,結(jié)合周期定時(shí)器動(dòng)態(tài)設(shè)置globalAlpha屬性去控制元素的顯示與隱藏。
// 淡入淡出動(dòng)畫 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á)到最大透明度后開始減少 } } 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像素 } // 繪制魚 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 () { // 開始動(dòng)畫 position.forEach((item, index) => { fadeInOut(index); }); };
第四步 關(guān)于魚的繪制和動(dòng)畫
// Fish 圖片的初始位置和大小 var fishX = 1150; var fishY = 450; var fishWidth = 200; var fishHeight = 200; // 魚的透明度 var fishOpacity = 1; // 跳躍動(dòng)畫 function jumpAnimation() { var startY = fishY; var startx = fishX; var maxHeight = startY - 150; // 魚的最高跳躍高度 var speed = 2; // 跳躍速度 var gravity = 0.1; // 重力加速度 var isRising = true; // 是否處于上升狀態(tài) var jumpInterval = setInterval(function () { // 魚上升 if (isRising) { fishY -= speed; fishX -= speed + 3; if (fishY <= maxHeight) { isRising = false; } } // 魚下落 else { fishY += speed; fishX -= speed + 3; if (fishY >= startY) { clearInterval(jumpInterval); // 開始消失效果 fadeOut(); } } drawImage(); // 重新繪制魚 }, 30); } // 消失效果 function fadeOut() { var opacityDecrement = 0.05; // 透明度減少的步長(zhǎng) var fadeInterval = setInterval(function () { fishOpacity -= opacityDecrement; // 透明度逐漸減小 if (fishOpacity <= 0) { fishOpacity = 0; clearInterval(fadeInterval); } drawImage(); // 重新繪制魚 }, 50); } //用處 imgFish.onload = function () { // 圖片加載完成后開始動(dòng)畫 setTimeout(function () { jumpAnimation(); // 1秒后開始跳躍動(dòng)畫 }, 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)鯉魚躍龍門的動(dòng)畫效果的詳細(xì)內(nèi)容,更多關(guān)于canvas鯉魚躍龍門的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
es6?js?匹配兩個(gè)數(shù)組對(duì)象的方法
這篇文章主要介紹了es6?js?匹配兩個(gè)數(shù)組對(duì)象的方法,實(shí)例代碼介紹了判斷兩個(gè)數(shù)組用的value是否相等,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03JavaScript與DropDownList 區(qū)別分析
大家都知道,.NET中一些Web服務(wù)器控件解析并編譯,最終被渲染的時(shí)候,其實(shí)是轉(zhuǎn)化成了普通的html控件。2010-01-01一個(gè)js隨機(jī)顏色腳本(用于標(biāo)簽頁(yè)面,也可用于任何頁(yè)面)
一個(gè)js隨機(jī)顏色腳本(用于標(biāo)簽頁(yè)面,也可用于任何頁(yè)面)...2007-09-09七行JSON代碼把你的網(wǎng)站變成移動(dòng)應(yīng)用過程詳解
這篇文章主要介紹了七行JSON代碼把你的網(wǎng)站變成移動(dòng)應(yīng)用過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值2019-07-07ES6通過babel轉(zhuǎn)碼使用webpack使用import關(guān)鍵字
這篇文章主要介紹了es6通過babel轉(zhuǎn)碼還需要使用webpack才可以使用import關(guān)鍵字嗎的相關(guān)資料,需要的朋友可以參考下2016-12-12Ionic2系列之使用DeepLinker實(shí)現(xiàn)指定頁(yè)面URL
這篇文章主要介紹了Ionic2系列之使用DeepLinker實(shí)現(xiàn)指定頁(yè)面URL的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-119個(gè)JavaScript評(píng)級(jí)/投票插件
在訪問某個(gè)網(wǎng)站或者博客時(shí),如果該站點(diǎn)為用戶提供內(nèi)容的評(píng)級(jí)或投票功能的話,可以增強(qiáng)用戶參與的交互性之外,更可以給用戶一種“主人”的親切感,使得用戶可以切實(shí)地參與到網(wǎng)站內(nèi)容的評(píng)價(jià)體系中來(lái)。2010-01-01JS實(shí)現(xiàn)選中當(dāng)前菜單后高亮顯示的導(dǎo)航條效果
這篇文章主要介紹了JS實(shí)現(xiàn)選中當(dāng)前菜單后高亮顯示的導(dǎo)航條效果,涉及JavaScript針對(duì)頁(yè)面元素的遍歷及樣式動(dòng)態(tài)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10