0

我正在尝试调整文本元素的大小,但是当我尝试使其更大时,我总是会更改比例。

我像 konvajs vue 文档一样配置了转换器选项并且运行良好,然后我像 js 示例一样进行配置,但是当您调整文本元素的大小时,文本总是会更改比例,并且元素的大小有时不会更改为您拥有的大小选择但要大得多。

我基于 js 中的示例(https://konvajs.org/docs/select_and_transform/Resize_Text.html#page-title)并尝试将其传递给 vue。

我在 main.js 上导入了库

import VueKonva from "vue-konva";

Vue.use(VueKonva);

app.js 模板

<v-stage ref="stage" :config="config" @mousedown="handleStageMouseDown" @touchstart="handleStageMouseDown">
  <v-layer ref="layer">
    <template v-for="item in list">
      <v-text :key="item.id" :ref="item.name" :config="item" @transformend="handleTransformEnd" />
    </template>

    <v-transformer ref="transformer" :config="{ enabledAnchors: ['middle-left', 'middle-right'], boundBoxFunc: (oldBox, newBox) => {
          if (newBox.width < this.MIN_WIDTH) {
            return oldBox;
          }

          return newBox;
        },
      }"
    />
  </v-layer>
</v-stage>

app.js 脚本

<script>
export default {
  name: "App",
  data() {
    return {
      MIN_WIDTH: 20,
      config: {
        width: window.innerWidth,
        height: window.innerHeight,
      },
      selectedShapeName: "",
      list: [
        {
          x: 50,
          y: 60,
          fontSize: 20,
          text: "Hello from the Konva framework. Try to resize me.",
          draggable: true,
          width: 200,
          scaleX: 1,
          name: "textResize1",
          height: "auto",
        },
      ],
    };
  },
  methods: {
    handleTransformEnd(e) {
      const item = this.list.find((i) => i.name === this.selectedShapeName);

      item.width = Math.max(
        e.target.width() * e.target.scaleX(),
        this.MIN_WIDTH
      );
      item.scaleX = 1;
      item.scaleY = 1;
    },
    handleStageMouseDown(e) {
      // clicked on stage - clear selection
      if (e.target === e.target.getStage()) {
        this.selectedShapeName = "";
        this.updateTransformer();
        return;
      }

      // clicked on transformer - do nothing
      const clickedOnTransformer =
        e.target.getParent().className === "Transformer";
      if (clickedOnTransformer) {
        return;
      }

      // find clicked rect by its name
      const name = e.target.name();
      const item = this.list.find((i) => i.name === name);
      if (item) {
        this.selectedShapeName = name;
      } else {
        this.selectedShapeName = "";
      }
      this.updateTransformer();
    },
    updateTransformer() {
      // here we need to manually attach or detach Transformer node
      const transformerNode = this.$refs.transformer.getNode();
      const stage = transformerNode.getStage();
      const { selectedShapeName } = this;

      const selectedNode = stage.findOne("." + selectedShapeName);
      // do nothing if selected node is already attached
      if (selectedNode === transformerNode.node()) {
        return;
      }

      if (selectedNode) {
        // attach to another node
        transformerNode.nodes([selectedNode]);
      } else {
        // remove transformer
        transformerNode.nodes([]);
      }
    },
  },
};
</script>

此代码示例 https://codesandbox.io/s/transform-07mwo

编辑:用代码更新

4

1 回答 1

1

我让它与这些变化一起工作

在 v-text 标签中,我们需要将 transformend 事件更改为 transform 事件,以在不改变比例的情况下直观地更新文本。

旧的 v-text 标签

<v-text 
    :key="item.id"  
    :ref="item.name"    
    :config="item"  
    @transformend="handleTransformEnd"  
/>

更新了 v-text 标签

<v-text 
    :key="item.id"  
    :ref="item.name"    
    :config="item"  
    @transform="handleTransformEnd" 
/>

在函数 handleTransformEnd 中,我们必须更新列表中项目的宽度,同时我们必须更新选定的形状并更新 X 和 Y 缩放,使其始终为 1,从而不会重新缩放。

旧句柄TransformEnd

handleTransformEnd(e) { 
  const item = this.list.find((i) => i.name === this.selectedShapeName);    
  item.width = Math.max(    
    e.target.width() * e.target.scaleX(),   
    this.MIN_WIDTH  
  );    
  item.scaleX = 1;  
  item.scaleY = 1;  
},

更新了句柄TransformEnd

handleTransformEnd() {
  const selectedNode = this.$refs.transformer
    .getStage()
    .getStage()
    .findOne("." + this.selectedShapeName);

  const item = this.list.find(
    (item) => item.name === this.selectedShapeName
  );
  item.width = item.width * selectedNode.getScaleX();

  selectedNode.setScaleX(1);
  selectedNode.setScaleY(1);
},
于 2021-11-11T10:43:10.963 回答