混合/复杂文本节点包括用于按钮和标签的 FontAwsome

Mixed / complex text node inc FontAwsome for buttons and tags

我需要混合使用 Arial 和 Fontawsome 制作按钮和标签。 HTML 5 canvas 就混合字体而言相对粗糙,尽管 Konvajs 具有方便的标签形状,但据我所知,它不适应除单个文本节点以外的形状。看看我的答案片段,看看我想要什么,以及我是如何解决它的。

这是我的解决方案。唯一的技巧是我们必须使用 shape.getWidth() 方法并存储每个元素的总宽度和宽度以用于最终定位的文本居中。

似乎有效。

var s1 = new Konva.Stage({container: 'container1', width: 200, height: 200});
var layer1 = new Konva.Layer({draggable: false});
var bg1 = new Konva.Rect({width: 200, height: 200, fill: 'gold', })
layer1.add(bg1);
s1.add(layer1);


        function MakeComplexText(opts){
            var yOffset = 6;
            var txtEle = [];
            var maxW = 0;
            var g = new Konva.Group({x: opts.pos.x, y: opts.pos.y});
            g.add(new Konva.Rect({width: opts.pos.w, height: opts.pos.h, fill: opts.bgClr, stroke: opts.lineClr, strokeWidth: 1, cornerRadius: opts.cornerRadius}));

            if (opts.symbolLeft != ""){
                var t1 = new Konva.Text({name: 'symText1', y: yOffset + 1, width: 15, text: opts.symbolLeft, fontFamily: 'FontAwesome', fontSize: 11, fill: opts.textClr, align: 'left'});
                txtEle.push({obj: t1, w: t1.getWidth()});
                maxW = maxW + t1.getWidth();
                g.add(t1);
            }

            var t = new Konva.Text({name: 'btnText', y: yOffset, height: opts.pos.h, text: opts.text, fontFamily: 'Arial', fontSize: 11, fontStyle: "Bold", fill: opts.textClr, align: 'center'})
            txtEle.push({obj: t, w: t.getWidth()});
            maxW = maxW + t.getWidth();
            g.add(t);

            if (opts.symbolRight != ""){
                var t2 = new Konva.Text({name: 'symText2', y: yOffset + 1, width: 15, text: opts.symbolRight, fontFamily: 'FontAwesome', fontSize: 11, fill: opts.textClr, align: 'right'});
                txtEle.push({obj: t2, w: t2.getWidth()});
                maxW = maxW + t2.getWidth();
                g.add(t2);
            }
          
            var xPos = (opts.pos.w - maxW)/2;
            for (var i = 0; i < txtEle.length; i = i + 1){
                txtEle[i].obj.x(xPos);
                xPos = xPos + txtEle[i].w;
            }

            opts.parent.add(g);
            return g;
        }


        // move button icon right only
        var btnModeMoveR = MakeComplexText(
          {parent: layer1, pos: {x:5, y:7, w: 75, h: 24}, text: "Move", textClr: "#666666", bgClr: "#cccccc", lineClr: "#666666", symbolLeft: "", symbolRight: "\uf047", cornerRadius: 0}
        );

        // move button with icons left & right
        var btnModeMoveL = MakeComplexText(
          {parent: layer1, pos: {x:5, y:37, w: 75, h: 24}, text: "Move", textClr: "#666666", bgClr: "#cccccc", lineClr: "#666666", symbolLeft: "\uf047", symbolRight: "\uf047", cornerRadius: 0}
        );

        // Reresh button icon left
        var btnModeMoveL = MakeComplexText(
          {parent: layer1, pos: {x:5, y:67, w: 75, h: 24}, text: "Refresh", textClr: "#666666", bgClr: "#cccccc", lineClr: "#666666", symbolLeft: "", symbolRight: "\uf021", cornerRadius: 0}
        );


      // to make a tooltip we combine a label and complex text in a group. 

      var g = new Konva.Group({ x: 5, y: 97});

      var tooltip = new Konva.Label({x: 0, y: 0, width: 100});
      tooltip.add(new Konva.Tag({
        fill: "#cccccc",
        pointerDirection: 'right',
        pointerWidth: 10,
        pointerHeight: 10,
        lineJoin: 'round',
        width: 80,
        height: 24
      }));
      g.add(tooltip);
        // edit button
        var btnEdit = MakeComplexText(
          {parent: g, pos: {x:0, y:0, w: 75, h: 24}, text: "Edit", textClr: "#666666", bgClr: "#cccccc", lineClr: "transparent", symbolLeft: "", symbolRight: "\uf14b", cornerRadius: 0}
        );
    layer1.add(g)

//    btnEdit.moveTo(layer1);



s1.draw()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>

<div id='container1' style="display: inline-block; width: 400px, height: 400px; background-color: silver; overflow: hidden;"></div>