paper.js - 创建可拖动形状数组
paper.js - create array of draggable shapes
我正在尝试在 paper.js 中创建一组形状。每个形状都应该是可拖动的,并且在拖动过程中给出该形状的索引。
我尝试了以下代码,但我只收到消息“Uncaught TypeError: Cannot read 属性 'position' of undefined”。
感谢收到的任何帮助。
<canvas id = "canvas_1" > < /canvas>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js" > < /script>
<script type = "text/paperscript" canvas = "canvas_1" >
var path = [];
for (i = 0; i < 5; i++) {
path[i] = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
path[i].onMouseDrag = function(event) {
path[i].position += event.delta;
console.log("shape " + i + " is being dragged.")
}
}
</script>
问题
您的错误归结为 variable scoping 在 Javascript 中的工作方式:变量的范围限定为包含函数或脚本 。当您开始拖动圆圈时,for 循环中的 i === 5
,因此 path[i]
在拖动函数中未定义(越界)。因此,你的错误。
如果您想了解更多信息,this answer 提供了对这个“闭包内循环”问题的深入研究。
解决方案
This answer 提供了一些针对此问题的常见解决方案。
ES6 让
ES6 let
statement 是这个问题的现代解决方案,避免了 var
语句的许多范围“怪癖”。 包含块的变量作用域,因此循环的每次通过都会获得自己的 i
.
实例
要在 PaperScript 中使用 ES6 功能,您首先需要 load a newer version of the Acorn parser (感谢 sasensi 和 Geddes)。然后简单地在循环中声明let i
:
var path = [];
for (let i = 0; i < 5; i++) {
path[i] = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
path[i].onMouseDrag = function(event) {
path[i].position += event.delta;
console.log("shape " + i + " is being dragged.")
};
}
关闭
无需修改 PaperScript 解析器,您可以使用 closure 在新函数范围内捕获索引:
var path = [];
function createMouseDragHandler(index) {
return function(event) {
path[index].position += event.delta;
console.log("shape " + index + " is being dragged.")
};
}
for (var i = 0; i < 5; i++) {
path[i] = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
path[i].onMouseDrag = createMouseDragHandler(i);
}
我正在尝试在 paper.js 中创建一组形状。每个形状都应该是可拖动的,并且在拖动过程中给出该形状的索引。
我尝试了以下代码,但我只收到消息“Uncaught TypeError: Cannot read 属性 'position' of undefined”。
感谢收到的任何帮助。
<canvas id = "canvas_1" > < /canvas>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js" > < /script>
<script type = "text/paperscript" canvas = "canvas_1" >
var path = [];
for (i = 0; i < 5; i++) {
path[i] = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
path[i].onMouseDrag = function(event) {
path[i].position += event.delta;
console.log("shape " + i + " is being dragged.")
}
}
</script>
问题
您的错误归结为 variable scoping 在 Javascript 中的工作方式:变量的范围限定为包含函数或脚本 。当您开始拖动圆圈时,for 循环中的 i === 5
,因此 path[i]
在拖动函数中未定义(越界)。因此,你的错误。
如果您想了解更多信息,this answer 提供了对这个“闭包内循环”问题的深入研究。
解决方案
This answer 提供了一些针对此问题的常见解决方案。
ES6 让
ES6 let
statement 是这个问题的现代解决方案,避免了 var
语句的许多范围“怪癖”。 包含块的变量作用域,因此循环的每次通过都会获得自己的 i
.
要在 PaperScript 中使用 ES6 功能,您首先需要 load a newer version of the Acorn parser (感谢 sasensi 和 Geddes)。然后简单地在循环中声明let i
:
var path = [];
for (let i = 0; i < 5; i++) {
path[i] = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
path[i].onMouseDrag = function(event) {
path[i].position += event.delta;
console.log("shape " + i + " is being dragged.")
};
}
关闭
无需修改 PaperScript 解析器,您可以使用 closure 在新函数范围内捕获索引:
var path = [];
function createMouseDragHandler(index) {
return function(event) {
path[index].position += event.delta;
console.log("shape " + index + " is being dragged.")
};
}
for (var i = 0; i < 5; i++) {
path[i] = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
path[i].onMouseDrag = createMouseDragHandler(i);
}