Konva 内容重叠无法触发点击事件的解决方法

发布时间 2023-06-25 14:03:09作者: Dandelion_000

写在前面:

  • 环境:Vue3 + Konva + vite
  • 在绘制界面时踩坑,主要是关于 listening 属性的使用
  • 在绘制界面时,不免出现有内容重叠的情况,这会影响事件的触发

  • 使用设置listening属性可以允许事件穿透,默认为true不可穿透(示例如下)

    <template>
      <div>
        <div id="mybtn"></div>
      </div>
    </template>
    
    <script>
    import Konva from 'konva';
    
    export default {
      data() {
        return {
          position: {
            posX: 0,
            posY: 0,
          },
          size: {
            width: 100,
            height: 50,
          },
          styles: {
            borderSize: 1,
            fontSize: 12,
            backgroundColor: '',
            fontColor: '#000',
            borderColor: '#000',
            opacity: 1,
          },
          btnText: 'Button',
        };
      },
      mounted() {
        this.initializeKonva();
      },
      methods: {
        initializeKonva() {
          const stage = new Konva.Stage({
            container: 'mybtn',
            width: this.size.width,
            height: this.size.height,
          });
    
          const layer = new Konva.Layer();
          stage.add(layer);
    
          const button = new Konva.Rect({
            x: this.position.posX,
            y: this.position.posY,
            width: this.size.width,
            height: this.size.height,
            fill: this.styles.backgroundColor,
            stroke: this.styles.borderColor,
            strokeWidth: this.styles.borderSize,
            opacity: this.styles.opacity,
          });
    
          const buttonText = new Konva.Text({
            x: this.position.posX,
            y: this.position.posY,
            width: this.size.width,
            height: this.size.height,
            text: this.btnText,
            fontSize: this.styles.fontSize,
            fontFamily: 'Arial',
            fill: this.styles.fontColor,
            align: 'center',
            verticalAlign: 'middle',
            listening: false,   // 设置listening为false,允许事件穿透
          });
    
          button.on('click', this.clickBtn);
    
          layer.add(button);
          layer.add(buttonText);
          layer.draw();
    
        },
    
        clickBtn() {
          console.log('clickBtn run');
          // 点击事件逻辑
        }
      },
    };
    </script>
    
    <style scoped>
    div {
      width: 100%;
      height: 100%;
    }
    </style>