Commit ead346ee by Valera Rozuvan Committed by Alexander Kryklia

Refactoring. New feature: adding multiple draggables from one.

parent e2bbaf08
...@@ -5,189 +5,170 @@ ...@@ -5,189 +5,170 @@
(function (requirejs, require, define) { (function (requirejs, require, define) {
define(['logme', 'update_input'], function (logme, updateInput) { define(['logme', 'update_input'], function (logme, updateInput) {
return Draggables; return {
'init': init
};
function Draggables(state) { function init(state) {
var c1; logme('Draggables.init; state = ', state);
state.draggables = []; state.draggables = [];
state.numDraggablesInSlider = 0; state.numDraggablesInSlider = 0;
state.currentMovingDraggable = null;
for (c1 = 0; c1 < state.config.draggables.length; c1 += 1) { (function (c1) {
processDraggable(state.config.draggables[c1], c1 + 1); while (c1 < state.config.draggables.length) {
} processDraggable(state, state.config.draggables[c1], c1 + 1);
c1 += 1
}
}(0));
state.updateArrowOpacity(); state.updateArrowOpacity();
state.currentMovingDraggable = null;
$(document).mousemove(function (event) { $(document).mousemove(function (event) {
if (state.currentMovingDraggable !== null) { documentMouseMove(state, event);
state.currentMovingDraggable.iconEl.css( });
}
function documentMouseMove(state, event) {
if (state.currentMovingDraggable !== null) {
state.currentMovingDraggable.iconEl.css(
'left',
event.pageX -
state.baseImageEl.offset().left -
state.currentMovingDraggable.iconWidth * 0.5
- state.currentMovingDraggable.iconElLeftOffset
);
state.currentMovingDraggable.iconEl.css(
'top',
event.pageY -
state.baseImageEl.offset().top -
state.currentMovingDraggable.iconHeight * 0.5
);
if (state.currentMovingDraggable.labelEl !== null) {
state.currentMovingDraggable.labelEl.css(
'left', 'left',
event.pageX - event.pageX -
state.baseImageEl.offset().left - state.baseImageEl.offset().left -
state.currentMovingDraggable.iconWidth * 0.5 state.currentMovingDraggable.labelWidth * 0.5
- state.currentMovingDraggable.iconElLeftOffset - 9 // Account for padding, border.
); );
state.currentMovingDraggable.iconEl.css( state.currentMovingDraggable.labelEl.css(
'top', 'top',
event.pageY - event.pageY -
state.baseImageEl.offset().top - state.baseImageEl.offset().top +
state.currentMovingDraggable.iconHeight * 0.5 state.currentMovingDraggable.iconHeight * 0.5 +
5
); );
if (state.currentMovingDraggable.labelEl !== null) {
state.currentMovingDraggable.labelEl.css(
'left',
event.pageX -
state.baseImageEl.offset().left -
state.currentMovingDraggable.labelWidth * 0.5
- 9 // Account for padding, border.
);
state.currentMovingDraggable.labelEl.css(
'top',
event.pageY -
state.baseImageEl.offset().top +
state.currentMovingDraggable.iconHeight * 0.5 +
5
);
}
} }
}); }
}
return; function processDraggable(state, obj, objIndex) {
var draggableObj;
function processDraggable(obj, objIndex) {
var inContainer, mousePressed, onTarget, draggableObj; logme('processDraggable; state = ', state);
draggableObj = { logme('Processing draggable #' + objIndex);
'zIndex': objIndex,
'oldZIndex': objIndex, draggableObj = {
'labelEl': null, 'zIndex': objIndex,
'hasLoaded': false 'oldZIndex': objIndex,
}; 'labelEl': null,
'hasLoaded': false,
draggableObj.containerEl = $( 'inContainer': true,
'<div ' + 'mousePressed': false,
'style=" ' + 'onTarget': null,
'width: 100px; ' +
'height: 100px; ' + 'state': state,
'display: inline; ' +
'float: left; ' + 'mouseDown': mouseDown,
'overflow: hidden; ' + 'mouseUp': mouseUp,
'z-index: ' + objIndex + '; ' + 'mouseMove': mouseMove,
'border-left: 1px solid #CCC; ' + 'checkLandingElement': checkLandingElement,
'border-right: 1px solid #CCC; ' + 'removeObjIdFromTarget': removeObjIdFromTarget,
'text-align: center; ' + 'checkIfOnTarget': checkIfOnTarget,
'position: relative; ' + 'snapToTarget': snapToTarget,
'" ' + 'correctZIndexes': correctZIndexes,
'></div>' 'moveBackToSlider': moveBackToSlider
};
draggableObj.containerEl = $(
'<div ' +
'style=" ' +
'width: 100px; ' +
'height: 100px; ' +
'display: inline; ' +
'float: left; ' +
'overflow: hidden; ' +
'z-index: ' + objIndex + '; ' +
'border-left: 1px solid #CCC; ' +
'border-right: 1px solid #CCC; ' +
'text-align: center; ' +
'position: relative; ' +
'" ' +
'></div>'
);
draggableObj.containerEl.appendTo(state.sliderEl);
if (obj.icon.length > 0) {
draggableObj.iconElBGColor = 'transparent';
draggableObj.iconElPadding = 0;
draggableObj.iconElBorder = 'none';
draggableObj.iconElLeftOffset = 0;
draggableObj.iconEl = $('<img />');
draggableObj.iconEl.attr(
'src',
obj.icon
); );
draggableObj.iconEl.load(function () {
draggableObj.iconWidth = this.width;
draggableObj.iconHeight = this.height;
if (draggableObj.iconWidth >= draggableObj.iconHeight) {
draggableObj.iconWidthSmall = 60;
draggableObj.iconHeightSmall =
draggableObj.iconWidthSmall *
(draggableObj.iconHeight / draggableObj.iconWidth);
} else {
draggableObj.iconHeightSmall = 60;
draggableObj.iconWidthSmall =
draggableObj.iconHeightSmall *
(draggableObj.iconWidth / draggableObj.iconHeight);
}
draggableObj.containerEl.appendTo(state.sliderEl); draggableObj.iconEl.css('position', 'absolute');
if (obj.icon.length > 0) {
draggableObj.iconElBGColor = 'transparent';
draggableObj.iconElPadding = 0;
draggableObj.iconElBorder = 'none';
draggableObj.iconElLeftOffset = 0;
draggableObj.iconEl = $('<img />'); draggableObj.iconEl.css(
draggableObj.iconEl.attr( 'width',
'src', draggableObj.iconWidthSmall
obj.icon );
draggableObj.iconEl.css(
'height',
draggableObj.iconHeightSmall
); );
draggableObj.iconEl.load(function () {
draggableObj.iconWidth = this.width;
draggableObj.iconHeight = this.height;
if (draggableObj.iconWidth >= draggableObj.iconHeight) {
draggableObj.iconWidthSmall = 60;
draggableObj.iconHeightSmall =
draggableObj.iconWidthSmall *
(draggableObj.iconHeight / draggableObj.iconWidth);
} else {
draggableObj.iconHeightSmall = 60;
draggableObj.iconWidthSmall =
draggableObj.iconHeightSmall *
(draggableObj.iconWidth / draggableObj.iconHeight);
}
draggableObj.iconEl.css('position', 'absolute');
draggableObj.iconEl.css( draggableObj.iconEl.css(
'width', 'left',
draggableObj.iconWidthSmall 50 - draggableObj.iconWidthSmall * 0.5
); );
draggableObj.iconEl.css(
'height',
draggableObj.iconHeightSmall
);
if (obj.label.length > 0) {
draggableObj.iconEl.css('top', 5);
} else {
draggableObj.iconEl.css( draggableObj.iconEl.css(
'left', 'top',
50 - draggableObj.iconWidthSmall * 0.5 50 - draggableObj.iconHeightSmall * 0.5
); );
}
if (obj.label.length > 0) { draggableObj.iconEl.appendTo(draggableObj.containerEl);
draggableObj.iconEl.css('top', 5);
} else {
draggableObj.iconEl.css(
'top',
50 - draggableObj.iconHeightSmall * 0.5
);
}
draggableObj.iconEl.appendTo(draggableObj.containerEl);
if (obj.label.length > 0) {
draggableObj.labelEl = $(
'<div ' +
'style=" ' +
'position: absolute; ' +
'color: black; ' +
'font-size: 0.95em; ' +
'z-index: ' + objIndex + '; ' +
'" ' +
'>' +
obj.label +
'</div>'
);
draggableObj.labelEl.appendTo(
draggableObj.containerEl
);
draggableObj.labelWidth = draggableObj.labelEl.width();
draggableObj.labelEl.css(
'left',
50 - draggableObj.labelWidth * 0.5
);
draggableObj.labelEl.css(
'top',
5 + draggableObj.iconHeightSmall + 5
);
draggableObj.labelEl.mousedown(mouseDown);
draggableObj.labelEl.mouseup(mouseUp);
draggableObj.labelEl.mousemove(mouseMove);
}
draggableObj.hasLoaded = true;
});
} else {
// To make life easier, if there is no icon, but there is a
// label, we will create a label and store it as if it was an
// icon. All the existing code will work, and the user will
// see a label instead of an icon.
if (obj.label.length > 0) { if (obj.label.length > 0) {
draggableObj.iconElBGColor = state.config.labelBgColor; draggableObj.labelEl = $(
draggableObj.iconElPadding = 8;
draggableObj.iconElBorder = '1px solid black';
draggableObj.iconElLeftOffset = 9;
draggableObj.iconEl = $(
'<div ' + '<div ' +
'style=" ' + 'style=" ' +
'position: absolute; ' + 'position: absolute; ' +
...@@ -200,599 +181,631 @@ define(['logme', 'update_input'], function (logme, updateInput) { ...@@ -200,599 +181,631 @@ define(['logme', 'update_input'], function (logme, updateInput) {
'</div>' '</div>'
); );
draggableObj.iconEl.appendTo(draggableObj.containerEl); draggableObj.labelEl.appendTo(
draggableObj.containerEl
);
draggableObj.iconWidth = draggableObj.iconEl.width(); draggableObj.labelWidth = draggableObj.labelEl.width();
draggableObj.iconHeight = draggableObj.iconEl.height();
draggableObj.iconWidthSmall = draggableObj.iconWidth;
draggableObj.iconHeightSmall = draggableObj.iconHeight;
draggableObj.iconEl.css( draggableObj.labelEl.css(
'left', 'left',
50 - draggableObj.iconWidthSmall * 0.5 50 - draggableObj.labelWidth * 0.5
); );
draggableObj.iconEl.css( draggableObj.labelEl.css(
'top', 'top',
50 - draggableObj.iconHeightSmall * 0.5 5 + draggableObj.iconHeightSmall + 5
); );
} else {
// If no icon and no label, don't create a draggable.
return;
}
}
draggableObj.iconEl.mousedown(mouseDown);
draggableObj.iconEl.mouseup(mouseUp);
draggableObj.iconEl.mousemove(mouseMove);
draggableObj.containerEl.mousedown(mouseDown);
draggableObj.containerEl.mouseup(mouseUp);
draggableObj.containerEl.mousemove(mouseMove);
inContainer = true;
mousePressed = false;
onTarget = null;
draggableObj.id = obj.id;
draggableObj.x = -1;
draggableObj.y = -1;
draggableObj.setInContainer = function (val) {
inContainer = val;
};
draggableObj.setOnTarget = function (val) {
onTarget = val;
};
state.draggables.push(draggableObj); draggableObj.labelEl.mousedown(function (event) {
draggableObj.mouseDown.call(draggableObj, event);
state.numDraggablesInSlider += 1; });
draggableObj.labelEl.mouseup(function (event) {
draggableObj.mouseUp.call(draggableObj, event);
});
draggableObj.labelEl.mousemove(function (event) {
draggableObj.mouseMove.call(draggableObj, event);
});
}
if (obj.icon.length === 0) {
draggableObj.hasLoaded = true; draggableObj.hasLoaded = true;
} });
} else {
return; // To make life easier, if there is no icon, but there is a
// label, we will create a label and store it as if it was an
// icon. All the existing code will work, and the user will
// see a label instead of an icon.
if (obj.label.length > 0) {
draggableObj.iconElBGColor = state.config.labelBgColor;
draggableObj.iconElPadding = 8;
draggableObj.iconElBorder = '1px solid black';
draggableObj.iconElLeftOffset = 9;
draggableObj.iconEl = $(
'<div ' +
'style=" ' +
'position: absolute; ' +
'color: black; ' +
'font-size: 0.95em; ' +
'z-index: ' + objIndex + '; ' +
'" ' +
'>' +
obj.label +
'</div>'
);
function mouseDown(event) { draggableObj.iconEl.appendTo(draggableObj.containerEl);
if (mousePressed === false) {
// So that the browser does not perform a default drag.
// If we don't do this, each drag operation will
// potentially cause the highlghting of the dragged element.
event.preventDefault();
// If this draggable is just being dragged out of the draggableObj.iconWidth = draggableObj.iconEl.width();
// container, we must perform some additional tasks. draggableObj.iconHeight = draggableObj.iconEl.height();
if (inContainer === true) { draggableObj.iconWidthSmall = draggableObj.iconWidth;
draggableObj.containerEl.hide(); draggableObj.iconHeightSmall = draggableObj.iconHeight;
draggableObj.iconEl.detach(); draggableObj.iconEl.css(
draggableObj.iconEl.css( 'left',
'background-color', draggableObj.iconElBGColor 50 - draggableObj.iconWidthSmall * 0.5
); );
draggableObj.iconEl.css( draggableObj.iconEl.css(
'padding-left', draggableObj.iconElPadding 'top',
); 50 - draggableObj.iconHeightSmall * 0.5
draggableObj.iconEl.css( );
'padding-right', draggableObj.iconElPadding } else {
); // If no icon and no label, don't create a draggable.
draggableObj.iconEl.css( return;
'border', draggableObj.iconElBorder }
); }
draggableObj.iconEl.css(
'width',
draggableObj.iconWidth
);
draggableObj.iconEl.css(
'height',
draggableObj.iconHeight
);
draggableObj.iconEl.css(
'left',
event.pageX -
state.baseImageEl.offset().left -
draggableObj.iconWidth * 0.5
- draggableObj.iconElLeftOffset
);
draggableObj.iconEl.css(
'top',
event.pageY -
state.baseImageEl.offset().top -
draggableObj.iconHeight * 0.5
);
draggableObj.iconEl.appendTo(
state.baseImageEl.parent()
);
if (draggableObj.labelEl !== null) { draggableObj.iconEl.mousedown(function (event) {
draggableObj.labelEl.detach(); draggableObj.mouseDown.call(draggableObj, event);
draggableObj.labelEl.css( });
'background-color', state.config.labelBgColor draggableObj.iconEl.mouseup(function (event) {
); draggableObj.mouseUp.call(draggableObj, event);
draggableObj.labelEl.css( });
'padding-left', 8 draggableObj.iconEl.mousemove(function (event) {
); draggableObj.mouseMove.call(draggableObj, event);
draggableObj.labelEl.css( });
'padding-right', 8
);
draggableObj.labelEl.css(
'border', '1px solid black'
);
draggableObj.labelEl.css(
'left',
event.pageX -
state.baseImageEl.offset().left -
draggableObj.labelWidth * 0.5
- 9 // Account for padding, border.
);
draggableObj.labelEl.css(
'top',
event.pageY -
state.baseImageEl.offset().top +
draggableObj.iconHeight * 0.5 + 5
);
draggableObj.labelEl.appendTo(
state.baseImageEl.parent()
);
}
inContainer = false; draggableObj.containerEl.mousedown(function (event) {
state.numDraggablesInSlider -= 1; draggableObj.mouseDown.call(draggableObj, event);
} });
draggableObj.containerEl.mouseup(function (event) {
draggableObj.mouseUp.call(draggableObj, event);
});
draggableObj.containerEl.mousemove(function (event) {
draggableObj.mouseMove.call(draggableObj, event);
});
draggableObj.oldZIndex = draggableObj.zIndex; draggableObj.id = obj.id;
draggableObj.zIndex = 1000; draggableObj.x = -1;
draggableObj.iconEl.css('z-index', '1000'); draggableObj.y = -1;
if (draggableObj.labelEl !== null) {
draggableObj.labelEl.css('z-index', '1000');
}
mousePressed = true; state.numDraggablesInSlider += 1;
state.currentMovingDraggable = draggableObj;
}
}
function mouseUp() { if (obj.icon.length === 0) {
if (mousePressed === true) { draggableObj.hasLoaded = true;
state.currentMovingDraggable = null; }
checkLandingElement(); state.draggables.push(draggableObj);
} }
}
function mouseMove() { function mouseDown(event) {
if (mousePressed === true) { if (this.mousePressed === false) {
// Because we have also attached a 'mousemove' event to the // So that the browser does not perform a default drag.
// 'document' (that will do the same thing), let's tell the // If we don't do this, each drag operation will
// browser not to bubble up this event. The attached event // potentially cause the highlghting of the dragged element.
// on the 'document' will only be triggered when the mouse event.preventDefault();
// pointer leaves the draggable while it is in the middle
// of a drag operation (user moves the mouse very quickly). // If this draggable is just being dragged out of the
event.stopPropagation(); // container, we must perform some additional tasks.
if (this.inContainer === true) {
this.containerEl.hide();
this.iconEl.detach();
this.iconEl.css(
'background-color', this.iconElBGColor
);
this.iconEl.css(
'padding-left', this.iconElPadding
);
this.iconEl.css(
'padding-right', this.iconElPadding
);
this.iconEl.css(
'border', this.iconElBorder
);
this.iconEl.css(
'width',
this.iconWidth
);
this.iconEl.css(
'height',
this.iconHeight
);
this.iconEl.css(
'left',
event.pageX -
this.state.baseImageEl.offset().left -
this.iconWidth * 0.5
- this.iconElLeftOffset
);
this.iconEl.css(
'top',
event.pageY -
this.state.baseImageEl.offset().top -
this.iconHeight * 0.5
);
this.iconEl.appendTo(
state.baseImageEl.parent()
);
draggableObj.iconEl.css( if (this.labelEl !== null) {
this.labelEl.detach();
this.labelEl.css(
'background-color', this.state.config.labelBgColor
);
this.labelEl.css(
'padding-left', 8
);
this.labelEl.css(
'padding-right', 8
);
this.labelEl.css(
'border', '1px solid black'
);
this.labelEl.css(
'left', 'left',
event.pageX - event.pageX -
state.baseImageEl.offset().left - this.state.baseImageEl.offset().left -
draggableObj.iconWidth * 0.5 this.labelWidth * 0.5
- draggableObj.iconElLeftOffset - 9 // Account for padding, border.
); );
draggableObj.iconEl.css( this.labelEl.css(
'top', 'top',
event.pageY - event.pageY -
state.baseImageEl.offset().top - this.state.baseImageEl.offset().top +
draggableObj.iconHeight * 0.5 this.iconHeight * 0.5 + 5
);
this.labelEl.appendTo(
this.state.baseImageEl.parent()
); );
if (draggableObj.labelEl !== null) {
draggableObj.labelEl.css(
'left',
event.pageX -
state.baseImageEl.offset().left -
draggableObj.labelWidth * 0.5
- 9 // Acoount for padding, border.
);
draggableObj.labelEl.css(
'top',
event.pageY -
state.baseImageEl.offset().top +
draggableObj.iconHeight * 0.5 +
5
);
}
} }
}
// At this point the mouse was realeased, and we need to check this.inContainer = false;
// where the draggable eneded up. Based on several things, we this.state.numDraggablesInSlider -= 1;
// will either move the draggable back to the slider, or update }
// 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 positionIE, targetFound;
mousePressed = false; this.oldZIndex = this.zIndex;
positionIE = draggableObj.iconEl.position(); this.zIndex = 1000;
this.iconEl.css('z-index', '1000');
if (this.labelEl !== null) {
this.labelEl.css('z-index', '1000');
}
if (state.individualTargets === true) { this.mousePressed = true;
targetFound = false; this.state.currentMovingDraggable = this;
}
}
checkIfOnTarget(); function mouseUp() {
if (this.mousePressed === true) {
this.state.currentMovingDraggable = null;
if (targetFound === true) { this.checkLandingElement();
correctZIndexes(); }
} else { }
moveBackToSlider();
removeObjIdFromTarget();
state.numDraggablesInSlider += 1; function mouseMove() {
} if (this.mousePressed === true) {
} else { // Because we have also attached a 'mousemove' event to the
if ( // 'document' (that will do the same thing), let's tell the
(positionIE.left < 0) || // browser not to bubble up this event. The attached event
( // on the 'document' will only be triggered when the mouse
positionIE.left + draggableObj.iconWidth > // pointer leaves the draggable while it is in the middle
state.baseImageEl.width() // of a drag operation (user moves the mouse very quickly).
) || event.stopPropagation();
(positionIE.top < 0) ||
( this.iconEl.css(
positionIE.top + draggableObj.iconHeight > 'left',
state.baseImageEl.height() event.pageX -
) this.state.baseImageEl.offset().left -
) { this.iconWidth * 0.5
moveBackToSlider(); - this.iconElLeftOffset
);
this.iconEl.css(
'top',
event.pageY -
this.state.baseImageEl.offset().top -
this.iconHeight * 0.5
);
draggableObj.x = -1; if (this.labelEl !== null) {
draggableObj.y = -1; this.labelEl.css(
'left',
event.pageX -
this.state.baseImageEl.offset().left -
this.labelWidth * 0.5
- 9 // Acoount for padding, border.
);
this.labelEl.css(
'top',
event.pageY -
this.state.baseImageEl.offset().top +
this.iconHeight * 0.5 +
5
);
}
}
}
state.numDraggablesInSlider += 1; // At this point the mouse was realeased, and we need to check
} else { // where the draggable eneded up. Based on several things, we
correctZIndexes(); // will either move the draggable back to the slider, or update
// 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 positionIE;
draggableObj.x = this.mousePressed = false;
positionIE.left + draggableObj.iconWidth * 0.5; positionIE = this.iconEl.position();
draggableObj.y =
positionIE.top + draggableObj.iconHeight * 0.5;
}
}
state.updateArrowOpacity(); if (this.state.individualTargets === true) {
updateInput(state); if (this.checkIfOnTarget(positionIE) === true) {
this.correctZIndexes();
} else {
this.moveBackToSlider();
this.removeObjIdFromTarget();
return; this.state.numDraggablesInSlider += 1;
}
} else {
if (
(positionIE.left < 0) ||
(
positionIE.left + this.iconWidth >
this.state.baseImageEl.width()
) ||
(positionIE.top < 0) ||
(
positionIE.top + this.iconHeight >
this.state.baseImageEl.height()
)
) {
this.moveBackToSlider();
this.x = -1;
this.y = -1;
this.state.numDraggablesInSlider += 1;
} else {
this.correctZIndexes();
function removeObjIdFromTarget() { this.x =
var c1; positionIE.left + this.iconWidth * 0.5;
this.y =
positionIE.top + this.iconHeight * 0.5;
}
}
if (onTarget !== null) { this.state.updateArrowOpacity();
for (c1 = 0; c1 < onTarget.draggable.length; c1 += 1) { updateInput(this.state);
if (onTarget.draggable[c1] === draggableObj.id) { }
onTarget.draggable.splice(c1, 1);
break; function removeObjIdFromTarget() {
} var c1;
}
if (onTarget.numTextEl !== null) { if (this.onTarget !== null) {
onTarget.updateNumTextEl(); for (c1 = 0; c1 < this.onTarget.draggable.length; c1 += 1) {
} if (this.onTarget.draggable[c1] === this.id) {
this.onTarget.draggable.splice(c1, 1);
onTarget = null; break;
}
} }
}
// if (this.onTarget.numTextEl !== null) {
// Determine if a draggable, after it was relased, ends up on a this.onTarget.updateNumTextEl();
// target. We do this by iterating over all of the targets, and }
// for each one we check whether the draggable's center is
// within the target's dimensions.
//
// positionIE is the object as returned by
//
// draggableObj.iconEl.position()
//
function checkIfOnTarget() {
var c1, target;
for (c1 = 0; c1 < state.targets.length; c1 += 1) {
target = state.targets[c1];
// If only one draggable per target is allowed, and
// the current target already has a draggable on it
// (with an ID different from the one we are checking
// against), then go to next target.
if (
(state.config.one_per_target === true) &&
(target.draggable.length === 1) &&
(target.draggable[0] !== draggableObj.id)
) {
continue;
}
// Check if the draggable's center coordinate is within this.onTarget = null;
// the target's dimensions. If not, go to next target. }
if ( }
positionIE.top + draggableObj.iconHeight * 0.5 <
target.offset.top
) {
continue;
}
if (
positionIE.top + draggableObj.iconHeight * 0.5 >
target.offset.top + target.h
) {
continue;
}
if (
positionIE.left + draggableObj.iconWidth * 0.5 <
target.offset.left
) {
continue;
}
if (
positionIE.left + draggableObj.iconWidth * 0.5 >
target.offset.left + target.w
) {
continue;
}
// If we got here, then our draggable is on top of a //
// target. // Determine if a draggable, after it was relased, ends up on a
targetFound = true; // target. We do this by iterating over all of the targets, and
// for each one we check whether the draggable's center is
// within the target's dimensions.
//
// positionIE is the object as returned by
//
// this.iconEl.position()
//
function checkIfOnTarget(positionIE) {
var c1, target, targetFound;
targetFound = false;
for (c1 = 0; c1 < this.state.targets.length; c1 += 1) {
target = this.state.targets[c1];
// If only one draggable per target is allowed, and
// the current target already has a draggable on it
// (with an ID different from the one we are checking
// against), then go to next target.
if (
(this.state.config.one_per_target === true) &&
(target.draggable.length === 1) &&
(target.draggable[0] !== this.id)
) {
continue;
}
// If the draggable was moved from one target to // Check if the draggable's center coordinate is within
// another, then we need to remove it's ID from the // the target's dimensions. If not, go to next target.
// previous target's draggables list, and add it to the if (
// new target's draggables list. positionIE.top + this.iconHeight * 0.5 <
if ( target.offset.top
(onTarget !== null) && ) {
(onTarget.id !== target.id) continue;
) { }
removeObjIdFromTarget(); if (
onTarget = target; positionIE.top + this.iconHeight * 0.5 >
target.draggable.push(draggableObj.id); target.offset.top + target.h
} ) {
// If the draggable was moved from the slider to a continue;
// target, remember the target, and add ID to the }
// target's draggables list. if (
else if (onTarget === null) { positionIE.left + this.iconWidth * 0.5 <
onTarget = target; target.offset.left
target.draggable.push(draggableObj.id); ) {
} continue;
}
if (
positionIE.left + this.iconWidth * 0.5 >
target.offset.left + target.w
) {
continue;
}
if (target.numTextEl !== null) { // If we got here, then our draggable is on top of a
target.updateNumTextEl(); // target.
} targetFound = true;
// If the draggable was moved from one target to
// another, then we need to remove it's ID from the
// previous target's draggables list, and add it to the
// new target's draggables list.
if (
(this.onTarget !== null) &&
(this.onTarget.id !== target.id)
) {
this.removeObjIdFromTarget();
this.onTarget = target;
target.draggable.push(this.id);
}
// If the draggable was moved from the slider to a
// target, remember the target, and add ID to the
// target's draggables list.
else if (this.onTarget === null) {
this.onTarget = target;
target.draggable.push(this.id);
}
// Reposition the draggable so that it's center if (target.numTextEl !== null) {
// coincides with the center of the target. target.updateNumTextEl();
snapToTarget(target); }
break; // Reposition the draggable so that it's center
} // coincides with the center of the target.
} this.snapToTarget(target);
function snapToTarget(target) { break;
var offset; }
offset = 0; return targetFound;
if (state.config.targetOutline === true) { }
offset = 1;
}
draggableObj.iconEl.css( function snapToTarget(target) {
'left', var offset;
target.offset.left + 0.5 * target.w -
draggableObj.iconWidth * 0.5 + offset
- draggableObj.iconElLeftOffset
);
draggableObj.iconEl.css(
'top',
target.offset.top + 0.5 * target.h -
draggableObj.iconHeight * 0.5 + offset
);
if (draggableObj.labelEl !== null) { offset = 0;
draggableObj.labelEl.css( if (this.state.config.targetOutline === true) {
'left', offset = 1;
target.offset.left + 0.5 * target.w - }
draggableObj.labelWidth * 0.5 + offset
- 9 // Acoount for padding, border. this.iconEl.css(
); 'left',
draggableObj.labelEl.css( target.offset.left + 0.5 * target.w -
'top', this.iconWidth * 0.5 + offset
target.offset.top + 0.5 * target.h + - this.iconElLeftOffset
draggableObj.iconHeight * 0.5 + 5 + offset );
); this.iconEl.css(
'top',
target.offset.top + 0.5 * target.h -
this.iconHeight * 0.5 + offset
);
if (this.labelEl !== null) {
this.labelEl.css(
'left',
target.offset.left + 0.5 * target.w -
this.labelWidth * 0.5 + offset
- 9 // Acoount for padding, border.
);
this.labelEl.css(
'top',
target.offset.top + 0.5 * target.h +
this.iconHeight * 0.5 + 5 + offset
);
}
}
// Go through all of the draggables subtract 1 from the z-index
// of all whose z-index is higher than the old z-index of the
// current element. After, set the z-index of the current
// element to 1 + N (where N is the number of draggables - i.e.
// the highest z-index possible).
//
// This will make sure that after releasing a draggable, it
// will be on top of all of the other draggables. Also, the
// ordering of the visibility (z-index) of the other draggables
// will not change.
function correctZIndexes() {
var draggablesInMe, c1, c2, highestZIndex;
if (this.state.individualTargets === true) {
if (this.onTarget.draggable.length > 0) {
draggablesInMe = [];
for (c1 = 0; c1 < this.onTarget.draggable.length; c1 += 1) {
for (c2 = 0; c2 < this.state.draggables.length; c2 += 1) {
if (
this.onTarget.draggable[c1] ===
this.state.draggables[c2].id
) {
draggablesInMe.push(this.state.draggables[c2]);
}
} }
} }
// Go through all of the draggables subtract 1 from the z-index highestZIndex = -10000;
// of all whose z-index is higher than the old z-index of the
// current element. After, set the z-index of the current
// element to 1 + N (where N is the number of draggables - i.e.
// the highest z-index possible).
//
// This will make sure that after releasing a draggable, it
// will be on top of all of the other draggables. Also, the
// ordering of the visibility (z-index) of the other draggables
// will not change.
function correctZIndexes() {
var draggablesInMe, c1, c2, highestZIndex;
if (state.individualTargets === true) {
logme('In correctZIndexes.');
if (onTarget.draggable.length > 0) {
logme('onTarget.draggable.length > 0');
draggablesInMe = [];
for (c1 = 0; c1 < onTarget.draggable.length; c1 += 1) {
for (c2 = 0; c2 < state.draggables.length; c2 += 1) {
if (
onTarget.draggable[c1] ===
state.draggables[c2].id
) {
draggablesInMe.push(state.draggables[c2]);
}
}
}
highestZIndex = -10000;
for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
if (
(draggablesInMe[c1].zIndex > highestZIndex) &&
(draggablesInMe[c1].zIndex !== 1000)
) {
highestZIndex = draggablesInMe[c1].zIndex;
}
}
if (highestZIndex === -10000) {
highestZIndex = onTarget.draggable.length;
} else if (highestZIndex < draggableObj.oldZIndex) {
highestZIndex = draggableObj.oldZIndex;
} else {
for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
logme('draggablesInMe[' + c1 + '].id = ' + draggablesInMe[c1].id);
logme('draggablesInMe[' + c1 + '].zIndex = ' + draggablesInMe[c1].zIndex);
logme('draggablesInMe[' + c1 + '].oldZIndex = ' + draggablesInMe[c1].oldZIndex);
}
logme('----------------');
logme('highestZIndex = ' + highestZIndex);
for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
draggablesInMe[c1].zIndex -= 1;
draggablesInMe[c1].oldZIndex -= 1;
draggablesInMe[c1].iconEl.css(
'z-index',
draggablesInMe[c1].zIndex
);
if (draggablesInMe[c1].labelEl !== null) {
draggablesInMe[c1].labelEl.css(
'z-index',
draggablesInMe[c1].zIndex
);
}
}
}
} else {
logme('highestZIndex = onTarget.draggable.length');
highestZIndex = onTarget.draggable.length;
}
draggableObj.zIndex = highestZIndex; for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
draggableObj.oldZIndex = highestZIndex; if (
(draggablesInMe[c1].zIndex > highestZIndex) &&
(draggablesInMe[c1].zIndex !== 1000)
) {
highestZIndex = draggablesInMe[c1].zIndex;
}
}
draggableObj.iconEl.css( if (highestZIndex === -10000) {
highestZIndex = this.onTarget.draggable.length;
} else if (highestZIndex < this.oldZIndex) {
highestZIndex = this.oldZIndex;
} else {
for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
draggablesInMe[c1].zIndex -= 1;
draggablesInMe[c1].oldZIndex -= 1;
draggablesInMe[c1].iconEl.css(
'z-index', 'z-index',
draggableObj.zIndex draggablesInMe[c1].zIndex
); );
if (draggableObj.labelEl !== null) { if (draggablesInMe[c1].labelEl !== null) {
draggableObj.labelEl.css( draggablesInMe[c1].labelEl.css(
'z-index', 'z-index',
draggableObj.zIndex draggablesInMe[c1].zIndex
); );
} }
} else {
for (c1 = 0; c1 < state.draggables.length; c1++) {
if (
draggableObj.oldZIndex <
state.draggables[c1].zIndex
) {
state.draggables[c1].zIndex -= 1;
state.draggables[c1].oldZIndex = state.draggables[c1].zIndex;
state.draggables[c1].iconEl.css(
'z-index',
state.draggables[c1].zIndex
);
if (state.draggables[c1].labelEl !== null) {
state.draggables[c1].labelEl.css(
'z-index',
state.draggables[c1].zIndex
);
}
}
}
draggableObj.zIndex = c1;
draggableObj.oldZIndex = c1;
draggableObj.iconEl.css('z-index', c1);
if (draggableObj.labelEl !== null) {
draggableObj.labelEl.css('z-index', c1);
}
} }
} }
} else {
highestZIndex = this.onTarget.draggable.length;
}
// If a draggable was released in a wrong positione, we will this.zIndex = highestZIndex;
// move it back to the slider, placing it in the same position this.oldZIndex = highestZIndex;
// that it was dragged out of.
function moveBackToSlider() {
draggableObj.containerEl.show();
draggableObj.zIndex = draggableObj.oldZIndex;
draggableObj.iconEl.detach(); this.iconEl.css(
draggableObj.iconEl.css('border', 'none'); 'z-index',
draggableObj.iconEl.css('background-color', 'transparent'); this.zIndex
draggableObj.iconEl.css('padding-left', 0); );
draggableObj.iconEl.css('padding-right', 0); if (this.labelEl !== null) {
draggableObj.iconEl.css('z-index', draggableObj.zIndex); this.labelEl.css(
draggableObj.iconEl.css( 'z-index',
'width', this.zIndex
draggableObj.iconWidthSmall );
); }
draggableObj.iconEl.css( } else {
'height', for (c1 = 0; c1 < this.state.draggables.length; c1++) {
draggableObj.iconHeightSmall if (
); this.oldZIndex <
draggableObj.iconEl.css( this.state.draggables[c1].zIndex
'left', ) {
50 - draggableObj.iconWidthSmall * 0.5 this.state.draggables[c1].zIndex -= 1;
this.state.draggables[c1].oldZIndex = this.state.draggables[c1].zIndex;
this.state.draggables[c1].iconEl.css(
'z-index',
this.state.draggables[c1].zIndex
); );
if (draggableObj.labelEl !== null) {
draggableObj.iconEl.css('top', 5);
} else {
draggableObj.iconEl.css(
'top',
50 - draggableObj.iconHeightSmall * 0.5
);
}
draggableObj.iconEl.appendTo(draggableObj.containerEl); if (this.state.draggables[c1].labelEl !== null) {
this.state.draggables[c1].labelEl.css(
if (draggableObj.labelEl !== null) { 'z-index',
draggableObj.labelEl.detach(); this.state.draggables[c1].zIndex
draggableObj.labelEl.css('border', 'none');
draggableObj.labelEl.css('background-color', 'transparent');
draggableObj.labelEl.css('padding-left', 0);
draggableObj.labelEl.css('padding-right', 0);
draggableObj.labelEl.css('z-index', draggableObj.zIndex);
draggableObj.labelEl.css(
'left',
50 - draggableObj.labelWidth * 0.5
);
draggableObj.labelEl.css(
'top',
5 + draggableObj.iconHeightSmall + 5
);
draggableObj.labelEl.appendTo(
draggableObj.containerEl
); );
} }
inContainer = true;
} }
} }
this.zIndex = c1;
this.oldZIndex = c1;
this.iconEl.css('z-index', c1);
if (this.labelEl !== null) {
this.labelEl.css('z-index', c1);
}
}
}
// If a draggable was released in a wrong positione, we will
// move it back to the slider, placing it in the same position
// that it was dragged out of.
function moveBackToSlider() {
this.containerEl.show();
this.zIndex = this.oldZIndex;
this.iconEl.detach();
this.iconEl.css('border', 'none');
this.iconEl.css('background-color', 'transparent');
this.iconEl.css('padding-left', 0);
this.iconEl.css('padding-right', 0);
this.iconEl.css('z-index', this.zIndex);
this.iconEl.css(
'width',
this.iconWidthSmall
);
this.iconEl.css(
'height',
this.iconHeightSmall
);
this.iconEl.css(
'left',
50 - this.iconWidthSmall * 0.5
);
if (this.labelEl !== null) {
this.iconEl.css('top', 5);
} else {
this.iconEl.css(
'top',
50 - this.iconHeightSmall * 0.5
);
}
this.iconEl.appendTo(this.containerEl);
if (this.labelEl !== null) {
this.labelEl.detach();
this.labelEl.css('border', 'none');
this.labelEl.css('background-color', 'transparent');
this.labelEl.css('padding-left', 0);
this.labelEl.css('padding-right', 0);
this.labelEl.css('z-index', this.zIndex);
this.labelEl.css(
'left',
50 - this.labelWidth * 0.5
);
this.labelEl.css(
'top',
5 + this.iconHeightSmall + 5
);
this.labelEl.appendTo(
this.containerEl
);
} }
this.inContainer = true;
} }
}); });
......
...@@ -63,7 +63,9 @@ define( ...@@ -63,7 +63,9 @@ define(
Targets(state); Targets(state);
Scroller(state); Scroller(state);
Draggables(state); Draggables.init(state);
logme('After Draggables.init(state); state = ', state);
// Update the input element, checking first that it is not filled with // Update the input element, checking first that it is not filled with
// an answer from the server. // an answer from the server.
......
...@@ -120,15 +120,6 @@ define(['logme'], function (logme) { ...@@ -120,15 +120,6 @@ define(['logme'], function (logme) {
lowestZIndex = 10000; lowestZIndex = 10000;
for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) { for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
logme(
'draggablesInMe[' + c1 + '].id = ' + draggablesInMe[c1].id,
'draggablesInMe[' + c1 + '].zIndex = ' + draggablesInMe[c1].zIndex,
'draggablesInMe[' + c1 + '].oldZIndex = ' + draggablesInMe[c1].oldZIndex
);
}
logme('------------------');
for (c1 = 0; c1 < draggablesInMe.length; c1 += 1) {
if (draggablesInMe[c1].zIndex < lowestZIndex) { if (draggablesInMe[c1].zIndex < lowestZIndex) {
lowestZIndex = draggablesInMe[c1].zIndex; lowestZIndex = draggablesInMe[c1].zIndex;
} }
......
...@@ -10,6 +10,8 @@ define(['logme'], function (logme) { ...@@ -10,6 +10,8 @@ define(['logme'], function (logme) {
function updateInput(state, checkFirst) { function updateInput(state, checkFirst) {
var inputEl, stateStr, targets, draggables, c1, c2, tempObj; var inputEl, stateStr, targets, draggables, c1, c2, tempObj;
logme('updateInput; state = ', state);
if (checkFirst === true) { if (checkFirst === true) {
if (checkIfHasAnswer() === true) { if (checkIfHasAnswer() === true) {
return; return;
...@@ -126,7 +128,7 @@ define(['logme'], function (logme) { ...@@ -126,7 +128,7 @@ define(['logme'], function (logme) {
return; return;
} }
draggable.setInContainer(false); draggable.inContainer = false;
draggable.containerEl.hide(); draggable.containerEl.hide();
draggable.iconEl.detach(); draggable.iconEl.detach();
...@@ -196,7 +198,7 @@ define(['logme'], function (logme) { ...@@ -196,7 +198,7 @@ define(['logme'], function (logme) {
); );
} }
draggable.setOnTarget(target); draggable.onTarget = target;
target.draggable.push(draggableId); target.draggable.push(draggableId);
if (target.numTextEl !== null) { if (target.numTextEl !== null) {
...@@ -244,7 +246,7 @@ define(['logme'], function (logme) { ...@@ -244,7 +246,7 @@ define(['logme'], function (logme) {
return; return;
} }
draggable.setInContainer(false); draggable.inContainer = false;
draggable.containerEl.hide(); draggable.containerEl.hide();
draggable.iconEl.detach(); draggable.iconEl.detach();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment