Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snap multiple relative points; 'startCoords' offset #133

Merged
merged 11 commits into from
Dec 20, 2014
48 changes: 37 additions & 11 deletions demo/js/snap.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
tango = '#ff4400',
draggingAnchor = null,

snapOffset = { x: 0, y: 0 },

snapGrid = {
x: 10,
y: 10,
Expand All @@ -39,7 +41,11 @@
function drawGrid (grid, gridOffset, range) {
if (!grid.x || !grid.y) { return; }

var barLength = 16;
var barLength = 16,
offset = {
x: gridOffset.x + snapOffset.x,
y: gridOffset.y + snapOffset.y
};

guidesContext.clearRect(0, 0, width, height);

Expand All @@ -49,20 +55,20 @@
guidesContext.fillRect(0, 0, width, height);
}

for (var i = -(1 + gridOffset.x / grid.x | 0), lenX = width / grid.x + 1; i < lenX; i++) {
for (var j = -( 1 + gridOffset.y / grid.y | 0), lenY = height / grid.y + 1; j < lenY; j++) {
for (var i = -(1 + offset.x / grid.x | 0), lenX = width / grid.x + 1; i < lenX; i++) {
for (var j = -( 1 + offset.y / grid.y | 0), lenY = height / grid.y + 1; j < lenY; j++) {
if (range > 0 && range !== Infinity) {
guidesContext.circle(i * grid.x + gridOffset.x, j * grid.y + gridOffset.y, range, blue).fill();
guidesContext.circle(i * grid.x + offset.x, j * grid.y + offset.y, range, blue).fill();
}

guidesContext.beginPath();
guidesContext.moveTo(i * grid.x + gridOffset.x, j * grid.y + gridOffset.y - barLength / 2);
guidesContext.lineTo(i * grid.x + gridOffset.x, j * grid.y + gridOffset.y + barLength / 2);
guidesContext.moveTo(i * grid.x + offset.x, j * grid.y + offset.y - barLength / 2);
guidesContext.lineTo(i * grid.x + offset.x, j * grid.y + offset.y + barLength / 2);
guidesContext.stroke();

guidesContext.beginPath();
guidesContext.moveTo(i * grid.x + gridOffset.x - barLength / 2, j * grid.y + gridOffset.y);
guidesContext.lineTo(i * grid.x + gridOffset.x + barLength / 2, j * grid.y + gridOffset.y);
guidesContext.moveTo(i * grid.x + offset.x - barLength / 2, j * grid.y + offset.y);
guidesContext.lineTo(i * grid.x + offset.x + barLength / 2, j * grid.y + offset.y);
guidesContext.stroke();
}
}
Expand All @@ -79,7 +85,11 @@
}

for (var i = 0, len = anchors.length; i < len; i++) {
var anchor = anchors[i],
var anchor = {
x: anchors[i].x + snapOffset.x,
y: anchors[i].y + snapOffset.y,
range: anchors[i].range
},
range = typeof anchor.range === 'number'? anchor.range: defaultRange;

if (range > 0 && range !== Infinity) {
Expand Down Expand Up @@ -221,11 +231,16 @@
snap: {
targets: status.gridMode.checked? [gridFunc] : status.anchorMode.checked? anchors : null,
enabled: !status.offMode.checked,
endOnly: status.endOnly.checked
endOnly: status.endOnly.checked,
offset: status.relative.checked? 'startCoords' : null
}
})
.inertia(status.inertia.checked);

if (!status.relative.checked) {
snapOffset.x = snapOffset.y = 0;
}

drawSnap(interact(canvas).draggable().snap);
}

Expand Down Expand Up @@ -255,6 +270,16 @@
restriction: 'self'
}
})
.on('move down', function (event) {
if ((event.type === 'down' || !event.interaction.pointerIsDown) && status.relative.checked) {
var rect = interact.getElementRect(canvas);

snapOffset.x = event.pageX - rect.left;
snapOffset.y = event.pageY - rect.top;

drawSnap(interact(canvas).draggable().snap);
}
})
.origin('self')
.draggable(true);

Expand All @@ -279,7 +304,8 @@
anchorMode: document.getElementById('anchor-mode'),
anchorDrag: document.getElementById('drag-anchors'),
endOnly: document.getElementById('end-only'),
inertia: document.getElementById('inertia')
inertia: document.getElementById('inertia'),
relative: document.getElementById('relative')
};

