夏天到了,西瓜配橙汁,来点小清新风格

165 阅读4分钟

本来想投稿夏天创意大赛的,可惜已经结束了,真是遗憾,本来可以拿个小奖啥的,最近是真的忙里忙外,忙得没谱了。

说到夏天,大家第一印象是啥呢?炎炎夏日,还是狂风骤雨?我的第一印象是这个:在凉爽的空调房里,抱着西瓜看剧玩游戏。确定是宅男无疑了,哥就喜欢这种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);

code.juejin.cn/pen/7112630…