You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Konva图形调用draggable()报错:draggable不是函数的问题求助

Konva.js拖拽功能设置报错解决方案

问题背景

需要实现以下交互逻辑:

  • 图形初始化时处于不可拖拽状态
  • 选中图形时开启其拖拽功能
  • 取消选中时关闭其拖拽功能

但调用draggable()方法时,浏览器提示“draggable不是函数”。

错误原因

Konva.js中没有名为draggable()的方法,设置节点拖拽状态需要通过属性赋值或setAttr()方法操作draggable属性,而非函数调用方式。

修复后的代码

1. 初始化图形的draw函数

将错误的poly.draggable(false)替换为属性赋值方式:

draw(Map, points) {
        var poly = new Konva.Line({
            points: points,
            stroke: 'blue',
            strokeWidth: 5,
            closed: true,
            name: 'polygon'
        });
        // 初始化设置不可拖拽(替换原poly.draggable(false))
        poly.draggable = false;
        Map.stage.findOne("#draw").add(poly);
        Map.stage.findOne("#tr").nodes([poly]);

        if(points.length == 2){
            var imageObj = new Image();
            imageObj.onload = function() {
                var yoda = new Konva.Image({
                    x: points[0]-20,
                    y: points[1]-20,
                    image: imageObj,
                    width: 20,
                    height: 20,
                    name:'finishBtn'
                });
                Map.stage.findOne("#draw").add(yoda);
            };
            imageObj.src = '/src/assets/drawmap/ok.png';
        }

        return poly;
    }

2. 点击选择图形的事件处理代码

修改选中时的拖拽设置逻辑,同时补充取消选中时的拖拽关闭逻辑:

Map.stage.on('click tap', function(e) {
            if (this.findOne('#selectionRectangle').visible()) {
                return;
            }
            if (Map.curTool !== tool.pick) {
                return;
            }

            // 先获取之前选中的节点,清空选中时关闭拖拽
            const prevSelectedNodes = this.findOne("#tr").nodes();
            if (e.target === this) {
                // 关闭所有之前选中节点的拖拽
                prevSelectedNodes.forEach(node => {
                    node.draggable = false;
                });
                this.findOne("#tr").nodes([]);
                return;
            }

            if (!e.target.hasName('rect') && !e.target.hasName('polygon') && !e.target.hasName('image')) {
                return;
            }

            const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
            const isSelected = prevSelectedNodes.indexOf(e.target) >= 0;

            let newSelectedNodes = [...prevSelectedNodes];
            if (!metaPressed && !isSelected) {
                // 关闭之前选中节点的拖拽
                prevSelectedNodes.forEach(node => {
                    node.draggable = false;
                });
                newSelectedNodes = [e.target];
            } else if (metaPressed && isSelected) {
                // 移除选中时关闭该节点的拖拽
                e.target.draggable = false;
                newSelectedNodes.splice(newSelectedNodes.indexOf(e.target), 1);
            } else if (metaPressed && !isSelected) {
                newSelectedNodes = [...prevSelectedNodes, e.target];
            }
            
            this.findOne("#tr").nodes(newSelectedNodes);
            // 为新选中的节点开启拖拽
            newSelectedNodes.forEach(node => {
                node.draggable = true;
            });
        });

补充说明

  • 除了node.draggable = value,也可以使用node.setAttr('draggable', value)实现相同效果
  • 必须处理取消选中的场景,确保未选中的图形恢复不可拖拽状态

内容的提问来源于stack exchange,提问作者zefesa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:25:35