interact(status.sliders)
Expand Down
5 changes: 5 additions & 0 deletions demo/snap.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ <h3> snap mode </h3>
Inertia
<input id="inertia" type="checkbox" checked>
</label>

<label for="relative">
Relative to "startCoords"
<input id="relative" type="checkbox">
</label>
<br>
<br>

Expand Down
69 changes: 48 additions & 21 deletions interact.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@
endOnly : false,
range : Infinity,
targets : null,
offsets : null,

elementOrigin: null
relativePoints: null
},

restrict: {
Expand Down Expand Up @@ -1200,7 +1201,7 @@

this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };
this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };
this.snapOffset = { x: 0, y: 0};
this.snapOffsets = [];

this.gesture = {
start: { x: 0, y: 0 },
Expand Down Expand Up @@ -1575,6 +1576,7 @@

setStartOffsets: function (action, interactable, element) {
var rect = interactable.getRect(element),
origin = getOriginXY(interactable, element),
snap = interactable.options[this.prepared.name].snap,
restrict = interactable.options[this.prepared.name].restrict,
width, height;
Expand All @@ -1595,12 +1597,25 @@
this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;
}

if (rect && snap.elementOrigin) {
this.snapOffset.x = this.startOffset.left - (width * snap.elementOrigin.x);
this.snapOffset.y = this.startOffset.top - (height * snap.elementOrigin.y);
this.snapOffsets.splice(0);

var snapOffset = snap.offset === 'startCoords'
? {
x: this.startCoords.page.x - origin.x,
y: this.startCoords.page.y - origin.y
}
: snap.offset || { x: 0, y: 0 };

if (rect && snap.relativePoints && snap.relativePoints.length) {
for (var i = 0; i < snap.relativePoints.length; i++) {
this.snapOffsets.push({
x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,
y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y
});
}
}
else {
this.snapOffset.x = this.snapOffset.y = 0;
this.snapOffsets.push(snapOffset);
}

if (rect && restrict.elementRect) {
Expand Down Expand Up @@ -1812,7 +1827,7 @@
var shouldMove = this.setModifications(this.curCoords.page, preEnd);

// move if snapping or restriction doesn't prevent it
if (shouldMove) {
if (shouldMove || starting) {
this.prevEvent = this[this.prepared.name + 'Move'](event);
}

Expand Down Expand Up @@ -2690,26 +2705,34 @@
status.realX = page.x;
status.realY = page.y;

page.x = page.x - this.inertiaStatus.resumeDx - this.snapOffset.x;
page.y = page.y - this.inertiaStatus.resumeDy - this.snapOffset.y;
page.x = page.x - this.inertiaStatus.resumeDx;
page.y = page.y - this.inertiaStatus.resumeDy;

var len = snap.targets? snap.targets.length : 0;

for (i = 0; i < len; i++) {
target = snap.targets[i];
for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {
var relative = {
x: page.x - this.snapOffsets[relIndex].x,
y: page.y - this.snapOffsets[relIndex].y
};

if (isFunction(target)) {
target = target(page.x, page.y);
}
for (i = 0; i < len; i++) {
if (isFunction(snap.targets[i])) {
target = snap.targets[i](relative.x, relative.y);
}
else {
target = snap.targets[i];
}

if (!target) { continue; }
if (!target) { continue; }

targets.push({
x: isNumber(target.x) ? target.x : page.x,
y: isNumber(target.y) ? target.y : page.y,
targets.push({
x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,
y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,

range: isNumber(target.range)? target.range: snap.range
});
range: isNumber(target.range)? target.range: snap.range
});
}
}

var closest = {
Expand Down Expand Up @@ -3073,7 +3096,7 @@
client.x -= origin.x;
client.y -= origin.y;

if (checkSnap(target, action) && !(starting && options[action].snap.elementOrigin)) {
if (checkSnap(target, action) && !(starting && interaction.snapOffsets.length)) {
this.snap = {
range : snapStatus.range,
locked : snapStatus.locked,
Expand Down Expand Up @@ -4092,6 +4115,10 @@
else if (thisOption.mode === 'path') {
thisOption.targets = thisOption.paths;
}

if ('elementOrigin' in options) {
thisOption.relativePoints = [options.elementOrigin];
}
}
}
else {
Expand Down