Fixed drag behavior. Now drag of icon itself rather than container element. This allows for finer selection (no overlap of transparent areas), and positioning of icon precisely onto a target. This breaks labels - TODO fix.
This commit is contained in:
committed by
Alexander Kryklia
parent
a0f99ac3ce
commit
2e08ece7ff
@@ -22,18 +22,31 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
normalizeEvent(event);
|
||||
|
||||
if (state.currentMovingDraggable !== null) {
|
||||
state.currentMovingDraggable.css('left', event.pageX - state.baseImageEl.offset().left - 50);
|
||||
state.currentMovingDraggable.css('top', event.pageY - state.baseImageEl.offset().top - 50);
|
||||
state.currentMovingDraggable.iconEl.css(
|
||||
'left',
|
||||
event.pageX -
|
||||
state.baseImageEl.offset().left -
|
||||
state.currentMovingDraggable.iconWidth * 0.5
|
||||
);
|
||||
state.currentMovingDraggable.iconEl.css(
|
||||
'top',
|
||||
event.pageY -
|
||||
state.baseImageEl.offset().top -
|
||||
state.currentMovingDraggable.iconHeight * 0.5
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
function processDraggable(obj, objIndex) {
|
||||
var draggableContainerEl, inContainer, mousePressed, onTarget,
|
||||
draggableObj, marginCss;
|
||||
var inContainer, mousePressed, onTarget, draggableObj, marginCss;
|
||||
|
||||
draggableContainerEl = $(
|
||||
draggableObj = {};
|
||||
|
||||
draggableObj.zIndex = objIndex;
|
||||
|
||||
draggableObj.containerEl = $(
|
||||
'<div ' +
|
||||
'style=" ' +
|
||||
'width: 100px; ' +
|
||||
@@ -44,71 +57,84 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
'z-index: ' + objIndex + '; ' +
|
||||
'border: 1px solid #CCC; ' +
|
||||
'text-align: center; ' +
|
||||
'position: relative; ' +
|
||||
'" ' +
|
||||
'data-draggable-position-index="' + objIndex + '" ' +
|
||||
'></div>'
|
||||
);
|
||||
draggableObj.containerEl.appendTo(state.sliderEl);
|
||||
|
||||
if (obj.icon.length > 0) {
|
||||
draggableContainerEl.append(
|
||||
$('<img src="' + state.config.imageDir + '/' + obj.icon + '" />')
|
||||
draggableObj.iconEl = $('<img />');
|
||||
draggableObj.iconEl.attr(
|
||||
'src',
|
||||
state.config.imageDir + '/' + obj.icon
|
||||
);
|
||||
draggableObj.iconEl.load(function () {
|
||||
draggableObj.iconWidth = this.width;
|
||||
draggableObj.iconHeight = this.height;
|
||||
|
||||
draggableObj.iconEl.css('position', 'absolute');
|
||||
draggableObj.iconEl.css('top', (50 - this.height * 0.5) + 'px');
|
||||
draggableObj.iconEl.css('left', (50 - this.width * 0.5) + 'px');
|
||||
|
||||
draggableObj.iconEl.appendTo(draggableObj.containerEl);
|
||||
});
|
||||
|
||||
draggableObj.iconEl.mousedown(mouseDown);
|
||||
draggableObj.iconEl.mouseup(mouseUp);
|
||||
draggableObj.iconEl.mousemove(mouseMove);
|
||||
} else {
|
||||
// Must fix - add +label support, and just label support.
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj.label.length > 0) {
|
||||
marginCss = '';
|
||||
// if (obj.label.length > 0) {
|
||||
// marginCss = '';
|
||||
//
|
||||
// if (obj.icon.length === 0) {
|
||||
// marginCss = 'margin-top: 38px;';
|
||||
// }
|
||||
|
||||
if (obj.icon.length === 0) {
|
||||
marginCss = 'margin-top: 38px;';
|
||||
}
|
||||
|
||||
draggableContainerEl.append(
|
||||
$('<div style="clear: both; text-align: center; ' + marginCss + ' ">' + obj.label + '</div>')
|
||||
);
|
||||
}
|
||||
|
||||
draggableContainerEl.appendTo(state.sliderEl);
|
||||
// draggableContainerEl.append(
|
||||
// $('<div style="clear: both; text-align: center; ' + marginCss + ' ">' + obj.label + '</div>')
|
||||
// );
|
||||
// }
|
||||
|
||||
inContainer = true;
|
||||
mousePressed = false;
|
||||
|
||||
onTarget = null;
|
||||
|
||||
draggableObj = {
|
||||
'id': obj.id,
|
||||
'el': draggableContainerEl,
|
||||
'x': -1,
|
||||
'y': -1,
|
||||
draggableObj.id = obj.id;
|
||||
draggableObj.x = -1;
|
||||
draggableObj.y = -1;
|
||||
|
||||
draggableObj.setInContainer = function (val) { inContainer = val; };
|
||||
draggableObj.setOnTarget = function (val) { onTarget = val; };
|
||||
|
||||
'setInContainer': function (val) { inContainer = val; },
|
||||
'setOnTarget': function (val) { onTarget = val; },
|
||||
};
|
||||
state.draggables.push(draggableObj);
|
||||
|
||||
draggableContainerEl.mousedown(mouseDown);
|
||||
draggableContainerEl.mouseup(mouseUp);
|
||||
draggableContainerEl.mousemove(mouseMove);
|
||||
|
||||
return;
|
||||
|
||||
function mouseDown(event) {
|
||||
if (mousePressed === false) {
|
||||
state.currentMovingDraggable = draggableContainerEl;
|
||||
state.currentMovingDraggable = draggableObj;
|
||||
normalizeEvent(event);
|
||||
|
||||
if (inContainer === true) {
|
||||
draggableContainerEl.detach();
|
||||
draggableContainerEl.css('border', 'none');
|
||||
draggableContainerEl.css('position', 'absolute');
|
||||
draggableContainerEl.css('left', event.pageX - state.baseImageEl.offset().left - 50);
|
||||
draggableContainerEl.css('top', event.pageY - state.baseImageEl.offset().top - 50);
|
||||
draggableContainerEl.appendTo(state.baseImageEl.parent());
|
||||
draggableObj.containerEl.hide();
|
||||
|
||||
draggableObj.iconEl.detach();
|
||||
draggableObj.iconEl.css('left', event.pageX - state.baseImageEl.offset().left - draggableObj.iconWidth * 0.5);
|
||||
draggableObj.iconEl.css('top', event.pageY - state.baseImageEl.offset().top - draggableObj.iconHeight * 0.5);
|
||||
draggableObj.iconEl.appendTo(state.baseImageEl.parent());
|
||||
|
||||
inContainer = false;
|
||||
}
|
||||
|
||||
draggableContainerEl.attr('data-old-z-index', draggableContainerEl.css('z-index'));
|
||||
draggableContainerEl.css('z-index', '1000');
|
||||
draggableObj.oldZIndex = draggableObj.zIndex;
|
||||
draggableObj.zIndex = 1000;
|
||||
draggableObj.iconEl.css('z-index', '1000');
|
||||
|
||||
mousePressed = true;
|
||||
event.preventDefault();
|
||||
@@ -119,14 +145,14 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
if (mousePressed === true) {
|
||||
state.currentMovingDraggable = null;
|
||||
|
||||
checkLandingElement(event);
|
||||
checkLandingElement();
|
||||
}
|
||||
}
|
||||
|
||||
function mouseMove() {
|
||||
if (mousePressed === true) {
|
||||
draggableContainerEl.css('left', event.pageX - state.baseImageEl.offset().left - 50);
|
||||
draggableContainerEl.css('top', event.pageY - state.baseImageEl.offset().top - 50);
|
||||
draggableObj.iconEl.css('left', event.pageX - state.baseImageEl.offset().left - draggableObj.iconWidth * 0.5);
|
||||
draggableObj.iconEl.css('top', event.pageY - state.baseImageEl.offset().top - draggableObj.iconHeight * 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,11 +162,11 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
// the input with the user's answer (X-Y position of the draggable,
|
||||
// or the ID of the target where it landed.
|
||||
function checkLandingElement() {
|
||||
var offsetDE, indexes, DEindex, targetFound;
|
||||
var offsetIE, targetFound;
|
||||
|
||||
mousePressed = false;
|
||||
|
||||
offsetDE = draggableContainerEl.position();
|
||||
offsetIE = draggableObj.iconEl.position();
|
||||
|
||||
if (state.individualTargets === true) {
|
||||
targetFound = false;
|
||||
@@ -155,10 +181,10 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
(offsetDE.left < 0) ||
|
||||
(offsetDE.left + 100 > state.baseImageEl.width()) ||
|
||||
(offsetDE.top < 0) ||
|
||||
(offsetDE.top + 100 > state.baseImageEl.height())
|
||||
(offsetIE.left < 0) ||
|
||||
(offsetIE.left + draggableObj.iconWidth > state.baseImageEl.width()) ||
|
||||
(offsetIE.top < 0) ||
|
||||
(offsetIE.top + draggableObj.iconHeight > state.baseImageEl.height())
|
||||
) {
|
||||
moveBackToSlider();
|
||||
|
||||
@@ -182,7 +208,7 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
|
||||
if (onTarget !== null) {
|
||||
for (c1 = 0; c1 < onTarget.draggable.length; c1 += 1) {
|
||||
if (onTarget.draggable[c1] === obj.id) {
|
||||
if (onTarget.draggable[c1] === draggableObj.id) {
|
||||
onTarget.draggable.splice(c1, 1);
|
||||
|
||||
break;
|
||||
@@ -203,23 +229,23 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
for (c1 = 0; c1 < state.targets.length; c1 += 1) {
|
||||
target = state.targets[c1];
|
||||
|
||||
if (offsetDE.top + 50 < target.offset.top) {
|
||||
if (offsetIE.top + draggableObj.iconHeight * 0.5 < target.offset.top) {
|
||||
continue;
|
||||
}
|
||||
if (offsetDE.top + 50 > target.offset.top + target.h) {
|
||||
if (offsetIE.top + draggableObj.iconHeight * 0.5 > target.offset.top + target.h) {
|
||||
continue;
|
||||
}
|
||||
if (offsetDE.left + 50 < target.offset.left) {
|
||||
if (offsetIE.left + draggableObj.iconWidth * 0.5 < target.offset.left) {
|
||||
continue;
|
||||
}
|
||||
if (offsetDE.left + 50 > target.offset.left + target.w) {
|
||||
if (offsetIE.left + draggableObj.iconWidth * 0.5 > target.offset.left + target.w) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
(state.config.one_per_target === true) &&
|
||||
(target.draggable.length === 1) &&
|
||||
(target.draggable[0] !== obj.id)
|
||||
(target.draggable[0] !== draggableObj.id)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@@ -233,10 +259,10 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
if ((onTarget !== null) && (onTarget.id !== target.id)) {
|
||||
removeObjIdFromTarget();
|
||||
onTarget = target;
|
||||
target.draggable.push(obj.id);
|
||||
target.draggable.push(draggableObj.id);
|
||||
} else if (onTarget === null) {
|
||||
onTarget = target;
|
||||
target.draggable.push(obj.id);
|
||||
target.draggable.push(draggableObj.id);
|
||||
}
|
||||
|
||||
// Reposition the draggable so that it's center
|
||||
@@ -248,8 +274,15 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
}
|
||||
|
||||
function snapToTarget(target) {
|
||||
draggableContainerEl.css('left', target.offset.left + 0.5 * target.w - 50);
|
||||
draggableContainerEl.css('top', target.offset.top + 0.5 * target.h - 50);
|
||||
var offset;
|
||||
|
||||
offset = 0;
|
||||
if (state.config.targetOutline === true) {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
draggableObj.iconEl.css('left', target.offset.left + 0.5 * target.w - draggableObj.iconWidth * 0.5 + offset);
|
||||
draggableObj.iconEl.css('top', target.offset.top + 0.5 * target.h - draggableObj.iconHeight * 0.5 + offset);
|
||||
}
|
||||
|
||||
// Go through all of the draggables subtract 1 from the z-index
|
||||
@@ -266,18 +299,17 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
var c1;
|
||||
|
||||
for (c1 = 0; c1 < state.draggables.length; c1++) {
|
||||
if (
|
||||
parseInt(draggableContainerEl.attr('data-old-z-index'), 10) <
|
||||
parseInt(state.draggables[c1].el.css('z-index'), 10)
|
||||
) {
|
||||
state.draggables[c1].el.css(
|
||||
if (draggableObj.oldZIndex < state.draggables[c1].zIndex) {
|
||||
state.draggables[c1].zIndex -= 1;
|
||||
state.draggables[c1].iconEl.css(
|
||||
'z-index',
|
||||
parseInt(state.draggables[c1].el.css('z-index'), 10) - 1
|
||||
state.draggables[c1].zIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
draggableContainerEl.css('z-index', c1);
|
||||
draggableObj.zIndex = c1;
|
||||
draggableObj.iconEl.css('z-index', c1);
|
||||
}
|
||||
|
||||
// If a draggable was released in a wrong positione, we will
|
||||
@@ -286,47 +318,16 @@ define(['logme', 'update_input'], function (logme, updateInput) {
|
||||
function moveBackToSlider() {
|
||||
var c1;
|
||||
|
||||
draggableContainerEl.detach();
|
||||
draggableContainerEl.css('position', 'static');
|
||||
draggableObj.containerEl.show();
|
||||
|
||||
// Get the position indexes of all draggables that are
|
||||
// currently in the slider, along with the corresponding
|
||||
// jQuery element.
|
||||
indexes = [];
|
||||
state.sliderEl.children().each(function (index, value) {
|
||||
indexes.push({
|
||||
'index': parseInt($(value).attr('data-draggable-position-index'), 10),
|
||||
'el': $(value)
|
||||
});
|
||||
});
|
||||
draggableObj.iconEl.detach();
|
||||
|
||||
// Get the position index of the element that we are
|
||||
// inserting back into the slider.
|
||||
DEindex = parseInt(draggableContainerEl.attr('data-draggable-position-index'), 10);
|
||||
draggableObj.iconEl.css('top', (50 - draggableObj.iconHeight * 0.5) + 'px');
|
||||
draggableObj.iconEl.css('left', (50 - draggableObj.iconWidth * 0.5) + 'px');
|
||||
|
||||
// Starting from the first position index that we
|
||||
// retrieved, and going up, if we find a position index
|
||||
// that is more than 'DEindex', we know that we must insert
|
||||
// the current element before the element with the greater
|
||||
// position index.
|
||||
for (c1 = 0; c1 < indexes.length; c1 += 1) {
|
||||
if ((inContainer === false) && (indexes[c1].index > DEindex)) {
|
||||
indexes[c1].el.before(draggableContainerEl);
|
||||
inContainer = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we did not find a greater postion index, then either
|
||||
// there are no elements in the slider, or all of them
|
||||
// have a lesser position index. In both cases we add the
|
||||
// current draggable to the end.
|
||||
if (inContainer === false) {
|
||||
draggableContainerEl.appendTo(state.sliderEl);
|
||||
}
|
||||
draggableObj.iconEl.appendTo(draggableObj.containerEl);
|
||||
|
||||
inContainer = true;
|
||||
|
||||
draggableContainerEl.css('border', '1px solid gray');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user