我正在使用KineticJS并尝试完成一些看似简单的事情:尝试使用当前被拖动的形状来改变位置。
这个想法是:
•您在画布上拾取形状。这会触发一个mousedown
事件监听器,它会保存您拾取的形状的当前位置。
•在保持形状的同时,如果在另一个形状上触发mouseover
,则会触发该形状的事件并根据当前形状的保存位置交换其位置。
以下是我试图让其工作的相关代码:
电路板设置: 只需设置电路板并在此处调用所需的功能即可。我还没有对舞台,gameBoard或ctx做任何事情(其中一部分是因为我试图让drawImage在多幅画布上工作,但现在已经放弃了)。
class BoardView {
constructor(stage, gameBoard, ctx) {
this.stage = stage;
this.gameBoard = gameBoard;
this.ctx = ctx;
this.orbs = [[], [], [], [], []];
this.setupBoard();
}
电路板设置功能 这是我设置电路板并为每个Kinetic Circle提供在图层上渲染所需的属性的地方。也许我在这里遗漏了一些明显的东西?
setupBoard () {
for (let colIdx = 0; colIdx < 5; colIdx++) {
this.addRow(colIdx);
}
this.renderBoard();
}
addRow (colIdx) {
for (let rowIdx = 0; rowIdx < 6; rowIdx++) {
let orbType = Math.round(Math.random() * 5);
let orbColor;
if (orbType === 0) {
orbColor = "#990000";
} else if (orbType === 1) {
orbColor = "#112288";
} else if (orbType === 2) {
orbColor = "#005544";
} else if (orbType === 3) {
orbColor = "#776611";
} else if (orbType === 4) {
orbColor = "#772299";
} else {
orbColor = "#dd2277";
}
let orbject = new Kinetic.Circle({
x: (rowIdx + 0.5) * 100,
y: (colIdx + 0.5) * 100,
width: 100,
height: 100,
fill: orbColor,
draggable: true
});
this.orbs[colIdx].push(orbject);
}
}
棋盘渲染功能 这是我将所有Kinetic Circle对象添加到新图层中的位置,并在调用事件处理程序时为这些图层提供所有自己的属性。在将图层添加到舞台后,我还在此处设置了事件处理程序。我是否可能通过添加太多图层来搞乱这一点?
renderBoard () {
for (let row = 0; row < this.orbs.length; row++) {
for (let orb = 0; orb < this.orbs[row].length; orb++) {
let layer = new Kinetic.Layer();
layer.add(this.orbs[row][orb]);
layer.moving = false;
layer.orbId = `orb${row}${orb}`;
layer.pos = [this.orbs[row][orb].attrs.x, this.orbs[row][orb].attrs.y];
this.stage.add(layer);
layer.on("mousedown", this.handleMouseDown);
layer.on("mouseup", this.handleMouseUp);
layer.on("mouseout", this.handleMouseOut);
layer.on("mousemove", this.handleMouseMove);
}
}
}
鼠标事件处理程序: 这是我认为我遇到主要问题的地方。我如何处理移动鼠标以改变球体的事件,也许我做了一些非常错误的事情?
handleMouseDown (e) {
window.currentOrb = this;
console.log(window.currentOrb.orbId);
this.moving = true;
}
//handleMouseUp (e) {
// window.currentOrb = undefined;
// this.moving = false;
//}
//handleMouseOut (e) {
//}
handleMouseMove (e) {
if (window.currentOrb !== undefined && window.currentOrb.orbId != this.orbId) {
this.children[0].attrs.x = window.currentOrb.pos[0];
this.children[0].attrs.y = window.currentOrb.pos[1];
this.children[0].draw();
} else {
}
}
}
module.exports = BoardView;
我已经尝试过查看KineticJS文档和许多StackOverflow答案,希望找到一个对我有用的解决方案,但到目前为止我还没有看过和尝试过(包括有关我写这个问题的时候出现了似乎是有帮助的,我知道我到目前为止的方式可能远远没有达到我想要的最佳方式,所以我&#39 ;我可以接受任何建议,指示,回答的问题,或任何可以指引我正确指向我所缺少的东西,以使其发挥作用。
如果这有用,这里还可以看到渲染电路板时的外观。
圈子都是动力圈(为了我想要的目的而选择的球体),然后点击并拖动一个到另一个圈子,那个没有被拖动但是悬停的圈子应移动到拖动圆圈的原始位置。
谢谢!
修改
从那时起,我对代码做了一些更改。首先,我改变了向舞台添加多个图层,只改为一个:
renderBoard () {
let layer = new Kinetic.Layer();
for (let row = 0; row < this.orbs.length; row++) {
for (let orb = 0; orb < this.orbs[row].length; orb++) {
layer.add(this.orbs[row][orb]);
this.orbCanvases.push(orbCanvas.id);
}
}
this.stage.add(layer);
}
我改为将侦听器添加到orb对象中:
addRow (colIdx) {
for (let rowIdx = 0; rowIdx < 6; rowIdx++) {
//same code as before
let orbject = new Kinetic.Circle({
x: (rowIdx + 0.5) * 100, y: (colIdx + 0.5) * 100,
width: 100, height: 100,
fill: orbColor, draggable: true, pos: [rowIdx, colIdx]
});
orbject.on("mousedown", this.handleMouseDown);
orbject.on("mouseup", this.handleMouseUp);
orbject.on("mouseout", this.handleMouseOut);
orbject.on("mousemove", this.handleMouseMove);
this.orbs[colIdx].push(orbject);
}
}
这样做的好处是可以在以前更快地进行拖放操作,速度非常慢,但我仍然无法让我的对象交换位置。
要明确,我的主要问题是知道我应该改变哪些x,y值。在handleMouseMove
的那一刻,我一直试图改变:
e.target.attrs.x = newX;
e.target.attrs.y = newY;
// newX and newY can be any number
然而,无论我改变它,它都没有效果。因此,我可以帮助我知道我是否改变了错误的东西/地方,例如,我是否应该从我存储的阵列中更改Kinetic Circle?再次感谢。
编辑2:
我想我明白了!但是,我必须this.orbs
并在window.orbs
的窗口中设置它,并测试它我做了:
window.orbs[0][0].x(450);
window.orbs[0][0].draw();
这导致x位置发生变化。但把它放在一个窗口似乎不是一个好习惯吗?
编辑3:
我现在让球体连续交换,除非在mouseover
继续射击时再次交换相同的球体。但是,在mouseup
,它可以再次交换。我还必须再次设置多个图层以使mouseover
事件在持有另一个orb时起作用,但性能似乎有所改善。
我将尝试弄清楚如何让它们能够在相同的鼠标保持下连续交换,但与此同时,这是我为实现这一目的而编写的代码:
addRow (colIdx) {
for (let rowIdx = 0; rowIdx < 6; rowIdx++) {
// same code as before, changed attr given to Kinetic.Circle
let orbject = new Kinetic.Circle({
x: (rowIdx + 0.5) * 100, y: (colIdx + 0.5) * 100,
width: 100, height: 100,
fill: orbColor, draggable: true, orbId: `orb${colIdx}${rowIdx}`
});
}
}
handleMouseDown (e) {
window.currentOrb = window.orbs[e.target.attrs.orbId];
window.newX = e.target.attrs.x;
window.newY = e.target.attrs.y;
}
鼠标按下ID保存currentOrb及其X和Y
handleMouseUp (e) {
window.currentOrb.x(window.newX);
window.currentOrb.y(window.newY);
window.currentOrb.parent.clear();
window.currentOrb.parent.draw();
window.currentOrb.draw();
window.currentOrb = undefined;
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 6; j++) {
window.orbs[`orb${i}${j}`].draw();
}
}
}
当鼠标被释放时,目前所有的球体都被重新绘制,因此它们都可以被使用。我打算重构这个,所以只有这个变化的球体才会发生这种变化。
handleMouseMove (e) {
if (window.currentOrb !== undefined && (window.currentOrb.attrs.orbId !== e.target.attrs.orbId)) {
window.orbMove.pause();
window.currentTime = 0;
window.orbMove.play();
let targOrbX = e.target.attrs.x;
let targOrbY = e.target.attrs.y;
// This is the target orb that's being changed's value
// We're storing this in targOrb
e.target.x(window.newX);
e.target.y(window.newY);
e.target.parent.clear();
e.target.parent.draw();
e.target.draw();
// Here we have the previously set current orb's position becoming
// the target orb's position
window.newX = targOrbX;
window.newY = targOrbY;
// Now that the move is made, we can set the newX and Y to be the
// target orb's position once mouseup
}
}
Orb交换逻辑,用于传递一次orb,但不是如果它们在同一回合中再次传递。
答案 0 :(得分:0)
什么时候&#34;悬停&#34;正式举行?
当鼠标事件的位置进入第二个球体时?如果是,请点击测试鼠标与每个非拖动球:
// pseudo-code -- make this test for every non-dragging orb
var dx=orb[draggingIndex].x-orb[n].x;
var dy=orb[draggingIndex].y-orb[n].y;
var rSum=orb[draggingIndex].radius+orb[n].radius;
if(dx*dx+dy*dy<=rSum*rSum){
// change orb[n]'s x,y to the dragging orb's x,y (and optionally re-render)
}
当拖动球体与第二个球体相交时?如果是,则碰撞测试拖动球体与每个非拖动球体:
In [3]: np.zeros([10, 10]) - 1
Out[3]:
array([[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.]])