So I’m trying to have a HTML element dragged around the page with my finger. The element is hidden at first, three other are shown, and when dragging one of them the hidden element reveals and moves with the finger - the initial element stays in place. When released, the dragged element disappears.
It’s much smoother that way, actually, but still a little bit bothering me as not really in par with native performances (as seen in Tera Battle for example). So if one of you has advices on how to improve performances, I would gladly use it ! Thanks !
A) Method to manipulate the DOM-element
You are using Angular ng-style to update the position of the element, pixel by pixel.
This can be costly performance-wise. You might want to try some other route. One example is below, #3: have Velocity move the element by translateX and translateY for drag events.
Event types include dragstart drag dragend and many more (hold, tap, doubletap, drag, dragstart, dragend, dragup, dragdown, dragleft, dragright, swipe, swipeup, swipedown, swipeleft, swiperight, transform, transformstart, transformend, rotate, pinch, pinchin, pinchout, touch, release).
Another point: at the very least - you do not need to update the style 60 times a second. This is what is currently happening in your code. Hammer.js (used by Ionic for the touch events) is pounding the events at 60 fps and you are updating the $scope.draggedStyle at that rate, then as well…
However you end up manipulating the DOM-element position, you could always drop a few events (every other or so) by code. Made a huge difference with some mobile devices in the project I am working on now. It is not visible at the Github code below, I added it afterwards for a specific (lots of large image elements) case.
I added this hack to skip every other update:
I suggest you benchmark a few ways - using your own specific cases, as controversial information exists about which method currently is the fastest.
1. CSS and transform
Previously, the recommended trick when using transforms was to always use translate3D to force hardware acceleration. Supposedly plain transform: translate is not always triggering hw acceleration.
Things are different on different platforms - desktop Chrome on OSX was fine using translate: transform(x, y) just a few months ago, but some update changed everything once again and had to switch back to using translate: transform3D(X, Y, 1px).
You might also experiment with backface visibility to eliminate flicker, if any is visible:
-webkit-backface-visibility: hidden; /* Chrome, Safari, Opera */
Solution: TEST using transform: translate3D(x, y, 0px) – or 1px or whatever for Z.
2. CSS + left / top
Some benchmarks proved little or no difference when using left / top vs. translate vs. translate3D. Especially noteworthy was, that with certain setups, I got better performance using left / top. …But mostly on desktop browsers. On some mobile browsers the performance was very bad, so switched back to use #1 again after a few disappointments.
I have had decent success with Velocity ( http://velocityjs.org/ ). You can use Velocity to animate a movement with easings – or you can use it to follow the drag px by px using mock = true / or an easing time of 0. Velocity animations are automatically hardware accelerated on mobile devices, so no need to use transforms for Z there.
I ended up using Velocity, wrapped a generic drag directive around it - enabling dragging X to cause translate X - or anything else (like rotate Y etc.). Also - it enabled me to add a momentum to the drag movement: as you release the element, the end movement is bouncy (spring-like) or easing out (the usual). The movement plus the possible endpoints may have limits, so the dragged element snaps to some points. This can be used to return the dragged element to the start point with a spring-effect, has it not been dragged far enough.
Absolutely fu***** awesome, man ! You gave me so much to explore right now, I could not thank you enough. I will continue working on the project, get it to a more advanced state ,and then make tests following your recommandations - bookmarked with love, of course. Again, thank you so much. Couldn’t hope for a more clear and complete answer !