# 创意投稿大赛 龙年春节
废话不多说,先看效果图:
实现代码与思路如下:
第一步 添加canvas画布
html
<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元素
js
let canvas = document.getElementById("tutorial");
//检查支持性
if (canvas.getContext) {
var ctx = canvas.getContext("2d"); // 获取渲染上下文
// ToDo ...
}
第三步 关于白云部分的绘制和动画
- 白云的绘制
用position数组统一设置白云的位置
js
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 }]; //设置白云的位置
img.onload = function () {
// 开始动画
for (let i = 0; i < position.length; i++) {
ctx.drawImage(img, position[i].x, position[i].y); // 每个图片间隔300像素
}
};
- 白云的动画
整体的思路就是,结合周期定时器动态设置globalAlpha属性去控制元素的显示与隐藏。
js
// 淡入淡出动画
function fadeInOut(index) {
var opacity = 1; // 初始透明度为1
var increasing = true;
// 每隔10毫秒执行一次淡入淡出效果
var intervalId = setInterval(function () {
var randomNum = Math.random();
if (increasing) {
opacity += randomNum * 0.01; // 透明度逐渐增加
if (opacity >= 1) {
increasing = false; // 达到最大透明度后开始减少
}
} else {
opacity -= randomNum * 0.01; // 透明度逐渐减小
if (opacity <= 0) {
// increasing = true;
clearInterval(intervalId); // 透明度减小到0后清除定时器
setTimeout(() => fadeInOut(index), 100); // 等待100ms后重新执行淡入淡出
}
}
imageOpacities[index] = opacity; // 更新图片透明度
drawImage(); // 重新绘制
}, 60);
}
// 绘制图片
function drawImage() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save(); // 保存当前绘制状态
// 绘制之前的内容
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); // 每个图片间隔300像素
}
// 绘制鱼
ctx.globalAlpha = fishOpacity;
ctx.drawImage(imgFish, fishX, fishY, fishWidth, fishHeight);
ctx.globalAlpha = 1 - fishOpacity;
ctx.drawImage(imgDragon, 250, 100, 600, 600);
ctx.restore(); // 恢复之前保存的绘制状态
}
//用处
img.onload = function () {
// 开始动画
position.forEach((item, index) => {
fadeInOut(index);
});
};
第四步 关于鱼的绘制和动画
js
// Fish 图片的初始位置和大小
var fishX = 1150;
var fishY = 450;
var fishWidth = 200;
var fishHeight = 200;
// 鱼的透明度
var fishOpacity = 1;
// 跳跃动画
function jumpAnimation() {
var startY = fishY;
var startx = fishX;
var maxHeight = startY - 150; // 鱼的最高跳跃高度
var speed = 2; // 跳跃速度
var gravity = 0.1; // 重力加速度
var isRising = true; // 是否处于上升状态
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; // 透明度减少的步长
var fadeInterval = setInterval(function () {
fishOpacity -= opacityDecrement; // 透明度逐渐减小
if (fishOpacity <= 0) {
fishOpacity = 0;
clearInterval(fadeInterval);
}
drawImage(); // 重新绘制鱼
}, 50);
}
//用处
imgFish.onload = function () {
// 图片加载完成后开始动画
setTimeout(function () {
jumpAnimation(); // 1秒后开始跳跃动画
}, 1000);
};
第五步 关于对文字的样式
html
<style>
.text {
position: absolute;
top: 28px;
left: 25px;
}
p {
text-align: center;
margin: 10px;
}
</style>
就这,over over ~
祝大家新的一年 诸事顺遂 心想事成!