canvas文档:https://www.runoob.com/jsref/dom-obj-canvas.html

创建画板、图片、文字、自动换行都是分开方法,可以灵活调用
里面有两个小demo,演示调用方法
其实简单修改也可以不需要依靠vue

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    img {
        width: 100%;
        height: 100%;
    }
</style>
<body style="background-color: blue">
<div id="app">
    <!-- 画板 -->
    <canvas style="display: none" id="myCanvas" width=""></canvas>
    <!-- 效果 -->
    <img :src="img_src" alt="">
</div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    let v = new Vue({
        el: '#app',
        data: {
            img_src: '',
            ctx: '',
            myCanvas: '',
        },
        methods: {
            makePlan() { // demo1
                let row = 15; // 行数会影响页面的长度 签字预留400 顶部预留100
                this.makeCanvas(400, 500 + 20 * row); // 签字预留400 上面文字 100+20*行数
                //文本
                this.makeText('标题', 200, 40, 'center', '#000', '20px Arial')
                this.makeLine(20, 60, 380, 60);
                this.makeText('任务', 100, 100, 'center', '#000', '16px Arial')
                this.makeText('单位', 300, 100, 'center', '#000', '16px Arial')
                let i = 0;
                for (i = 0; i < row; i++) {
                    this.makeText('2020-02-13-2020-03-13', 100, 120 + 20 * i, 'center')
                    this.makeText('90次', 300, 120 + 20 * i, 'center')
                }
                this.makeLine(20, 120 + 20 * i, 380, 120 + 20 * i);
                let img = 'https://csdnimg.cn/public/common/toolbar/images/eduwxfix.png'
                this.makeImage(img, 20, 400, 360); // 创建图片
                this.imagePut();
            },
            makeFloat(text) { // demo2
                // 超长画布来计算文字预计的高度
                this.makeCanvas(400, 10000);
                let y = this.autoRow(text, 20, 0, 360, 20, '16px Arial')  // 计算文字的总高度
                this.makeCanvas(400, 500 + y); // 签字预留400 上面文字 100+20*行数
                //文本
                this.makeText('考核任务', 200, 40, 'center', '#000', '20px Arial')
                this.makeLine(20, 60, 380, 60);
                y = this.autoRow(text, 20, 90, 360, 20, '16px Arial')
                this.makeLine(20, 20 + y, 380, 20 + y);
                this.imagePut();
            },
            makeImage(url, x, y, width) {
                let image = new Image();
                image.setAttribute('crossOrigin', 'anonymous')
                image.src = url;
                image.onload = () => {
                    this.ctx.drawImage(image, x, y, width, image.height * width / image.height);
                }
            },
            imagePut(type) { // 输出图像
                // 因为需要渲染图像才能导出,暂时没啥办法,几计时刷新了,有大牛好办法可以留言
                let i = 0;
                let t = setInterval(() => {
                    i++;
                    this.img_src = this.ctx.canvas.toDataURL(type);
                    if (i > 100) {
                        clearInterval(t)
                    }
                }, 100);
            },
            makeCanvas(width, height) { // 初始化画板
                this.myCanvas = document.getElementById('myCanvas');  // 画板id
                this.myCanvas.width = width;  //尺寸
                this.myCanvas.height = height;
                this.ctx = this.myCanvas.getContext('2d');
                this.ctx.fillStyle = '#ffffff';
                this.ctx.fillStyle = '#fff';
                this.ctx.fillRect(0, 0, this.myCanvas.width, this.myCanvas.height);
            },
            makeText(text, x, y, align, color, font) { //文字
                this.ctx.font = !font ? '14px Arial' : font;
                this.ctx.fillStyle = !color ? '#4a4a4a' : color;
                this.ctx.textAlign = !align ? 'left' : align;
                this.ctx.fillText(text, x, y);
            },
            makeLine(start_x, start_y, end_x, end_y, cap,) { // 线条
                this.ctx.beginPath();
                this.ctx.lineCap = !cap ? "round" : cap;
                this.ctx.moveTo(start_x, start_y);
                this.ctx.lineTo(end_x, end_y);
                this.ctx.stroke();
            },
            /**
             * 自动换行
             * @param text
             * @param x
             * @param y
             * @param maxWidth 最大宽度
             * @param lineHeight 行高
             */
            autoRow(text, x, y, maxWidth, lineHeight, font) {
                let arrText = text.split('');
                let line = '';
                this.ctx.font = !font ? '14px Arial' : font;
                for (let n = 0; n < arrText.length; n++) {
                    let testLine = line + arrText[n];
                    let metrics = this.ctx.measureText(testLine);
                    let testWidth = metrics.width;
                    if (testWidth > maxWidth && n > 0) {
                        this.makeText(line, x, y)
                        line = arrText[n];
                        y += lineHeight;
                    } else {
                        line = testLine;
                    }
                }
                this.makeText(line, x, y);
                return y;
            }
        },
        created() {
            this.makePlan('');
        }
    })

</script>
Logo

前往低代码交流专区

更多推荐