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

PaperJS中mouseleave/mouseenter事件触发TypeError错误求助

Paper.js矩形网格鼠标悬停事件间歇性TypeError问题原因解析

我想要创建一个矩形网格,实现鼠标悬停时矩形高亮的效果,但在矩形路径的mouseleave(或mouseenter)事件中出现了错误。该错误并非每次都会触发,主要在快速移动光标或光标移出浏览器时出现。

报错信息

paper-core.js:12475 Uncaught TypeError: Cannot create property '_canvasStyle' on string 'grey'
    at fields.<computed> [as fillColor] (paper-core.js:12475:12)
    at item.<computed> [as fillColor] (paper-core.js:12530:16)
    at Path2.<anonymous> (percussions.js?t=1659596246337:30:28)
    at Path2.emit (paper-core.js:705:20)
    at emit (paper-core.js:13349:13)
    at emitMouseEvent (paper-core.js:13364:8)
    at CanvasView2._handleMouseEvent (paper-core.js:13438:6)
    at handleMouseMove (paper-core.js:13230:8)
    at docEvents.<computed> (paper-core.js:13300:4)

使用的代码实现

初始化PaperScope代码

let paper = new PaperScope()
var canvas = document.getElementById('paperjs');
paper.setup(canvas);

网格与交互实现代码

let tileSize = Math.floor((window.innerWidth + window.innerHeight) * .025)

for (var y = 0; y < paper.view.size.height; y += tileSize) {
    for (var x = 0; x < paper.view.size.width; x += tileSize) {
        let topLeft = new paper.Point(x, y);
        let radius = new paper.Size(tileSize, tileSize);
        let rect = new paper.Path.Rectangle(topLeft,  radius);
        rect.fillColor = 'white';
        rect.on('mouseenter', function (e) {
            this.fillColor = 'grey'
        })
        rect.on('mouseleave', function (e) {
            this.fillColor = 'white'
        })
    }
}

HTML代码

<body>
  <canvas id="paperjs" resize data-paper-hidpi="off"></canvas>
  <script type="module" src="/src/main.js"></script>
</body>

CSS代码

body {
    min-height: 100vh;
}
canvas[resize] {
    width: 100%;
    height: 100%;
}
#paperjs {
    background-color: white;
    position: fixed;
}

问题原因

这个错误的核心是事件回调中this的指向异常:

  1. 当快速移动光标或移出浏览器时,Paper.js的事件系统在边界场景下(比如元素状态异常、事件队列混乱),会导致回调函数中的this不再指向对应的矩形Path实例,意外指向了之前设置的颜色字符串('grey'或'white')。
  2. Paper.js的fillColor属性内部会尝试在目标对象上创建_canvasStyle属性管理样式,但字符串是不可变的原始类型,无法添加新属性,因此抛出Cannot create property '_canvasStyle' on string的错误。

修复方案

通过固定目标对象的引用避免this指向问题:

  • 使用箭头函数继承外部作用域的变量引用:
rect.on('mouseenter', (e) => {
    rect.fillColor = 'grey'
})
rect.on('mouseleave', (e) => {
    rect.fillColor = 'white'
})
  • 或在回调外部保存矩形实例的引用:
let currentRect = rect;
rect.on('mouseenter', function (e) {
    currentRect.fillColor = 'grey'
})
rect.on('mouseleave', function (e) {
    currentRect.fillColor = 'white'
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:15:12