@@ -133,71 +133,211 @@ As well as you can use `ui-default` for that:
133133
134134## New Experimental Features
135135
136+ ### $swipe
137+
138+ A drop in replacement for ` ngTouch ` 's ` $swipe ` . It is free from other ` ngTouch ` features that does not play or duplicates fastclicks behaviour.
139+
136140### $drag
137141
138- ` $drag ` Service wraps ` ngTouch ` 's ` $swipe ` to extend its behavior moving one or more
139- target element through css transform according to the ` $swipe ` coords thus creating
140- a drag effect.
142+ ` $drag ` Service wraps ` $swipe ` to extend its behavior moving target element through css transform according to the ` $swipe ` coords thus creating a drag effect.
141143
142- $drag interface is similar to ` $swipe ` :
144+ $drag interface is very close to ` $swipe ` :
143145
144146``` js
145147app .controller (' MyController' , function ($drag , $element ){
146- $drag .bind ($element, {
147- start : function (coords , cancel , markers , e ){},
148- move : function (coords , cancel , markers , e ){},
149- end : function (coords , cancel , markers , e ){},
150- cancel : function (coords , markers , e ){},
151- transform : function (x , y , transform ) {},
152- adaptTransform : function (x , y , transform ) {},
153- constraint: fn or {top: y1, left: x1, bottom: y2, right: x2}
148+ var unbindDrag = $drag .bind ($element, {
149+ // drag callbacks
150+ // - rect is the current result of getBoundingClientRect() for bound element
151+ // - cancelFn issue a "touchcancel" on element
152+ // - resetFn restore the initial transform
153+ // - undoFn undoes the current movement
154+ // - swipeCoords are the coordinates exposed by the underlying $swipe service
155+ start : function (rect , cancelFn , resetFn , swipeCoords ){},
156+ move : function (rect , cancelFn , resetFn , swipeCoords ){},
157+ end : function (rect , undoFn , resetFn , swipeCoords ) {};
158+ cancel : function (rect , resetFn ){},
159+
160+ // constraints for the movement
161+ // you can use a "static" object of the form:
162+ // {top: .., lelf: .., bottom: .., rigth: ..}
163+ // or pass a function that is called on each movement
164+ // and return it in a dynamic way.
165+ // This is useful if you have to constraint drag movement while bounduaries are
166+ // changing over time.
167+
168+ constraint : function (){ return {top: y1, left: x1, bottom: y2, right: x2}; }, // or just {top: y1, left: x1, bottom: y2, right: x2}
169+
170+ // instantiates the Trasform according to touch movement (defaults to `t.translate(dx, dy);`)
171+ // dx, dy are the distances of movement for x and y axis after constraints are applyied
172+ transform : function (transform , dx , dy , currSwipeX , currSwipeY , startSwipeX , startSwipeY ) {},
173+
174+ // changes the Transform before is applied to element (useful to add something like easing or accelleration)
175+ adaptTransform : function (transform , dx , dy , currSwipeX , currSwipeY , startSwipeX , startSwipeY ) {}
176+
154177 });
178+
179+ // This is automatically called when element is disposed so it is not necessary
180+ // that you call this manually but if you have to detatch $drag service before
181+ // this you could just call:
182+ unbindDrag ();
155183});
156184```
157185
158186Main differences with ` $swipe ` are:
159-
187+ - bound elements will move following swipe direction automatically
160188 - coords param take into account css transform so you can easily detect collision with other elements.
161189 - start, move, end callback receive a cancel funcion that can be used to cancel the motion and reset
162190 the transform.
163191 - you can configure the transform behavior passing a transform function to options.
164- - you can constraint the motion through the constraint option (setting relative movement limits)
165- or through the track option (setting absolute coords);
166- - you can setup collision markers being watched and passed to callbacks.
167-
168- Example (drag to dismiss):
192+ - you can constraint the motion through the constraint option (setting relative movement limits)
193+
194+ ** Example 1.** Drag to dismiss
169195
170196``` js
171- $drag .bind (e, {
172- move : function (c , cancel , markers ){
173- if (c .left > markers .m1 .left ) {
174- e .addClass (' willBeDeleted' );
175- } else {
176- e .removeClass (' willBeDeleted' );
177- }
178- },
179- end : function (coords , cancel ){
180- if (c .left > markers .m1 .left ) {
181- e .addClass (' deleting' );
182- delete ($scope .myModel ).then (function (){
183- e .remove ();
184- }, function (){
185- cancel ();
186- });
187- } else {
188- cancel ();
189- }
190- },
191- cancel : function (){
192- e .removeClass (' willBeDeleted' );
193- e .removeClass (' deleting' );
194- },
195- constraint: {
196- minX: 0 ,
197- minY: 0 ,
198- maxY: 0
199- },
200- });
197+ app .directive (' dragToDismiss' , function ($drag , $parse , $timeout ){
198+ return {
199+ restrict: ' A' ,
200+ compile : function (elem , attrs ) {
201+ var dismissFn = $parse (attrs .dragToDismiss );
202+ return function (scope , elem , attrs ){
203+ var dismiss = false ;
204+
205+ $drag .bind (elem, {
206+ constraint: {
207+ minX: 0 ,
208+ minY: 0 ,
209+ maxY: 0
210+ },
211+ move : function (c ) {
212+ if ( c .left >= c .width / 4 ) {
213+ dismiss = true ;
214+ elem .addClass (' dismiss' );
215+ } else {
216+ dismiss = false ;
217+ elem .removeClass (' dismiss' );
218+ }
219+ },
220+ cancel : function (){
221+ elem .removeClass (' dismiss' );
222+ },
223+ end : function (c , undo , reset ) {
224+ if (dismiss) {
225+ elem .addClass (' dismitted' );
226+ $timeout (function () {
227+ scope .$apply (function () {
228+ dismissFn (scope);
229+ });
230+ }, 400 );
231+ } else {
232+ reset ();
233+ }
234+ }
235+ });
236+ };
237+ }
238+ };
239+ });
240+ ```
241+
242+ ** Example 2.** Touch enabled "deck of cards" carousel directive
243+
244+ ``` js
245+ app .directive (' carousel' , function (){
246+ return {
247+ restrict: ' C' ,
248+ scope: {},
249+ controller : function ($scope ) {
250+ this .itemCount = 0 ;
251+ this .activeItem = null ;
252+
253+ this .addItem = function (){
254+ var newId = this .itemCount ++ ;
255+ this .activeItem = this .itemCount == 1 ? newId : this .activeItem ;
256+ return newId;
257+ };
258+
259+ this .next = function (){
260+ this .activeItem = this .activeItem || 0 ;
261+ this .activeItem = this .activeItem == this .itemCount - 1 ? 0 : this .activeItem + 1 ;
262+ };
263+
264+ this .prev = function (){
265+ this .activeItem = this .activeItem || 0 ;
266+ this .activeItem = this .activeItem === 0 ? this .itemCount - 1 : this .activeItem - 1 ;
267+ };
268+ }
269+ };
270+ });
271+
272+ app .directive (' carouselItem' , function ($drag ) {
273+ return {
274+ restrict: ' C' ,
275+ require: ' ^carousel' ,
276+ scope: {},
277+ transclude: true ,
278+ template: ' <div class="item"><div ng-transclude></div></div>' ,
279+ link : function (scope , elem , attrs , carousel ) {
280+ scope .carousel = carousel;
281+ var id = carousel .addItem ();
282+
283+ var zIndex = function (){
284+ var res = 0 ;
285+ if (id == carousel .activeItem ){
286+ res = 2000 ;
287+ } else if (carousel .activeItem < id) {
288+ res = 2000 - (id - carousel .activeItem );
289+ } else {
290+ res = 2000 - (carousel .itemCount - 1 - carousel .activeItem + id);
291+ }
292+ return res;
293+ };
294+
295+ scope .$watch (function (){
296+ return carousel .activeItem ;
297+ }, function (n , o ){
298+ elem[0 ].style [' z-index' ]= zIndex ();
299+ });
300+
301+
302+ $drag .bind (elem, {
303+ constraint: { minY: 0 , maxY: 0 },
304+ adaptTransform : function (t , dx , dy , x , y , x0 , y0 ) {
305+ var maxAngle = 15 ;
306+ var velocity = 0.02 ;
307+ var r = t .getRotation ();
308+ var newRot = r + Math .round (dx * velocity);
309+ newRot = Math .min (newRot, maxAngle);
310+ newRot = Math .max (newRot, - maxAngle);
311+ t .rotate (- r);
312+ t .rotate (newRot);
313+ },
314+ move : function (c ){
315+ if (c .left >= c .width / 4 || c .left <= - (c .width / 4 )) {
316+ elem .addClass (' dismiss' );
317+ } else {
318+ elem .removeClass (' dismiss' );
319+ }
320+ },
321+ cancel : function (){
322+ elem .removeClass (' dismiss' );
323+ },
324+ end : function (c , undo , reset ) {
325+ elem .removeClass (' dismiss' );
326+ if (c .left >= c .width / 4 ) {
327+ scope .$apply (function () {
328+ carousel .next ();
329+ });
330+ } else if (c .left <= - (c .width / 4 )) {
331+ scope .$apply (function () {
332+ carousel .next ();
333+ });
334+ }
335+ reset ();
336+ }
337+ });
338+ }
339+ };
340+ });
201341```
202342
203343### Transform
@@ -235,10 +375,10 @@ t1.apply(e);
235375
236376Since 1.2 I've tried to retain bootstrap existing components look and feel as much as possible for two reason:
237377
238- 1 . People would expect to already know them and how customize them with css.
378+ 1 . People would expect to already know them and how customize their appearence through css.
2393792 . Mobile Angular UI dependance on bootstrap is more loose so it does not need to be updated each time BS3 changes.
240380
241- As a consequence i've reduced special style for panels/forms/modals to the bare minimum.
381+ As a consequence i've reduced special styles for panels/forms/modals to the bare minimum.
242382
243383### Navbars
244384
0 commit comments