canvas的练习

flyKot2025/03/10

初始化

const cvs = document.querySelector("canvas");
const ctx = cvs.getContext('2d');//设置为2d图形
cvs.height=window.InnerHeight;//设置高度
cvs.width=window.InnerWidth;//设置宽度

画个线条

    const cvs = document.querySelector("canvas");
    const ctx = cvs.getContext("2d")
    cvs.height = 300
    cvs.width = 300
	//画线↓
    ctx.beginPath()
    ctx.moveTo(10, 10)
    ctx.lineTo(50, 50)
    ctx.strokeStyle = "#ccc"
    ctx.stroke()

效果展示

画个矩形

    ctx.fillStyle = "#ccc";//设置填充颜色
    ctx.fillRect(10, 20, 50, 60)//在坐标点(10,20)画宽50,高60的矩形

效果展示

是不是非常简单

那么好,接下来就上点难度,嘿嘿

例一

效果展示

页面部分代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body,
        html {
            padding: 0;
            margin: 0;
            overflow: hidden;
        }

        canvas {
            image-rendering: auto;
            background-color: #000;
        }
    </style>
</head>

<body>
    <canvas></canvas>
    <script src="./index.js"></script>
</body>

</html>

功能部分

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext('2d');
function init() {
    // 获取设备像素比
    const scale = window.devicePixelRatio;

    // 设置canvas的实际大小(width和height)
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // 设置canvas的css样式
    canvas.style.width = `${window.innerWidth}px`;
    canvas.style.height = `${window.innerHeight}px`;

    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.globalCompositeOperation = 'source-over';

    new Graph(50, 350).draw();

}
class Graph {
    constructor(count = 60, maxDis = 550) {
        this.points = new Array(count).fill(0).map(() => new Point());
        this.maxDis = maxDis;
    }
    draw() {
        // 在浏览器下一次重绘之前调用指定的回调函数,以确保动画的流畅性和性能
        requestAnimationFrame(() => {
            this.draw();
        })
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (let i = 0; i < this.points.length; i++) {
            const p1 = this.points[i];
            p1.draw();
            for (let j = 0; j < this.points.length; j++) {
                const p2 = this.points[j];
                const d = Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
                if (d > this.maxDis) {
                    continue;
                }
                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);
                ctx.lineTo(p2.x, p2.y);
                ctx.closePath();
                ctx.strokeStyle = `rgba(200,200,200, ${1 - d / this.maxDis})`; // 根据小球之间距离决定颜色深浅
                // ctx.strokeStyle = '#ccc'
                ctx.stroke();
            }
        }
    }
}

class Point {

    constructor() {
        this.r = 5; // 半径
        this.x = getRadom(0, canvas.width - this.r / 2);  // x坐标
        this.y = getRadom(0, canvas.height - this.r / 2); // y坐标
        this.xSpeed = getRadom(-80, 80);   // x坐标移动速度
        this.ySpeed = getRadom(-80, 80);   // y坐标移动速度
        this.lastDrawTime = null;   // 上一次画的时间
    }

    draw() {
        // 更新坐标
        if (this.lastDrawTime) {
            // 计算新的坐标
            const duration = (Date.now() - this.lastDrawTime) / 1000;
            const xDis = this.xSpeed * duration;
            const yDis = this.ySpeed * duration;
            let x = this.x + xDis;
            let y = this.y + yDis;

            // 限制移动范围
            if (x > canvas.width - this.r / 2) {
                x = canvas.width - this.r / 2;
                this.xSpeed = -this.xSpeed;
            } else if (x < this.r / 2) {
                x = this.r / 2;
                this.xSpeed = -this.xSpeed;
            }
            if (y > canvas.height - this.r / 2) {
                y = canvas.height - this.r / 2;
                this.ySpeed = -this.ySpeed;
            } else if (y < this.r / 2) {
                y = this.r / 2;
                this.ySpeed = -this.ySpeed;
            }

            // 更新坐标
            this.x = x;
            this.y = y;
        }

        // 画小球
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
        ctx.fillStyle = '#fff'; // 小球颜色
        ctx.fill();
        this.lastDrawTime = Date.now(); // 记录这次绘画时间
    }
}

function getRadom(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.random() * (max - min + 1) + min;
}

// 在页面加载完成后初始化画布
window.onload = init;

// 监听窗口大小变化,以便动态调整画布大小
window.onresize = init;