source: prototipo_portal_2018/prototipo/static/js/draggable.js @ 327fd70

Last change on this file since 327fd70 was 747e744, checked in by Antonio Araujo <aaraujo@…>, 7 years ago

Creado directorio prototipo con fuentes de la modificación del portal para establecer la ubicación de la firma visible

  • Property mode set to 100755
File size: 13.5 KB
Line 
1(function (root, factory) {
2    if (typeof exports === 'object') {
3      module.exports = factory();
4    } else if (typeof define === 'function' && define.amd) {
5      define([], factory);
6    } else {
7      root.Draggable = factory();
8    }
9}(this, function () {
10
11  'use strict';
12
13  var defaults = {
14
15    // settings
16    grid: 0,                // grid cell size for snapping to on drag
17    filterTarget: null,     // disallow drag when target passes this test
18    limit: {                // limit the drag bounds
19      x: null,              // [minimum position, maximum position] || position
20      y: null               // [minimum position, maximum position] || position
21    },
22    threshold: 0,           // threshold to move before drag begins (in px)
23
24    // flags
25    setCursor: false,       // change cursor to reflect draggable?
26    setPosition: true,      // change draggable position to absolute?
27    smoothDrag: true,       // snap to grid when dropped, but not during
28    useGPU: true,           // move graphics calculation/composition to the GPU
29
30    // event hooks
31    onDrag: noop,           // function(element, X, Y, event)
32    onDragStart: noop,      // function(element, X, Y, event)
33    onDragEnd: noop         // function(element, X, Y, event)
34
35  };
36
37  var env = {
38
39    // CSS vendor-prefixed transform property
40    transform: (function(){
41
42      var prefixes = ' -o- -ms- -moz- -webkit-'.split(' ');
43      var style = document.body.style;
44
45      for (var n = prefixes.length; n--;) {
46        var property = prefixes[n] + 'transform';
47        if (property in style) {
48          return property;
49        }
50      }
51
52    })()
53
54  };
55
56  var util = {
57
58    assign: function () {
59
60      var obj = arguments[0];
61      var count = arguments.length;
62
63      for ( var n = 1; n < count; n++ ) {
64        var argument = arguments[n];
65        for ( var key in argument ) {
66          obj[key] = argument[key];
67        }
68      }
69
70      return obj;
71
72    },
73
74    bind: function (fn, context) {
75      return function() {
76        fn.apply(context, arguments);
77      }
78    },
79
80    on: function (element, e, fn) {
81      if (e && fn) {
82        util.addEvent (element, e, fn);
83      } else if (e) {
84        for (var ee in e) {
85          util.addEvent (element, ee, e[ee]);
86        }
87      }
88    },
89
90    off: function (element, e, fn) {
91      if (e && fn) {
92        util.removeEvent (element, e, fn);
93      } else if (e) {
94        for (var ee in e) {
95          util.removeEvent (element, ee, e[ee]);
96        }
97      }
98    },
99
100    // Example:
101    //
102    //     util.limit(x, limit.x)
103    limit: function (n, limit) {
104      // {Array} limit.x
105      if (isArray(limit)) {
106        limit = [+limit[0], +limit[1]];
107        if (n < limit[0]) n = limit[0];
108        else if (n > limit[1]) n = limit[1];
109      // {Number} limit.x
110      } else {
111        n = +limit;
112      }
113
114      return n;
115    },
116
117    addEvent: ('attachEvent' in Element.prototype)
118      ? function (element, e, fn) { element.attachEvent('on'+e, fn) }
119      : function (element, e, fn) { element.addEventListener(e, fn, false) },
120
121    removeEvent: ('attachEvent' in Element.prototype)
122      ? function (element, e, fn) { element.detachEvent('on'+e, fn) }
123      : function (element, e, fn) { element.removeEventListener(e, fn) }
124
125  };
126
127  /*
128    usage:
129
130    new Draggable (element, options)
131      - or -
132    new Draggable (element)
133  */
134
135  function Draggable (element, options) {
136
137    var me = this,
138      start = util.bind(me.start, me),
139      drag = util.bind(me.drag, me),
140      stop = util.bind(me.stop, me);
141
142    // sanity check
143    if (!isElement(element)) {
144      throw new TypeError('Draggable expects argument 0 to be an Element');
145    }
146
147    options = util.assign({}, defaults, options);
148
149    // set instance properties
150    util.assign(me, {
151
152      // DOM element
153      element: element,
154      handle: (options.handle && isElement(options.handle))
155              ? options.handle
156              : element,
157
158      // DOM event handlers
159      handlers: {
160        start: {
161          mousedown: start,
162          touchstart: start
163        },
164        move: {
165          mousemove: drag,
166          mouseup: stop,
167          touchmove: drag,
168          touchend: stop
169        }
170      },
171
172      // options
173      options: options
174
175    });
176
177    // initialize
178    me.initialize();
179
180  }
181
182  util.assign (Draggable.prototype, {
183
184    // public
185
186    setOption: function (property, value) {
187
188      var me = this;
189
190      me.options[property] = value;
191      me.initialize();
192
193      return me;
194
195    },
196
197    get: function() {
198
199      var dragEvent = this.dragEvent;
200
201      return {
202        x: dragEvent.x,
203        y: dragEvent.y
204      };
205
206    },
207
208    set: function (x, y) {
209
210      var me = this,
211        dragEvent = me.dragEvent;
212
213      dragEvent.original = {
214        x: dragEvent.x,
215        y: dragEvent.y
216      };
217
218      me.move(x, y);
219
220      return me;
221
222    },
223
224    // internal
225
226    dragEvent: {
227      started: false,
228      x: 0,
229      y: 0
230    },
231
232    initialize: function() {
233
234      var me = this,
235        element = me.element,
236        handle = me.handle,
237        style = element.style,
238        compStyle = getStyle(element),
239        options = me.options,
240        transform = env.transform,
241        oldTransform;
242
243      // cache element dimensions (for performance)
244
245      var _dimensions = me._dimensions = {
246        height: element.offsetHeight,
247        left: element.offsetLeft,
248        top: element.offsetTop,
249        width: element.offsetWidth
250      };
251
252      // shift compositing over to the GPU if the browser supports it (for performance)
253
254      if (options.useGPU && transform) {
255
256        // concatenate to any existing transform
257        // so we don't accidentally override it
258        oldTransform = compStyle[transform];
259
260        if (oldTransform === 'none') {
261          oldTransform = '';
262        }
263
264        style[transform] = oldTransform + ' translate3d(0,0,0)';
265      }
266
267      // optional styling
268
269      if (options.setPosition) {
270        style.display = 'block';
271        style.left = _dimensions.left + 'px';
272        style.top = _dimensions.top + 'px';
273        style.bottom = style.right = 'auto';
274        style.margin = 0;
275        style.position = 'absolute';
276      }
277
278      if (options.setCursor) {
279        style.cursor = 'move';
280      }
281
282      // set limit
283      me.setLimit(options.limit);
284
285      // set position in model
286      util.assign(me.dragEvent, {
287        x: _dimensions.left,
288        y: _dimensions.top
289      });
290
291      // attach mousedown event
292      util.on(me.handle, me.handlers.start);
293
294    },
295
296    start: function (e) {
297
298      var me = this;
299      var cursor = me.getCursor(e);
300      var element = me.element;
301
302      // filter the target?
303      if (!me.useTarget(e.target || e.srcElement)) {
304        return;
305      }
306
307      // prevent browsers from visually dragging the element's outline
308      if (e.preventDefault) {
309        e.preventDefault();
310      } else {
311        e.returnValue = false; // IE10
312      }
313
314      // set a high z-index, just in case
315      me.dragEvent.oldZindex = element.style.zIndex;
316      element.style.zIndex = 10000;
317
318      // set initial position
319      me.setCursor(cursor);
320      me.setPosition();
321      me.setZoom();
322
323      // add event listeners
324      util.on(document, me.handlers.move);
325
326    },
327
328    drag: function (e) {
329
330      var me = this,
331        dragEvent = me.dragEvent,
332        element = me.element,
333        initialCursor = me._cursor,
334        initialPosition = me._dimensions,
335        options = me.options,
336        zoom = initialPosition.zoom,
337        cursor = me.getCursor(e),
338        threshold = options.threshold,
339        x = (cursor.x - initialCursor.x)/zoom + initialPosition.left,
340        y = (cursor.y - initialCursor.y)/zoom + initialPosition.top;
341
342      // check threshold
343      if (!dragEvent.started && threshold &&
344        (Math.abs(initialCursor.x - cursor.x) < threshold) &&
345        (Math.abs(initialCursor.y - cursor.y) < threshold)
346      ) {
347        return;
348      }
349
350      // save original position?
351      if (!dragEvent.original) {
352        dragEvent.original = { x: x, y: y };
353      }
354
355      // trigger start event?
356      if (!dragEvent.started) {
357        options.onDragStart(element, x, y, e);
358        dragEvent.started = true;
359      }
360
361      // move the element
362      if (me.move(x, y)) {
363
364        // trigger drag event
365        options.onDrag(element, dragEvent.x, dragEvent.y, e);
366      }
367
368    },
369
370    move: function (x, y) {
371
372      var me = this,
373        dragEvent = me.dragEvent,
374        options = me.options,
375        grid = options.grid,
376        style = me.element.style,
377        pos = me.limit(x, y, dragEvent.original.x, dragEvent.original.y);
378
379      // snap to grid?
380      if (!options.smoothDrag && grid) {
381        pos = me.round (pos, grid);
382      }
383
384      // move it
385      if (pos.x !== dragEvent.x || pos.y !== dragEvent.y) {
386
387        dragEvent.x = pos.x;
388        dragEvent.y = pos.y;
389        style.left = pos.x + 'px';
390        style.top = pos.y + 'px';
391
392        return true;
393      }
394
395      return false;
396
397    },
398
399    stop: function (e) {
400
401      var me = this,
402        dragEvent = me.dragEvent,
403        element = me.element,
404        options = me.options,
405        grid = options.grid,
406        pos;
407
408      // remove event listeners
409      util.off(document, me.handlers.move);
410
411      // resent element's z-index
412      element.style.zIndex = dragEvent.oldZindex;
413
414      // snap to grid?
415      if (options.smoothDrag && grid) {
416        pos = me.round({ x: dragEvent.x, y: dragEvent.y }, grid);
417        me.move(pos.x, pos.y);
418        util.assign(me.dragEvent, pos);
419      }
420
421      // trigger dragend event
422      if (me.dragEvent.started) {
423        options.onDragEnd(element, dragEvent.x, dragEvent.y, e);
424      }
425
426      // clear temp vars
427      me.reset();
428
429    },
430
431    reset: function() {
432
433      this.dragEvent.started = false;
434
435    },
436
437    round: function (pos) {
438
439      var grid = this.options.grid;
440
441      return {
442        x: grid * Math.round(pos.x/grid),
443        y: grid * Math.round(pos.y/grid)
444      };
445
446    },
447
448    getCursor: function (e) {
449
450      return {
451        x: (e.targetTouches ? e.targetTouches[0] : e).clientX,
452        y: (e.targetTouches ? e.targetTouches[0] : e).clientY
453      };
454
455    },
456
457    setCursor: function (xy) {
458
459      this._cursor = xy;
460
461    },
462
463    setLimit: function (limit) {
464
465      var me = this,
466        _true = function (x, y) {
467          return { x:x, y:y };
468        };
469
470      // limit is a function
471      if (isFunction(limit)) {
472
473        me.limit = limit;
474
475      }
476
477      // limit is an element
478      else if (isElement(limit)) {
479
480        var draggableSize = me._dimensions,
481          height = limit.scrollHeight - draggableSize.height,
482          width = limit.scrollWidth - draggableSize.width;
483
484        me.limit = function (x, y) {
485          return {
486            x: util.limit(x, [0, width]),
487            y: util.limit(y, [0, height])
488          }
489        };
490
491      }
492
493      // limit is defined
494      else if (limit) {
495
496        var defined = {
497          x: isDefined(limit.x),
498          y: isDefined(limit.y)
499        };
500        var _x, _y;
501
502        // {Undefined} limit.x, {Undefined} limit.y
503        if (!defined.x && !defined.y) {
504
505          me.limit = _true;
506
507        } else {
508
509          me.limit = function (x, y) {
510            return {
511              x: defined.x ? util.limit(x, limit.x) : x,
512              y: defined.y ? util.limit(y, limit.y) : y
513            };
514          };
515
516        }
517      }
518
519      // limit is `null` or `undefined`
520      else {
521
522        me.limit = _true;
523
524      }
525
526    },
527
528    setPosition: function() {
529
530      var me = this,
531        element = me.element,
532        style = element.style;
533
534      util.assign(me._dimensions, {
535        left: parse(style.left) || element.offsetLeft,
536        top: parse(style.top) || element.offsetTop
537      });
538
539    },
540
541    setZoom: function() {
542
543      var me = this;
544      var element = me.element;
545      var zoom = 1;
546
547      while (element = element.offsetParent) {
548
549        var z = getStyle(element).zoom;
550
551        if (z && z !== 'normal') {
552          zoom = z;
553          break;
554        }
555
556      }
557
558      me._dimensions.zoom = zoom;
559
560    },
561
562    useTarget: function (element) {
563
564      var filterTarget = this.options.filterTarget;
565
566      if (filterTarget instanceof Function) {
567        return filterTarget(element);
568      }
569
570      return true;
571
572    },
573
574    destroy: function () {
575
576      util.off(this.handle, this.handlers.start);
577      util.off(document, this.handlers.move);
578
579    }
580
581  });
582
583  // helpers
584
585  function parse (string) {
586    return parseInt(string, 10);
587  }
588
589  function getStyle (element) {
590    return 'currentStyle' in element ? element.currentStyle : getComputedStyle(element);
591  }
592
593  function isArray (thing) {
594    return thing instanceof Array; // HTMLElement
595  }
596
597  function isDefined (thing) {
598    return thing !== void 0 && thing !== null;
599  }
600
601  function isElement (thing) {
602    return thing instanceof Element || typeof HTMLDocument !== 'undefined' && thing instanceof HTMLDocument;
603  }
604
605  function isFunction (thing) {
606    return thing instanceof Function;
607  }
608
609  function noop (){};
610
611  return Draggable;
612
613}));
Note: See TracBrowser for help on using the repository browser.