本来想投稿夏天创意大赛的,可惜已经结束了,真是遗憾,本来可以拿个小奖啥的,最近是真的忙里忙外,忙得没谱了。
说到夏天,大家第一印象是啥呢?炎炎夏日,还是狂风骤雨?我的第一印象是这个:在凉爽的空调房里,抱着西瓜看剧玩游戏。确定是宅男无疑了,哥就喜欢这种feeling。哈哈
所以,本来想画个西瓜,试过用css画,感觉有点太繁琐了,就改用canvas。画着画着,还学习了贝塞尔曲线,真是各行各业都离不开数学呢。画完了西瓜,感觉有点太单调,就又突发奇想画了个杯子,杯子里面来点可乐?是的,一开始是可乐,不过配色完全毁了,于是改成了橙汁。
画了一个多小时画完,感觉好像还少了点啥,整个画面不够律动!于是又花了半个小时加了气泡动画,很粗糙啊,不过效果勉强达到了。
最后祝各位心想事橙,见者好运啦。拜拜~
代码在这里,大佬和萌新都可以看看,写得是很匆忙,有很多可以优化的余地,欢迎指正!
(function () {
const bubbles = [];
const bubblesQuantity = 15;
let body = document.body;
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx.fillStyle = "#84bf96";
ctx.fillRect(0, 0, canvas.width, canvas.height);
body.appendChild(canvas);
// 西瓜
addWatermelon();
// 杯子
addCup();
// 吸管
addStraw();
// 标题
addTitle();
function addWatermelon() {
// 创建渐变
let grd = ctx.createLinearGradient(500, 200, 300, 700);
grd.addColorStop(0, "#d93a49");
grd.addColorStop(1, "white");
//顶部三角区
ctx.lineWidth = 0.01;
ctx.fillStyle = grd;
ctx.strokeStyle = "#fff";
ctx.beginPath();
ctx.moveTo(500, 200);
ctx.lineTo(300, 600);
ctx.lineTo(800, 600);
ctx.closePath();
ctx.fill();
ctx.stroke();
// 底部扇区
ctx.beginPath();
ctx.strokeStyle = "#007d65";
ctx.lineWidth = 20;
ctx.lineCap = "round";
ctx.moveTo(310, 600);
ctx.quadraticCurveTo(500, 700, 800, 600);
ctx.fill();
ctx.stroke();
// 侧面
let grd1 = ctx.createLinearGradient(500, 210, 805, 600);
grd1.addColorStop(0, "#d93a49");
grd1.addColorStop(0.6, "#aa2116");
ctx.lineWidth = 0.01;
ctx.strokeStyle = "#fff";
ctx.fillStyle = grd1;
ctx.beginPath();
ctx.moveTo(500, 200);
ctx.lineTo(600, 200);
ctx.lineTo(900, 550);
ctx.lineTo(800, 600);
ctx.fill();
ctx.stroke();
// 中分线加强
let grd2 = ctx.createLinearGradient(500, 210, 805, 600);
grd2.addColorStop(0, "#d93a49");
grd2.addColorStop(0.6, "#aa2116");
ctx.fillStyle = grd2;
ctx.lineWidth = 0.1;
ctx.strokeStyle = "#d93a49";
ctx.beginPath();
ctx.moveTo(500, 210);
ctx.lineTo(800, 600);
ctx.lineTo(805, 590);
ctx.lineTo(505, 210);
ctx.closePath();
ctx.fill();
ctx.stroke();
// 侧面底部加粗
ctx.lineWidth = 20;
ctx.strokeStyle = "#007d65";
ctx.beginPath();
ctx.moveTo(890, 550);
ctx.lineTo(800, 600);
ctx.stroke();
// 西瓜籽
addWatermelonSeed(830, 500);
addWatermelonSeed(700, 430);
addWatermelonSeed(680, 350);
addWatermelonSeed(630, 250);
addWatermelonSeed(550, 250);
}
function addWatermelonSeed(x, y) {
ctx.strokeStyle = "#000";
ctx.fillStyle = "#345";
ctx.lineWidth = 1;
const a = 4 + Math.random() * 3,
b = 11 + Math.random() * 3;
const k = 0.5522848 + Math.random() * 0.25,
ox = a * k,
oy = b * k;
ctx.beginPath();
ctx.moveTo(x - a, y);
ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b);
ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y);
ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b);
ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
function addCup() {
ctx.beginPath();
ctx.strokeStyle = "#eee";
ctx.fillStyle = "#f6f5ec";
ctx.lineWidth = 2;
ctx.lineCap = "round";
ctx.beginPath();
ctx.moveTo(900, 200);
ctx.lineTo(950, 600);
ctx.lineTo(1200, 600);
ctx.lineTo(1250, 200);
ctx.lineTo(1230, 200);
ctx.lineTo(1170, 500);
ctx.lineTo(1150, 500);
ctx.lineTo(1150, 550);
ctx.lineTo(1000, 550);
ctx.lineTo(1000, 500);
ctx.lineTo(980, 500);
ctx.lineTo(920, 200);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = "#fffef9";
ctx.beginPath();
ctx.moveTo(920, 200);
ctx.lineTo(980, 500);
ctx.lineTo(1000, 500);
ctx.lineTo(1000, 550);
ctx.lineTo(1150, 550);
ctx.lineTo(1150, 500);
ctx.lineTo(1170, 500);
ctx.lineTo(1230, 200);
ctx.lineTo(1250, 200);
ctx.closePath();
ctx.fill();
ctx.stroke();
// 创建渐变
let grd = ctx.createLinearGradient(960, 200, 1150, 700);
grd.addColorStop(1, "orange");
grd.addColorStop(0, "white");
ctx.fillStyle = grd;
ctx.beginPath();
ctx.moveTo(960, 400);
ctx.lineTo(980, 500);
ctx.lineTo(1000, 500);
ctx.lineTo(1000, 550);
ctx.lineTo(1150, 550);
ctx.lineTo(1150, 500);
ctx.lineTo(1170, 500);
ctx.lineTo(1190, 400);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = "#ccc";
ctx.strokeStyle = "#eee";
ctx.font = "14px Georgia";
ctx.beginPath();
ctx.rect(1130, 210, 80, 25);
ctx.fillText("LocknLock", 1135, 230);
ctx.stroke();
addBubble();
}
function addBubble() {
ctx.fillStyle = "#fff";
ctx.beginPath();
ctx.fillRect(960, 380, 220, 20);
ctx.clearRect(980, 400, 180, 100);
ctx.lineWidth = 30;
ctx.lineCap = "butt";
ctx.beginPath();
ctx.strokeStyle = "#feeeed";
ctx.moveTo(1048, 375);
ctx.lineTo(1058, 410);
ctx.stroke();
let grd = ctx.createLinearGradient(960, 200, 1150, 700);
grd.addColorStop(1, "orange");
grd.addColorStop(0, "white");
ctx.fillStyle = grd;
ctx.strokeStyle = "#fff";
ctx.lineWidth = 0.01;
ctx.beginPath();
ctx.moveTo(960, 400);
ctx.lineTo(980, 500);
ctx.lineTo(1000, 500);
ctx.lineTo(1000, 550);
ctx.lineTo(1150, 550);
ctx.lineTo(1150, 500);
ctx.lineTo(1170, 500);
ctx.lineTo(1190, 400);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.strokeStyle = "#dea32c";
ctx.fillStyle = "#fff";
ctx.lineWidth = 0.01;
ctx.beginPath();
if (bubbles.length > 0) {
for (let i = 0; i < bubbles.length; i++) {
let bubble = bubbles[i];
if (bubble.y <= 395) {
bubbles.splice(i, 1, {
x: 980 + Math.random() * 200,
y: 405 + Math.random() * 50,
r: 2 + Math.random() * 2,
});
}
bubble.x =
Math.random() > 0.5
? bubble.x + Math.random() * 1
: bubble.x - Math.random() * 1;
bubble.y -= Math.random() * 5;
bubble.r =
Math.random() > 0.5 || bubble.r < 1
? bubble.r + Math.random() * 1
: bubble.r - Math.random() * 1;
ctx.arc(bubble.x, bubble.y, bubble.r, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
}
} else {
for (let i = 0; i < bubblesQuantity; i++) {
let x = 980 + Math.random() * 200;
let y = 405 + Math.random() * 50;
let r = 2 + Math.random() * 2;
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.stroke();
bubbles.push({ x, y, r });
}
}
}
function addStraw() {
ctx.lineWidth = 30;
ctx.lineCap = "butt";
ctx.lineJoin = "round";
ctx.beginPath();
ctx.strokeStyle = "#feeeed";
ctx.moveTo(800, 130);
ctx.lineTo(1000, 220);
ctx.lineTo(1100, 550);
ctx.stroke();
}
function addTitle() {
ctx.strokeStyle = "#7fb80e";
ctx.fillStyle = "#007947";
ctx.font = "30px Verdana";
ctx.lineWidth = 1;
ctx.lineCap = "round";
ctx.beginPath();
ctx.moveTo(180, 40);
ctx.lineTo(560, 40);
ctx.lineTo(560, 100);
ctx.lineTo(180, 100);
ctx.lineCap = "round";
ctx.closePath();
ctx.filter = "opacity(0.5)";
ctx.fill();
ctx.stroke();
ctx.fillStyle = "#fff";
ctx.strokeStyle = "#005831";
ctx.fillStyle = "#1d953f";
ctx.beginPath();
ctx.arc(200, 110, 10, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.arc(200, 110, 5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(240, 110, 10, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.arc(240, 110, 5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(500, 110, 10, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.arc(500, 110, 5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(540, 110, 10, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.arc(540, 110, 5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(580, 90, 6, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(600, 90, 5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(620, 90, 4, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.filter = "none";
ctx.fillStyle = "#eed";
ctx.beginPath();
ctx.fillText("祝心想事橙,见者好运~", 200, 80);
animation();
}
function animation() {
addBubble();
setTimeout(animation, 100);
}
})(window);