首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >KonvaJS总是在标签中对文本进行居中

KonvaJS总是在标签中对文本进行居中
EN

Stack Overflow用户
提问于 2020-12-05 07:59:43
回答 1查看 1.1K关注 0票数 1

我为这段代码道歉,它处于我正在积极参与的状态。

在Konva JS,我在制作标签。基本上是一个组,它有一个形状和文本元素。这些形状是从数据库中动态绘制的,每个db行都有坐标、形状(方形、圆圈等)、大小和旋转。根据屏幕大小,它们被乘以一个比例。我有一个工作解决方案,我已经使用了几个星期,但我也有一个函数,可以改变形状的形状。因此,我按下一个按钮,它更新数据库(例如,改变方圆),然后重新绘制画布。因为从正方形到圆圈,从左上角画到中间画的形状都会改变,所以它会把坐标搞乱。我决定切换到宽度/2偏移量的矩形,这样矩形也是从中间画出来的。

后来我不断地打破它,我现在无法获得文本为中心的任何。我需要以文本为中心的文本,无论形状、大小或旋转。

当前代码

代码语言:javascript
运行
复制
        //Gets table array from SQL
        tables = callPhpFunction('getTablesInRoom', room);
        tables = JSON.parse(tables);
        
        numberOfTables = tables.length;
        index = 0;
        
        tableLayer = new Konva.Layer();
        tableLayer.add(transformer);
        
        //For every table
        while(index < numberOfTables){
            tableNumber = tables[index]['tablenumber'];
            offset_x = 0;
            offset_y = 0;
            pos_x = parseInt(tables[index]['posx']) * scale;
            pos_y = parseInt(tables[index]['posy']) * scale;
            shape = tables[index]['shape'];     
            tableWidth = parseInt(tables[index]['width']) * scale;
            tableHeight = parseInt(tables[index]['height']) * scale;
            rotation = parseInt(tables[index]['rotation']); 
            fillColor = "gray";
            strokeColor = "black";
                        
    
            var table = new Konva.Label({
                x: pos_x,
                y: pos_y,
                draggable:canDrag
              });

            pos_x = 0;
            pos_y = 0 ;
            
            //If the shape is a square, rectangle, or undefined
            if(shape != "circle" && shape != "ellipse" && shape != "longellipse"){
                offset_x = tableWidth/2
                offset_y = tableHeight/2
            
                table.add(new Konva.Rect({
                    width: tableWidth,
                    height: tableHeight,
                    offsetX: offset_y,
                    offsetY: offset_y,
                    height: tableHeight,
                    fill: fillColor,
                    stroke: strokeColor,
                    strokeWidth: 4
                }));
            //If shape is a circle or ellipse
            } else {
                
                table.add(new Konva.Ellipse({
                    radiusX: tableWidth/2,
                    radiusY: tableHeight/2,
                    fill: fillColor,
                    stroke: strokeColor,
                    strokeWidth: 4
                }));
                
                //Can't remember why this is here, but it seems to work/ Think if these are reused when the text is drawn it centers them. 
                pos_x = -tableWidth/2;
                pos_y = -tableHeight/2;
            }
            //Gets the first shape (ellipse or rectangle) in the label. I think is equivalent to getTag()
            innerShape = getInnerShape(table);
            
            //Rotates the inner shape, while leaving text unRotated. 
            if(rotation != 0){
                canvasX =  pos_x + (tableWidth/2)
                canvasY =  pos_y + (tableHeight/2)
                rotateAroundPoint(innerShape, rotation, {x:canvasX, y:canvasY });
            }
            
            //Currently approach is to get center based on the client rectangle. It's not working
            box = table.getClientRect();
            box_x = box.x + box.width / 2;
            box_y = box.y + box.height / 2; 
                            
            table.add(new Konva.Text({
                width: tableWidth,
                height: tableHeight,
                x: box_x,
                y: box_y,
                text: tableNumber,
                verticalAlign: 'middle',
                align: 'center',
                fontSize: 24,
                fontFamily: 'Calibri',
                fill: 'black',
                listening: false
            }))

这是视觉效果

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-05 11:05:05

我稍微重写了您的创作例程,看起来像这样工作得很好。这里的本质是形状+标签被组合在一起,全局缩放的位置被应用到这些组中,而不是单独的图形元素。

代码:

代码语言:javascript
运行
复制
    const tableLayer = new Konva.Layer();
    
    const scale = 1.0; // position scale factor
    
    const mockData = [
        {
            label: "45",
            shape: "circle",
            x: 100,
            y: 150,
            w: 100,
            h: 100,
            r: 0
        },
        {
            label: "46",
            shape: "rect",
            x: 200,
            y: 170,
            w: 150,
            h: 100,
            r: -30
        },
        {
            label: "47",
            shape: "rect",
            x: 70,
            y: 200,
            w: 50,
            h: 100,
            r: 15
        },
        {
            label: "48",
            shape: "ellipse",
            x: 400,
            y: 300,
            w: 250,
            h: 150,
            r: 30
        }
    ];


    function createShapeElement( data ) {
        // Create container group
        let element = new Konva.Group( {
            x: data.x * scale,
            y: data.y * scale,
            draggable: true,
            listening: true,
        } );

        // Create background shape
        let shape;
        switch ( data.shape ) {
            case "circle": // fall-through
            case "ellipse": // fall-through
            case "longellipse":
                shape = new Konva.Ellipse( {
                    x: 0,
                    y: 0,
                    radiusX: data.w * 0.5,
                    radiusY: data.h * 0.5,
                    rotation: data.r,
                    fill: "gray",
                    stroke: "black",
                    strokeWidth: 4,
                    draggable: false,
                    listening: true
                } );
                break;

            default:
                shape = new Konva.Rect( {
                    x: 0,
                    y: 0,
                    offsetX: data.w * 0.5,
                    offsetY: data.h * 0.5,
                    width: data.w,
                    height: data.h,
                    rotation: data.r,
                    fill: "gray",
                    stroke: "black",
                    strokeWidth: 4,
                    draggable: false,
                    listening: true
                } );
                break;
        } // End switch

        // Create label
        let label = new Konva.Text( {
            x: data.w * -0.5,
            y: data.h * -0.5,
            width: data.w,
            height: data.h,
            text: data.label,
            fontSize: 24,
            fill: "black",
            align: "center",
            verticalAlign: "middle",
            draggable: false,
            listening: false
        } );

        element.add( shape, label );

        return element;
    }


    // Loop your data and call the creation method for each data item.
    mockData.forEach( itemData => {
        tableLayer.add( createShapeElement( itemData ) );
    } );
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65154951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档