187 * @param event |
187 * @param event |
188 * The event object |
188 * The event object |
189 * @return Viewport X |
189 * @return Viewport X |
190 */ |
190 */ |
191 function evX(event) { |
191 function evX(event) { |
192 return event.pageX - parOfs.left; |
192 return max(event.pageX || 0, touchCoords(event).x) - parOfs.left; |
193 } |
193 } |
194 |
194 |
195 /** |
195 /** |
196 * Get event Y and translate it to viewport Y |
196 * Get event Y and translate it to viewport Y |
197 * |
197 * |
198 * @param event |
198 * @param event |
199 * The event object |
199 * The event object |
200 * @return Viewport Y |
200 * @return Viewport Y |
201 */ |
201 */ |
202 function evY(event) { |
202 function evY(event) { |
203 return event.pageY - parOfs.top; |
203 return max(event.pageY || 0, touchCoords(event).y) - parOfs.top; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Get X and Y coordinates of a touch event |
|
208 * |
|
209 * @param event |
|
210 * The event object |
|
211 * @return Coordinates object |
|
212 */ |
|
213 function touchCoords(event) { |
|
214 var oev = event.originalEvent || {}; |
|
215 |
|
216 if (oev.touches && oev.touches.length) |
|
217 return { x: oev.touches[0].pageX, y: oev.touches[0].pageY }; |
|
218 else |
|
219 return { x: 0, y: 0 }; |
204 } |
220 } |
205 |
221 |
206 /** |
222 /** |
207 * Get the current selection |
223 * Get the current selection |
208 * |
224 * |
484 * hide the selection and the outer area |
500 * hide the selection and the outer area |
485 */ |
501 */ |
486 if (options.autoHide || selection.width * selection.height == 0) |
502 if (options.autoHide || selection.width * selection.height == 0) |
487 hide($box.add($outer), function () { $(this).hide(); }); |
503 hide($box.add($outer), function () { $(this).hide(); }); |
488 |
504 |
489 $(document).unbind('mousemove', selectingMouseMove); |
505 $(document).off('mousemove touchmove', selectingMouseMove); |
490 $box.mousemove(areaMouseMove); |
506 $box.on('mousemove touchmove', areaMouseMove); |
491 |
507 |
492 options.onSelectEnd(img, getSelection()); |
508 options.onSelectEnd(img, getSelection()); |
493 } |
509 } |
494 |
510 |
495 /** |
511 /** |
498 * @param event |
514 * @param event |
499 * The event object |
515 * The event object |
500 * @return false |
516 * @return false |
501 */ |
517 */ |
502 function areaMouseDown(event) { |
518 function areaMouseDown(event) { |
503 if (event.which != 1) return false; |
519 if (event.type == 'mousedown' && event.which != 1) return false; |
|
520 |
|
521 /* |
|
522 * With mobile browsers, there is no "moving the pointer over" action, |
|
523 * so we need to simulate one mousemove event happening prior to |
|
524 * mousedown/touchstart. |
|
525 */ |
|
526 areaMouseMove(event); |
504 |
527 |
505 adjust(); |
528 adjust(); |
506 |
529 |
507 if (resize) { |
530 if (resize) { |
508 /* Resize mode is in effect */ |
531 /* Resize mode is in effect */ |
509 $('body').css('cursor', resize + '-resize'); |
532 $('body').css('cursor', resize + '-resize'); |
510 |
533 |
511 x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); |
534 x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); |
512 y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); |
535 y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); |
513 |
536 |
514 $(document).mousemove(selectingMouseMove) |
537 $(document).on('mousemove touchmove', selectingMouseMove) |
515 .one('mouseup', docMouseUp); |
538 .one('mouseup touchend', docMouseUp); |
516 $box.unbind('mousemove', areaMouseMove); |
539 $box.off('mousemove touchmove', areaMouseMove); |
517 } |
540 } |
518 else if (options.movable) { |
541 else if (options.movable) { |
519 startX = left + selection.x1 - evX(event); |
542 startX = left + selection.x1 - evX(event); |
520 startY = top + selection.y1 - evY(event); |
543 startY = top + selection.y1 - evY(event); |
521 |
544 |
522 $box.unbind('mousemove', areaMouseMove); |
545 $box.off('mousemove touchmove', areaMouseMove); |
523 |
546 |
524 $(document).mousemove(movingMouseMove) |
547 $(document).on('mousemove touchmove', movingMouseMove) |
525 .one('mouseup', function () { |
548 .one('mouseup touchend', function () { |
526 options.onSelectEnd(img, getSelection()); |
549 options.onSelectEnd(img, getSelection()); |
527 |
550 |
528 $(document).unbind('mousemove', movingMouseMove); |
551 $(document).off('mousemove touchmove', movingMouseMove); |
529 $box.mousemove(areaMouseMove); |
552 $box.on('mousemove touchmove', areaMouseMove); |
530 }); |
553 }); |
531 } |
554 } |
532 else |
555 else |
533 $img.mousedown(event); |
556 $img.mousedown(event); |
534 |
557 |
689 /* Show the plugin elements */ |
712 /* Show the plugin elements */ |
690 $box.add($outer).hide().fadeIn(options.fadeSpeed||0); |
713 $box.add($outer).hide().fadeIn(options.fadeSpeed||0); |
691 |
714 |
692 shown = true; |
715 shown = true; |
693 |
716 |
694 $(document).unbind('mouseup', cancelSelection) |
717 $(document).off('mouseup touchend', cancelSelection) |
695 .mousemove(selectingMouseMove).one('mouseup', docMouseUp); |
718 .on('mousemove touchmove', selectingMouseMove) |
696 $box.unbind('mousemove', areaMouseMove); |
719 .one('mouseup touchend', docMouseUp); |
|
720 $box.off('mousemove touchmove', areaMouseMove); |
697 |
721 |
698 options.onSelectStart(img, getSelection()); |
722 options.onSelectStart(img, getSelection()); |
699 } |
723 } |
700 |
724 |
701 /** |
725 /** |
702 * Cancel selection |
726 * Cancel selection |
703 */ |
727 */ |
704 function cancelSelection() { |
728 function cancelSelection() { |
705 $(document).unbind('mousemove', startSelection) |
729 $(document).off('mousemove touchmove', startSelection) |
706 .unbind('mouseup', cancelSelection); |
730 .off('mouseup touchend', cancelSelection); |
707 hide($box.add($outer)); |
731 hide($box.add($outer)); |
708 |
732 |
709 setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); |
733 setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); |
710 |
734 |
711 /* If this is an API call, callback functions should not be triggered */ |
735 /* If this is an API call, callback functions should not be triggered */ |
722 * The event object |
746 * The event object |
723 * @return false |
747 * @return false |
724 */ |
748 */ |
725 function imgMouseDown(event) { |
749 function imgMouseDown(event) { |
726 /* Ignore the event if animation is in progress */ |
750 /* Ignore the event if animation is in progress */ |
727 if (event.which != 1 || $outer.is(':animated')) return false; |
751 if (event.which > 1 || $outer.is(':animated')) return false; |
728 |
752 |
729 adjust(); |
753 adjust(); |
730 startX = x1 = evX(event); |
754 startX = x1 = evX(event); |
731 startY = y1 = evY(event); |
755 startY = y1 = evY(event); |
732 |
756 |
733 /* Selection will start when the mouse is moved */ |
757 /* Selection will start when the mouse is moved */ |
734 $(document).mousemove(startSelection).mouseup(cancelSelection); |
758 $(document).on({ 'mousemove touchmove': startSelection, |
|
759 'mouseup touchend': cancelSelection }); |
735 |
760 |
736 return false; |
761 return false; |
737 } |
762 } |
738 |
763 |
739 /** |
764 /** |
987 |
1012 |
988 $img.add($outer).unbind('mousedown', imgMouseDown); |
1013 $img.add($outer).unbind('mousedown', imgMouseDown); |
989 |
1014 |
990 if (options.disable || options.enable === false) { |
1015 if (options.disable || options.enable === false) { |
991 /* Disable the plugin */ |
1016 /* Disable the plugin */ |
992 $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); |
1017 $box.off({ 'mousemove touchmove': areaMouseMove, |
993 $(window).unbind('resize', windowResize); |
1018 'mousedown touchstart': areaMouseDown }); |
|
1019 $(window).off('resize', windowResize); |
994 } |
1020 } |
995 else { |
1021 else { |
996 if (options.enable || options.disable === false) { |
1022 if (options.enable || options.disable === false) { |
997 /* Enable the plugin */ |
1023 /* Enable the plugin */ |
998 if (options.resizable || options.movable) |
1024 if (options.resizable || options.movable) |
999 $box.mousemove(areaMouseMove).mousedown(areaMouseDown); |
1025 $box.on({ 'mousemove touchmove': areaMouseMove, |
|
1026 'mousedown touchstart': areaMouseDown }); |
1000 |
1027 |
1001 $(window).resize(windowResize); |
1028 $(window).resize(windowResize); |
1002 } |
1029 } |
1003 |
1030 |
1004 if (!options.persistent) |
1031 if (!options.persistent) |
1005 $img.add($outer).mousedown(imgMouseDown); |
1032 $img.add($outer).on('mousedown touchstart', imgMouseDown); |
1006 } |
1033 } |
1007 |
1034 |
1008 options.enable = options.disable = undefined; |
1035 options.enable = options.disable = undefined; |
1009 } |
1036 } |
1010 |
1037 |