KonvaJS: Как изменить свойства класса текста (размер шрифта, высоту и ширину) при изменении размера?

Я пытаюсь изменить размер текстового слоя в KonvaJS. Мой код выглядит так:

var Canvas = (function() {
    var funct = {};
    var stageWidth,stageHeight,stage,layer,circle,rect,myPlayer,textNode,tr;

    funct.stageInit = function(){
      stage = new Konva.Stage({
        container: 'canvas',
        width: stageWidth,
        height: stageHeight
      });

      layer = new Konva.Layer();
      stage.add(layer);

      funct.addText();
      funct.makeTextResizeable();
      layer.draw();
    }

    funct.addText = function(){
      textNode = new Konva.Text({
        text: 'Some text here',
        x: 50,
        y: 50,
        width: 50,
        height: 50,
        fontSize: 20,
        draggable: true,
      });

      layer.add(textNode);

      textNode.on('dblclick', () => {
        // create textarea over canvas with absolute position

        // first we need to find its positon
        var textPosition = textNode.getAbsolutePosition();
        var stageBox = stage.getContainer().getBoundingClientRect();

        var areaPosition = {
          x: textPosition.x + stageBox.left,
          y: textPosition.y + stageBox.top
        };


        // create textarea and style it
        var textarea = document.createElement('textarea');
        document.body.appendChild(textarea);

        textarea.value = textNode.text();
        textarea.style.position = 'absolute';
        textarea.style.top = areaPosition.y + 'px';
        textarea.style.left = areaPosition.x + 'px';
        textarea.style.width = textNode.width();
        textarea.style.zIndex = 15;

        textarea.focus();


        textarea.addEventListener('keydown', function (e) {
          if (e.keyCode === 13) {
            textNode.text(textarea.value);
            layer.draw();
            document.body.removeChild(textarea);
          }
        });
      });
    }

    funct.makeTextResizeable = function(){
      tr = new Konva.Transformer({
        boundBoxFunc: function (oldBoundBox, newBoundBox) {
          if (newBoundBox.width > 200) {
            return oldBoundBox;
          }
          textNode.attrs.fontSize = (newBoundBox.width/oldBoundBox.width)*textNode.attrs.fontSize;
          textNode.attrs.width = (newBoundBox.width/oldBoundBox.width)*textNode.attrs.width;
          textNode.attrs.height = (newBoundBox.width/oldBoundBox.width)*textNode.attrs.height;
          console.log(textNode.attrs.fontSize);
          return newBoundBox
        },
        isTransforming: function(){
          console.log('a');
        }
      });
      layer.add(tr);
      tr.attachTo(textNode);
    }

    funct.fitStageIntoParentContainer = function(){
      var container = document.querySelector('#canvas-container');
      var containerWidth = container.offsetWidth;
      var scale = containerWidth / stageWidth;

      stage.width(stageWidth * scale);
      stage.height(stageHeight * scale);
      stage.scale({ x: scale, y: scale });
      stage.draw();
    }

    funct.Onresize = function(){
      window.addEventListener('resize', function(){
        funct.fitStageIntoParentContainer();
      });
    }

    funct.init = function(){
      stageHeight = $('.vjs-poster').height();
      stageWidth =  $('.vjs-poster').width();
      funct.stageInit();
      funct.Onresize();
    }
    return funct;
  })();  

Я хотел бы разрешить изменение размера текстового слоя путем перетаскивания и соответствующего изменения размера шрифта. Я также хотел бы, чтобы текст был перенесен / развернут в зависимости от размера текстового слоя.

https://jsfiddle.net/gentrobot/5gk1h67u/

Требование состоит в том, чтобы иметь возможность динамически добавлять текст во время выполнения, изменять его размер и положение, а затем получать окончательный размер текста, текстовый контейнер и координаты текстового контейнера, чтобы сохранить его. На основе этой информации будет затем сгенерирован HTML-код с динамически добавляемым текстом, расположенный на основном элементе.

Я могу изменить размер текста, но он не изменяется плавно и не переносится при изменении размера. Хотя, сделав это, я могу также извлечь окончательные координаты и размер.


person gentrobot    schedule 10.09.2018    source источник


Ответы (1)


Возможно, вам не нужно менять scale при преобразовании текста. Вы можете сбрасывать его при каждом transform событии:

tr.on('transform', function() {
     textNode.setAttrs({
         width: textNode.width() * textNode.scaleX(),
         height: textNode.height() * textNode.scaleY(),
         scaleX: 1,
         scaleY: 1,
     });
})

Также для лучшего UX вы можете ограничить некоторые размеры:

  tr = new Konva.Transformer({
    boundBoxFunc: function (oldBoundBox, newBoundBox) {
      if (newBoundBox.width > 200 || newBoundBox.width < textNode.fontSize()) {
        return oldBoundBox;
      } else if (newBoundBox.height < textNode.fontSize()) {
        return oldBoundBox;
      }
      return newBoundBox
    }
});

Демо: https://jsfiddle.net/dgL1kvcb/1/

Если вам нужно изменить fontSize при преобразовании, вам необходимо определить его логику. Как это будет работать, если вы хотите изменить обтекание и размер шрифта?

person lavrton    schedule 10.09.2018
comment
Большое спасибо. Это прекрасно работает. Я тоже хотел изменить fontSize, но теперь изменил его в UX. Я даю текстовый редактор вместо текстового поля, в котором пользователи могут указать размер и стили шрифта. Если они изменяют размер текстового слоя, они могут редактировать эти значения из самого текстового редактора. - person gentrobot; 10.09.2018