Reputation: 2137
In my ionic project, I put some icons overlaying an image inside a ionic-scroll directive. Using x,y coordinates and putting the icons position to absolute (relative to the ionic scroll). Placing the icons works great.
Now I would like to be able to drag those icons around inside the ionic scroll.
I use on-touch and on-release to freeze the scroll and on-drag to get the drag event.
Now the problem I have is that the $event from the on-drag method only gives me x / y coordinates in relation to the window / document.
I can't seem to figure out a way to get the correct x,y coordinates relative to the parent (ionic-scroll):
The HTML looks like this:
<ion-scroll zooming="true" direction="xy">
<img >
<my-icon
on-touch="vm.stopIonicScroll()"
on-release="vm.startIonicScroll()"
on-drag="vm.dragging($event, vm.start)">
</my-icont>
</ion-scroll>
And my controller
vm.stopIonicScroll = function() {
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingY = false;
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingX = false;
};
vm.startIonicScroll = function() {
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingY = true;
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingX = true;
};
vm.dragging = function($event, element) {
console.log($event);
};
Once I start dragging the element I get the event call correctly:
e.g. of such and $event:
{
"gesture": {
"center": {
"pageX": 609,
"pageY": 363
},
"timeStamp": 1438260728495,
"target": {
},
"touches": {
"0": {
"target": {
},
"identifier": 3284571703,
"clientX": 609,
"clientY": 363,
"pageX": 609,
"pageY": 363,
"screenX": 609,
"screenY": 363
},
"length": 1
},
"eventType": "move",
"pointerType": "touch",
"srcEvent": {
"touches": {
"0": {
"target": {
},
"identifier": 3284571703,
"clientX": 609,
"clientY": 363,
"pageX": 609,
"pageY": 363,
"screenX": 609,
"screenY": 363
},
"length": 1
},
"targetTouches": {
"0": {
"target": {
},
"identifier": 3284571703,
"clientX": 609,
"clientY": 363,
"pageX": 609,
"pageY": 363,
"screenX": 609,
"screenY": 363
},
"length": 1
},
"changedTouches": {
"0": {
"target": {
},
"identifier": 3284571703,
"clientX": 609,
"clientY": 363,
"pageX": 609,
"pageY": 363,
"screenX": 609,
"screenY": 363
},
"length": 1
},
"scale": 1,
"rotation": 0,
"ctrlKey": false,
"shiftKey": false,
"altKey": false,
"metaKey": false
},
"deltaTime": 19992,
"deltaX": 252.05572809,
"deltaY": 139.527864045,
"velocityX": 0.012607829536315,
"velocityY": 0.0069791848762005,
"distance": 288.09740524333,
"angle": 28.967141193712,
"direction": "right",
"scale": 1,
"rotation": 0,
"startEvent": {
"center": {
"pageX": 356.94427191,
"pageY": 223.472135955
},
"timeStamp": 1438260708503,
"target": {
},
"touches": [
{
"target": {
},
"identifier": 3284571702,
"clientX": 348,
"clientY": 219,
"pageX": 348,
"pageY": 219,
"screenX": 348,
"screenY": 219
}
],
"eventType": "start",
"pointerType": "touch",
"srcEvent": {
"touches": {
"0": {
"target": {
},
"identifier": 3284571702,
"clientX": 1022,
"clientY": 710,
"pageX": 1022,
"pageY": 710,
"screenX": 1022,
"screenY": 710
},
"length": 1
},
"targetTouches": {
"0": {
"target": {
},
"identifier": 3284571702,
"clientX": 1022,
"clientY": 710,
"pageX": 1022,
"pageY": 710,
"screenX": 1022,
"screenY": 710
},
"length": 1
},
"changedTouches": {
"0": {
"target": {
},
"identifier": 3284571702,
"clientX": 1022,
"clientY": 710,
"pageX": 1022,
"pageY": 710,
"screenX": 1022,
"screenY": 710
},
"length": 1
},
"scale": 1,
"rotation": 0,
"ctrlKey": false,
"shiftKey": false,
"altKey": false,
"metaKey": false,
"isTapHandled": true
}
}
}
}
Now every x / y I get in this event is relative to the window / document.
With ng-click you can get the offsetX / offsetY
(relative to parent).
How could I manage this with on-drag
?
Upvotes: 1
Views: 2042
Reputation: 1
I just want so add a cleaner way of preventing the scroll-pane to scroll:
$ionicScrollDelegate.$getByHandle('plan').freezeScroll(boolean: shouldFreeze)
I had the very same problem for two days and just did not get why dragging did not work. You helped me a lot. I forgot about the zoomfactor :) Not using Math.round increases accuracy and, in my case makes the operation more failsafe.
Upvotes: 0
Reputation: 2137
I found a solution after a short break:
In case someone faces this problem in the future, here is my solution:
var zoom, currentpos;
vm.stopIonicScroll = function(el) {
currentpos = {
x: el.x,
y: el.y
};
zoom = $ionicScrollDelegate.$getByHandle('plan').getScrollView().__zoomLevel;
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingY = false;
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingX = false;
};
vm.startIonicScroll = function() {
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingY = true;
$ionicScrollDelegate.$getByHandle('plan').getScrollView().options.scrollingX = true;
};
vm.dragging = function($event, element) {
element.x = currentpos.x + Math.round($event.gesture.deltaX / zoom);
element.y = currentpos.y + Math.round($event.gesture.deltaY / zoom);
};
To clarify:
On first touch (stopIonicScroll) I put the current position of the element and current zoomlevel of the ionic scroll into a variable.
When I drag the element around, I use the gesture deltaX/Y.
This deltaX / Y is calculated from the start of the drag event (that's why we need to keep the initial position).
The zoomlevel is needed to adjust the 'speed'
of movement.
Upvotes: 1