Drag element and move it around - performances and animation

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.

Drag events themselves:
One way to link drag to controller-side is to use onDrag as you did - another is to register $ionicGesture ( http://ionicframework.com/docs/api/service/$ionicGesture/ ) to listen on an element:

$ionicGesture.on(eventType, callback, $element)

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).

Optimization
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:

        $ionicGesture.on('drag transform', function(ev) {
            if(skipThisFrame){
                skipThisFrame = false;
                return;
            }
            skipThisFrame = true;

B) Then, the actual manipulation of the position:

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 */
backface-visibility: hidden;

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.

3.Libraries
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.