在Animate CC中,使用CreateJS/EaselJS API,我创建了相当数量的不同HTML5画布,所有这些画布都具有拖放元素,每次都具有渐进式功能。
为了构建拖放交互,我在 DragMovieClip 中添加了一些 EventListeners,mousedown
、pressmove
和pressup
事件。它们都具有相关的功能。
(部分)拖动影片剪辑的操作代码
/* this refers to the Drag MovieClip */
root = this;
/* Mousedown Events */
/* removingFromDrop: Detects when a Drag is removed from certain Drop */
root.on("mousedown", removingFromDrop);
/* Pressmove Events */
/* onPressMove: Moves the Drag on pressmove */
root.on("pressmove", onPressMove);
/* detectDrop: While pressmoving, detects if the Drag is over a Drop */
root.on("pressmove", detectDrop);
/* Pressup events */
/* setDragOverDrop: Releasing the left button of the mouse,
if a Drag is over a Drop, the Drag is positioned over the Drop */
root.on("pressup", setDragOverDrop);
正如我所说,所有拖放功能都是以渐进的方式实现的,因此在某些画布中,拖动不会检测到下降(故意),在其他画布中,当拖动超过一个下降时,透明度(alpha)应用于拖动,在其他画布中,拖动必须放在一个下降上或返回到其原始位置, 在其他情况下,当拖拽放在一个水滴上时,它不能掉落到其他位置;等。
在几乎所有这些实现中没有改变的是拖动在pressmove
事件上的移动方式......
按移动功能
function onPressMove(event) {
// There is more code here, but for effects
// of this question, it's irrelevant
/* In layer terms, drag must be over the drop */
root.parent.setChildIndex(event.currentTarget, root.parent.numChildren-1);
/* Drag takes the actual position of the mouse pointer */
var point = stage.globalToLocal(event.stageX, event.stageY);
event.currentTarget.x = point.x;
event.currentTarget.y = point.y;
}
。以及当它低于时它如何检测下降,也在pressmove
事件上。
检测掉线功能
function detectDrop(event){
/* The original function is more complex than this. For example, the drop detection
in the original function is being done against all the available drops.
For effects of this question, I'm simplyfying this function, doing the detection
over a single drop */
/* Initial variables */
var dropLocation; // Drop Location
var point; // Point for the collision comparison
var dropFound = false; // Drop is found? By default, no.
/* Drop is cloned. For effects of this question, the drop is a global variable. */
dropLocation = drop.clone();
/* Position of the drop is converted to local using the mouse pointer position */
point = dropLocation.globalToLocal(event.stageX, event.stageY);
/* In local coordinates, the drag intersects with the point defined before? */
if (event.currentTarget.hitTest(point.x,point.y)) {
/* If yes, the drop was found */
dropFound = true;
}
if (dropFound) {
// Irrelevant for effects of this question
}
}
只有一种情况是拖放交互无法按预期工作,这种情况是画布响应时。
当画布位于中心时没有问题,拖动移动和跌落检测都工作正常。
但是当画布变得响应时,拖动的移动工作正常,但是 当拖动超过它时,不会检测到下降。正如我到目前为止所测试的那样,阻力检测到另一个位置的某个下降,这显然不是前面提到的下降的位置。
在对拖放进行了一些类似于上面显示的核心实现的测试之后,我得到了一个解决方案,该解决方案涉及对跌落检测功能进行其他转换。
首先,point 变量现在在舞台的坐标空间内保持当前鼠标位置:
var point = stage.globalToLocal(event.stageX, event.stageY);
然后,我使用该点转换为放置的坐标空间。该转换保存在另一个点变量中:
var pointGTL = dropLocation.globalToLocal(point.x, point.y);
局部坐标中的交集测试是使用之前定义的点变量完成的:
event.currentTarget.hitTest(pointGTL.x,pointGTL.y)
现在跌落检测功能如下所示:
检测掉线功能
function detectDrop(event){
/* Initial variables */
var dropLocation; // Drop Location
var point, pointGTL; // Points for the collision comparison
var dropFound = false; // Drop is found? By default, no.
/* Drop is cloned */
dropLocation = drop.clone();
/* Position of the stage is converted to local
using the mouse pointer position */
point = stage.globalToLocal(event.stageX, event.stageY);
/* Then, the position of the drop is converted to local
using the point defined before */
pointGTL = dropLocation.globalToLocal(point.x, point.y);
/* In local coordinates, the drag intersects with the point defined before? */
if (event.currentTarget.hitTest(pointGTL.x,pointGTL.y)) {
/* If yes, the drop was found */
dropFound = true;
}
/* Rest of the code */
}
拖动在两种响应模式(适合视图或拉伸以适应)下工作正常。