认识一下 canvas,体验一下它的魅力

在我们开始探索一门新的技术的时候,要以更高的角度来看一下这门技术能解决什么问题。

我觉得这样说应该不为过吧!CSS + HTML 能做的事情,canvas 都能做,而 canvas 能做的事情,CSS + HTML 却不一定能做。

那 canvas 究竟能做什么?

canvas 的本质是 HTML 中的一个标签、一个 HTML 元素:

<canvas id="canvas"></canvas>

使用 JavaScript 可以从 canvas 元素中获得一块「画布」(绘图上下文),可以是 2d 的也可以是 3d 的,有了画布以后,画家(程序员)就可以通过画笔(代码)进行绘制大好河山,发挥自己的想象。

使用 canvas 能够做:

1、动画,做一些炫酷的动画

2、游戏

3、数据可视化,比如 Echarts 做的可视化大屏;

4、图像处理;

5、实时视频处理;

总的来说 canvas 能做的事情很多。我们用代码感受一下 canvas。特别强调一下,关于 canvas 所有内容都是通过 TS 实现,好处是使用 TS 能够享受到智能提示。我在 demo 中也使用了 vite,写起来比较方便。

本节内容我们实现的效果是这样的:

完成上面的效果需要做几件事情,我直接上代码:

代码中共用的一些变量:

const parentId = 'canvas-warp';
const canvasWidth = 400;
const canvasHeight = 400;
// 网格线间距
const gridSpace = 40;
const lineColor = '#cec';
let dprValue = window.devicePixelRatio || 1;

1、创建一个 canvas 元素;

与创建其它 DOM 元素一样,直接使用 DOM 相关的API 即可。canvas 可以直接设置 width 和 height 属性,表示画布的宽高,dprValue 主要为了解决清晰度的。而通过 canvas.style.width 设置的是 CSS 的属性,只会影响 canvas 元素在网页中的布局和样式,不会影响画布的大小。

const createACanvas = () => {
    let canvas = document.createElement('canvas') as HTMLCanvasElement;
    // 设置画布的宽度
    canvas.width = canvasWidth * dprValue;
    // 设置画布的高度
    canvas.height = canvasHeight * dprValue;
    // 设置画布的 CSS 样式
    canvas.style.width = `${canvasWidth}px`;
    canvas.style.height = `${canvasHeight}px`;
    canvas.style.backgroundColor = '#fff';
    canvas.style.marginLeft = '40px';
    canvas.style.marginTop = '40px';
    return canvas;
}

2、画一个网格,并标记网格对应的坐标值;

画网格线的思路,在 x 和 y 方向上画不同的线即可,并在线的顶点处画坐标值即可。

const drawGrid = (ctx: CanvasRenderingContext2D) => {
    let xCount = canvasHeight / gridSpace;
    let yCount = canvasWidth / gridSpace;


    const drawValue = (i, isX) => {
        ctx.font = '12px';
        ctx.textAlign = 'left';
        ctx.textBaseline = 'top';
        ctx.fillStyle = '#222';
        if (isX) {
            ctx.fillText(`${i * gridSpace}`, 0, gridSpace * i);
        }
        else {
            ctx.fillText(`${i * gridSpace}`, gridSpace * i, 0);
        }
    }


    for (let i = 0; i < xCount; i++) {
        ctx.beginPath();
        ctx.moveTo(0, gridSpace * i);
        ctx.lineTo(canvasWidth, gridSpace * i);
        ctx.strokeStyle = lineColor;
        ctx.lineWidth = 1;
        ctx.stroke();
        drawValue(i, true);
    }


    for (let i = 0; i < yCount; i++) {
        ctx.beginPath();
        ctx.moveTo(gridSpace * i, 0);
        ctx.lineTo(gridSpace * i, canvasHeight);
        ctx.strokeStyle = lineColor;
        ctx.lineWidth = 1;
        ctx.stroke();


        drawValue(i, false);
    }
};

3、画一个矩形区域

const drawReact = (ctx: CanvasRenderingContext2D) => {
    ctx.fillStyle = 'blue';
    ctx.fillRect(40, 40, 120, 80);
}

最后,把各个步骤连起来就能看到最终的效果:



// 1. 创建 canvas
let canvas = createACanvas();


let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
ctx.setTransform(dprValue, 0, 0, dprValue, 0, 0);


// 2. 画网格
drawGrid(ctx);


// 3. 把 canvas 添加到 DOM 节点中
let parentDom = document.getElementById(parentId);
parentDom.appendChild(canvas);


// 4. 在画布中画一个矩形区域
drawReact(ctx);

上面的内容可能你看不懂,没关系,后面我们会逐步学习各个 API 的作用,大家加油!demo 地址:

https://github.com/lefex/FE/tree/master/learn-canvas

长按关注

素燕《前端小课》

帮助 10W 人入门并进阶前端

官网:https://lefex.gitee.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值