V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
huhailong1121
V2EX  ›  分享创造

[代码分享] 使用 HTML5 的 Canvas 绘制编码说明图片

  •  
  •   huhailong1121 · 12 天前 · 685 次点击

    最急在工作中遇到一个需求,根据给定的编码生成编码说明,像下面这样的效果。 image.png{{{width="auto" height="auto"}}} 不同含义的编码用横杠分割,然后每个编码下面用箭头指明具体的含义。下面是我使用 canvas 实现的代码。具体的编码宽度大家可以根据实际情况进行调整,目前我的这个方法中支持起始坐标设定,和箭头的长度设定。

    预览地址:https://www.huhailong.vip/res/html/codedescribe

    /**
     * 绘制编码说明图片
     * @param {起始横坐标} startX 
     * @param {起始纵坐标} startY 
     * @param {编码信息对象} codeDescribeObj
     */
    function drawCode(startX, startY, codeDescribeObj) {
    
        const canvas = document.getElementById('code-canvas');
        const ctx = canvas.getContext('2d');
    
        let preTextWidth = startX;  //左侧开始坐标
        let preTextHeight = startY; //开始高度坐标
    
        for(let i=0; i<codeDescribeObj.codeList.length; i++){
            ctx.font = "50px Arial";
            let tempText = ctx.measureText(codeDescribeObj.codeList[i]);
            ctx.fillText(codeDescribeObj.codeList[i], preTextWidth, preTextHeight);
            if(i < codeDescribeObj.codeList.length - 1){
                ctx.fillText('—',preTextWidth+tempText.width+10,preTextHeight - 2);
            }
            ctx.stroke();
            ctx.font = "16px Arial";
            let describeY = preTextHeight + codeDescribeObj.arrowHeightList[i];
            ctx.fillText(codeDescribeObj.describeList[i], preTextWidth, describeY);
            ctx.stroke();
            //绘制箭头
            ctx.lineWidth = 1;
            ctx.beginPath();
            ctx.moveTo(preTextWidth + 30, preTextHeight + 10);
            ctx.lineTo(preTextWidth + 30, describeY - 20);
            ctx.lineTo(preTextWidth + 25, describeY - 30);
            ctx.moveTo(preTextWidth + 30, describeY - 20);
            ctx.lineTo(preTextWidth + 35, describeY - 30);
            ctx.stroke();
            //更新坐标信息
            preTextWidth = preTextWidth + tempText.width + 80;
        }
    }
    
    //定义编码信息对象
    const codeDescribeObj = {
        codeList: ['F1','YHT','23Y','S1','8R'],
        describeList: ['方案代码','颜色代码','年代系列代码','品类款式代码','尺寸方向代码'],
        arrowHeightList: [100,300,200,150,300]
    }
    
    drawCode(120, 100, codeDescribeObj);
    
    
    

    对应的 html 文件和 css 文件如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>编码说明图片绘制</title>
        <link rel="stylesheet" type="text/css" href="./styles.css" />
    </head>
    <body>
        <div class="box">
            <canvas id="code-canvas" width="1000" height="600"></canvas>
        </div>
        <script src="./index.js"></script>
    </body>
    </html>
    
    body{
        margin: 0;
        height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .box{
        text-align: center;
        width: 800px;
    }
    canvas{
        border: 1px solid gray;
        border-radius: 4px;
        width: 100%;
    }
    

    因为没有找到符合的组件,所以自己写了,如果有知道有现成组件的小伙伴也可以分享一下。

    5 条回复    2024-05-08 11:16:58 +08:00
    codehz
        1
    codehz  
       12 天前
    是不是直接用 svg 比较方便()
    huhailong1121
        2
    huhailong1121  
    OP
       12 天前
    @codehz 因为我比较熟悉 canvas ,所以就使用 canvas 了,这个绘制不难,主要是这个编码是从服务端传来的,可能是 2 个或者 5 个,个数和文字宽度不确定,所以需要动态的去绘制。如果 svg 也可以动态绘制,理论上是可以的。
    iOCZS
        3
    iOCZS  
       12 天前
    @huhailong1121 svg 你可以想象成是绘制的 HTML ,div 用 rect 这种代替,所以。。。。
    huhailong1121
        4
    huhailong1121  
    OP
       12 天前
    @iOCZS 这么说的话这种场景下也挺适合的,起码放大不会失真,完了我学习学习。
    mewking
        5
    mewking  
       11 天前
    请教 OP 一个问题,这个网站好像是 Canvas 生成的图片,有无快捷的办法导出 PDF ,里面的文字必须 OCR ?

    内容是 DIY 鱼竿的文档

    https://www.fujitackle.com/catalog/book/fujitackleplus2024/HTML5/pc.html#/page/1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1337 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:55 · PVG 07:55 · LAX 16:55 · JFK 19:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.