加载中...
  • canvas 实现彩虹画笔绘画板 loading

    项目效果

    效果预览

    涉及特性

    Canvas:

    • 模板骨架
    • 基本属性
      • getContext()
      • strokeStyle
      • fillStyle
      • fillRect
      • lineCap
      • lineJoin
    • 路径绘制
      • beginPath()
      • lineTo()
      • moveTo()

    鼠标事件处理:

    • mousemove
    • mousedown
    • mouseup
    • mouseout

    过程指南

    1. 获取 HTML 中的 <canvas> 元素,并设定宽度和高度
    2. .getContext('2d') 获取上下文,下面以 ctx 表示
    3. 设定 ctx 基本属性
      • 描边和线条颜色
      • 线条宽度
      • 线条末端形状
    4. 绘画效果
      1. 设定一个用于标记绘画状态的变量
      2. 鼠标事件监听,不同类型的事件将标记变量设为不同值
      3. 编写发生绘制时触发的函数,设定绘制路径起点、终点
    5. 线条彩虹渐变效果(运用 hsl 的 h 值的变化,累加)
    6. 线条粗细渐变效果(设定一个范围,当超出这个范围时,线条粗细进行逆向改变

    Canvas相关知识

    Canvas_API

    彩虹画笔绘画板简单介绍

    一、 模板骨架

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="UTF-8">
    <title>HTML5 Canvas 实现彩虹画笔绘画板</title>
    <style type="text/css">
    canvas {
    border: 1px solid black;
    }
    </style>
    </head>

    <body>
    <canvas id="canvas" width="150" height="150"></canvas>
    < script></ script>
    </body>

    </html>
    • < canvas> 元素
    1
    <canvas id="canvas" width="150" height="150"></canvas>

    canvas 看起来和 img 元素很相像,唯一的不同就是它并没有 srcalt 属性。实际上,canvas 标签只有两个属性——widthheight。这些都是可选的,并且同样利用 DOM properties 来设置。当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。该元素可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果CSS的尺寸与初始画布的比例不一致,它会出现扭曲。

    • 渲染上下文(The rendering context)
    1
    2
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    canvas元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。

    canvas起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。canvas元素有一个叫做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()只有一个参数,上下文的格式。对于2D图像而言,基本教程,你可以使用CanvasRenderingContext2D

    项目源码分析

    源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="UTF-8">
    <title>实现彩虹画笔绘画板😊</title>
    <style>
    * {
    margin: 0;
    padding: 0;
    }

    canvas {
    border: 1px solid black;
    }
    </style>
    </head>

    <body>
    <canvas id="canvas" width="1200" height="800"></canvas>

    < script type="text/javascript">
    // 获取canvas节点
    let canvas = document.querySelector('#canvas');
    let ctx = canvas.getContext("2d");

    let colorDeg = 0;
    let lineWidth = 50;
    let direction = true;
    // hsl 色相(0 - 360) 饱和度 明度
    ctx.strokeStyle = `hsl(${colorDeg}, 90%, 50%)`;
    ctx.lineWidth = `${lineWidth}`;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';

    let drawing = false;
    let [x, y] = [0, 0]
    function draw(e) {
    if (!drawing) return;
    ctx.beginPath();

    // 控制笔触大小
    colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
    if (lineWidth > 50 || lineWidth < 10) {
    direction = !direction
    }
    direction ? lineWidth++ : lineWidth--;
    ctx.lineWidth = `${lineWidth}`;

    // 彩虹效
    ctx.strokeStyle = `hsl(${colorDeg}, 90%, 50%)`;

    // 控制绘制路径
    ctx.moveTo(x, y);
    console.log(x, y);
    ctx.lineTo(e.offsetX, e.offsetY);
    [x, y] = [e.offsetX, e.offsetY];
    ctx.stroke();

    }
    canvas.addEventListener("mousedown", (e) => {
    drawing = true;
    // 括号,方括号,正则开头的斜杠,加号,减号,反引号 作为行首的时候必须要加分号
    [x, y] = [e.offsetX, e.offsetY]
    });
    canvas.addEventListener('mousemove', draw)
    canvas.addEventListener('mouseup', () => {
    drawing = false
    });
    canvas.addEventListener('mouseleave', () => {
    drawing = false
    })
    </ script>
    </body>

    </html>

    源码分析

    Canvas

    属性

    • lineCap:笔触的形状,有 round | butt | square 圆、平、方三种。
    • lineJoin:线条相交的样式,有 round | bevel | miter 圆交、斜交、斜接三种。
    • lineWidth:线条的宽度
    • strokeStyle:线条描边的颜色
    • fillStyle:填充的颜色

    方法

    • beginPath():新建一条路径
    • stroke():绘制轮廓
    • moveTo():(此次)绘制操作的起点
    • lineTo():路径的终点

    彩虹渐变颜色——HSL

    在这个挑战中,涉及到改变线条的颜色,如何实现彩虹的渐变效果?我们需要利用 HSL 色彩模式,首先可以去这个网站 http://mothereffinghsl.com 感受一下 HSL 不同色彩值对应的效果。

    • H(hue) 代表色调,取值为 0~360,专业术语叫色相
    • S 是饱和度,可以理解为掺杂进去的灰度值,取值为 0~1
    • L 则是亮度,取值也是 0~1,或者百分比。

    这之中 H 值从 0 到 360 的变化代表了色相的角度的值域变化,利用这一点就可以实现绘制时线条颜色的渐变了,只需要在它的值超过 360 时恢复到 0 重新累加即可。

    1
    2
    3
    4
    let colorDeg = 0;

    ctx.strokeStyle = `hsl(${ colorDeg }, 90%, 50%)`;
    colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;

    除此之外,如果想实现黑白水墨的颜色,可以将颜色设置为黑色,通过透明度的改变来实现深浅不一的颜色。

    控制笔触大小

    1
    2
    3
    4
    5
    6
    //		控制笔触大小
    if (lineWidth > 50 || lineWidth < 10) {
    direction = !direction
    }
    direction ? lineWidth++ : lineWidth--;
    ctx.lineWidth = `${lineWidth}`;

    上面的代码中,根据线条的宽度的变化来控制direction的值,根据direction的值来控制线宽是增加还是减少。

    控制线条路径

    1
    2
    3
    4
    5
    6
    7
       // 控制绘制路径
    ctx.beginPath();
    ctx.moveTo(x, y);
    console.log(x, y);
    ctx.lineTo(e.offsetX, e.offsetY);
    [x, y] = [e.offsetX, e.offsetY];
    ctx.stroke();

    事件监听代码逻辑分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    canvas.addEventListener('mousedown', (e) => {
    // 开始绘图
    drawing = true;
    // 绘图起始坐标初始化
    [x, y] = [e.offsetX, e.offsetY]
    });

    // 鼠标移动时,调用draw方法
    canvas.addEventListener('mousemove', draw);
    // 鼠标抬起时,将drawing置为false
    canvas.addEventListener('mouseup', () => drawing = false);
    // 当鼠标不在可绘图区域范围内时,将drawing置为false
    canvas.addEventListener('mouseout', () => drawing = false);
    上一篇:
    audio 爵士鼓音乐敲击特效
    下一篇:
    理解 ES6 的 Map 数据结构
    本文目录
    本文目录