Day02 - 用 canvas 做渐变色涂鸦笔

今天想做色彩渐变,角色很单纯只有笔刷一位,预计做出的效果是在网页上用滑鼠涂色,让笔刷跟着滑鼠游标移动,并且滑鼠移动时记录当下的笔刷位子(其实也就是当下的滑鼠的位子),让滑鼠经过的地方都留下笔刷的痕迹

https://ithelp.ithome.com.tw/upload/images/20210917/20140513uxg73ecglj.jpg

工具

// 今天一样建立 Vector 当做存位子的工具
//((虽然这个练习很迷你,其实不用特别建 Vector
var Vector = function (x, y) {
    this.x = x;
    this.y = y;
};

角色
笔刷

// 笔刷
// 因为想让笔刷使用跟舞台同一个 canvas 所以预留一个 ctx 参数,等等舞台邀请角色上台时传入
var Pen = function (ctx){
    this.ctx = ctx;
    this.pos = new Vector(500,200);
    this.r = 60;
    this.rgb = [232, 167, 167];
    this.color = `(${this.rgb[0]},${this.rgb[1]},${this.rgb[2]})`;
};

舞台
角色预设就在舞台上,并设定舞台的初始化

var Game = function () {
    this.infectCanvas = document.getElementById('infectCanvas')
    this.ctx = infectCanvas.getContext('2d');
    
    // 欢迎主角 Pen 上台
    this.pen = new Pen(this.ctx);
    
    // 装所有 pens
    this.pens = [];
    
    // 预计让这个 t 会随着每次执行 update 时上升,等等在 update function 见
    this.t = 0;
    this.init();
    
};
Game.prototype.init = function(){
    this.infectCanvas.width = window.innerWidth;
    this.infectCanvas.height = window.innerHeight;
    // 初始化记得要 render 画面、update 资料
    this.render();
    this.update();
};

设定 render 函数将画舞台布景与角色画到 canvas 上

Game.prototype.render = function () {
    this.ctx.beginPath();
    this.ctx.fillStyle = '#ebc5c5';
    this.ctx.fillRect(0, 0, this.infectCanvas.width, this.infectCanvas.height);

    // pens
    // 在 canvas 画布画出每个笔刷经过的位子
    this.pens.forEach((pen) => {
        this.ctx.beginPath();
        this.ctx.fillStyle = pen.color;
        this.ctx.arc(pen.pos.x, pen.pos.y, this.pen.r, 0, Math.PI * 2);
        this.ctx.fill();
    })
    
    // 重复 render 画面
    requestAnimationFrame(()=>this.render())
};

本日渐变色重头戏!
透过时间更新 rgb 三色彩数值之一起向 google color picker 学习渐变色

我先透过观察 google color picker,当我初始颜色为 rgb(232,167,167) 时,拖移 google color picker 拉吧,会发现颜色一开始 rgb(232,167,167) 的 r 与 b 都不变,只有 g 从 167 上升到 232,也就是整体变成rgb(232,167,167)

接着换 g 与 b 都不变,r 从 232 一路下降到 167,一路拖移 color picker 的拉吧找出渐变的规律
https://ithelp.ithome.com.tw/upload/images/20210917/20140513JPEiKPzFOl.jpg


Game.prototype.update = function() {
    // 每更新一次资料 t 就加一
    this.t++;
    
    // 因为我们用重复执行 update 的频率很高,所以设个 ts 作为低频一点的数字
    this.ts = parseInt(this.t/3);

    // 以下出现 65 与 390 的原因就是透过 color picker 啦吧拖曳
    //发现色彩数值每次上升/下降的幅度都是 65,而且总共有六段的上升/下降
    // 所以 65*6 = 390,以 390 为一个循环
    // ts 每过多 390,其 ts%390 这里的余数就又从 0 开始上升,让渐变色循环更新
    
    // 从 rgb(232,167,167) 到 rgb(232,232,167)
    if (this.ts%390 <65){
        this.pen.rgb[1] += 1;

    // 从 rgb(232,232,167) 到 rgb(167,232,167)
    }else if (this.ts%390 >65 && this.ts%390 <65*2 ){
        this.pen.rgb[0] -= 1;
    }
    // 从 rgb(167,232,167) 到 rgb(167,232,232)
    else if (this.ts%390 >65*2 && this.ts%390 <65*3 ){
        this.pen.rgb[2] += 1;
    }
    // 从 rgb(167,232,232) 到 rgb(167,167,232)
    else if (this.ts%390 >65*3 && this.ts%390 <65*4 ){
        this.pen.rgb[1] -= 1;
    }
    // 从 rgb(167,167,232) 到 rgb(232,167,232)
    else if (this.ts%390 >65*4 && this.ts%390 <65*5 ){
        this.pen.rgb[0] += 1;
    }
    // 从 rgb(232,167,232) 到 rgb(232,167,167)
    else if (this.ts%390 >65*5 && this.ts%390 <=65*6 ){
        this.pen.rgb[2] -= 1;
    }
    this.pen.color = `rgb(${this.pen.rgb[0]}, ${this.pen.rgb[1]}, ${this.pen.rgb[2]})`;

    // 重复更新资料
    setTimeout(()=>this.update());
};

// 要建立舞台游戏才会开始喔
var game = new Game()

mouse event

game.infectCanvas.addEventListener('mousemove',function(e) {
    game.pen.pos = new Vector(e.x, e.y);
    game.pens.push({
        pos: game.pen.pos,
        color: game.pen.color,
    });
})

之後再来认真看网路上的大大做的渐变效果 Animated Background Gradient


如果理解有误的地方,或有其他渐变色产出方式,都希望路过的朋友能提点提点交流交流啦 ε= ᕕ( ᐛ )ᕗ


<<:  做为应徵者,如何回应技术题?

>>:  Day02 - this&Object Prototypes Ch3 Objects - Contents - Array

GitHub DevOps 流程参考实现

在这篇文章,我们来讨论 GitHub 与 DevOps 之间的关系,我们将从各种角度来讨论,GitH...

Day16 CSS Specificity 样式拍卖会

权重的概念让我联想到拍卖会,HTML元素的样式就像是拍卖会上被竞标的商品,而选择器们就像是竞标的买...

【Day 18】 实作 - 透过 AWS 服务 Glue Crawler 自动建立 VPC Log 资料表

大家午安 ~ 昨天我们已经启用 VPC Flow Log 并且存放到 S3,今天我们会设定 AWS ...

css display

昨天有说到div因为block这个元素而占了整行无法并排,今天就来说一下block是甚麽样的元素 d...

Day 26 Wireless Attacks - 无线攻击 (aircrack-ng)

前言 终於进入新的篇章06-Wireless Attacks,但由於先前的Kali虚拟机环境无法进行...