canvas模拟输入框输入

本文档展示了一个使用HTML5 Canvas实现的文本输入光标闪烁效果。通过JavaScript创建了一个类`InterPoint`,该类用于处理光标的绘制、颜色更新、清除和闪烁效果。当用户按下键盘键时,会更新输入文本,并即时刷新光标位置。此外,按退格键时会删除最后一个字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请添加图片描述
功能:
停止输入时插入点闪烁 输入时插入点更新

<!DOCTYPE html>
<html lang="zn-ch">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        canvas {
            border: 1px solid #51f;
        }
    </style>
</head>

<body>
    <!-- <canvas  width="500" height="500"></canvas> -->
    <script>
        const canvas = document.createElement("canvas");
        document.body.appendChild(canvas);
        const width = 700;
        const height = 500;
        const fontSize = 18;
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext("2d");

        const point = [0, height / 2];
        let inputs = [""];

        class InterPoint {
            timer;
            prevInterPoint = [0, 0];
            lineColor = '#51f';
            constructor(ctx, lineWidth, lineHength, delay) {
                this.ctx = ctx;
                this.lineHength = lineHength;
                this.lineWidth = lineWidth;
                this.delay = delay;
                this.drawInsetPoint(true);
            }
            /**
            * 更新线条颜色
            */
            setLineColor(lineColor) {
                this.lineColor = lineColor;
            }

            /**
            * 画垂直的直线
            */
            drawVerticalLine = (x, y, height) => {
                this.ctx.beginPath();
                this.ctx.lineWidth = this.lineWidth;
                this.ctx.moveTo(x, y);
                this.ctx.lineTo(x, y + height);
                this.ctx.strokeStyle = this.lineColor;
                this.ctx.stroke();
                this.ctx.closePath();
            }
            /**
            * 更新插入点坐标
            */
            updateInterPoint() {
                const x = this.ctx.measureText(inputs[inputs.length - 1]).width + 4;
                const y = (inputs.length - 1) * this.lineHength + height / 2;
                this.prevInterPoint = [x, y]
            }
            /**
            * 清除插入点
            */
            clear() {
                this.ctx.clearRect(this.prevInterPoint[0] - this.lineWidth / 2 - 1, this.prevInterPoint[1], this.prevInterPoint[0] + this.lineWidth, this.prevInterPoint[1] + this.lineHength);
            }

            /**
            * 循环 绘制插入点 添加闪烁行为
            */
            drawInsetPoint(state) {
                if (state) {
                    this.updateInterPoint();
                    this.drawVerticalLine(...this.prevInterPoint, this.lineHength);
                } else {
                    this.clear();
                }
                this.timer = setTimeout(() => {
                    this.drawInsetPoint(!state);
                }, this.delay);
            }
            /**
            * 立刻更新
            */
            immediatelyUpdate() {
                clearTimeout(this.timer);
                this.drawInsetPoint(true);
            }
        }

        const interPoint = new InterPoint(ctx, 5, fontSize, 500);

        function render() {
            //清空画布
            ctx.clearRect(0, 0, width, height);
            //绘制文字
            inputs.forEach((input, index) => {
                drawText(input, 0, index * fontSize + height / 2);
            });
            interPoint.immediatelyUpdate();
        }

        const drawText = (text, x, y) => {
            ctx.beginPath();
            ctx.font = `${fontSize}px 微软雅黑`;
            ctx.fillStyle = "#000";
            ctx.textBaseline = "top";
            ctx.fillText(text, x, y);
            ctx.closePath();
        };
        function handleDrawText(text) {

            const tempStr = inputs[inputs.length - 1] + text;
            const tempWidth = ctx.measureText(tempStr).width;
            if (tempWidth > width) {
                //一行放不下
                inputs.push(text);
            } else inputs[inputs.length - 1] += text;
            render();
        }

        function delText() {
            inputs[inputs.length - 1] = inputs[inputs.length - 1].substr(0, inputs[inputs.length - 1].length - 1)
            render();
        }

        window.addEventListener("keyup", e => {
            if (e.key === "Backspace") {
                delText();
            } else handleDrawText(e.key);
        });
    </script>
</body>

</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值