Advertisement
Guest User

Resizing and Cropping Images with Canvas. Modified

a guest
Oct 14th, 2016
719
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function resizeableImage(image_target, min_width, min_height) {
  2.     this.init = function (image_target, min_width, min_height) {
  3.         // When resizing, we will always use this copy of the original as the base
  4.         this.min_width = typeof min_width !== 'undefined' ? min_width : 256;
  5.         this.min_height = typeof min_height !== 'undefined' ? min_height : 256;
  6.         this.image_target = jQuery(image_target).get(0);
  7.         this.orig_src = new Image();
  8.         this.event_state = {};
  9.         this.constrain = false;
  10.         this.resize_canvas = document.createElement('canvas');
  11.         this.orig_src.src = image_target.src;
  12.  
  13.         // Wrap the image with the container and add resize handles
  14.         jQuery($(image_target)).wrap('<div class="resize-container"></div>')
  15.             .before('<span class="resize-handle resize-handle-nw"></span>')
  16.             .before('<span class="resize-handle resize-handle-ne"></span>')
  17.             .after('<span class="resize-handle resize-handle-se"></span>')
  18.             .after('<span class="resize-handle resize-handle-sw"></span>');
  19.  
  20.         // Assign the container to a variable
  21.         this.container = jQuery($(image_target)).parent('.resize-container');
  22.         // Add events
  23.         jQuery(this.container).on('mousedown touchstart', '.resize-handle', this.startResize.bind(this));
  24.         jQuery(this.container).on('mousedown touchstart', 'img', this.startMoving.bind(this));
  25.         this.overlay = jQuery(this.container).parent().children('.overlay')[0];
  26.         this.offsetLeft = this.container.parent().offset().left + 3;
  27.         this.offsetTop = this.container.parent().offset().top + 3;
  28.     };
  29.  
  30.     this.startResize = function (e) {
  31.         e.preventDefault();
  32.         e.stopPropagation();
  33.         this.saveEventState(e);
  34.         jQuery($(document)).on('mousemove touchmove', this.resizing.bind(this));
  35.         jQuery($(document)).on('mouseup touchend', this.endResize.bind(this));
  36.     };
  37.  
  38.     this.endResize = function (e) {
  39.         e.preventDefault();
  40.         jQuery($(document)).off('mouseup touchend');
  41.         jQuery($(document)).off('mousemove touchmove');
  42.         this.crop();
  43.     };
  44.  
  45.     this.saveEventState = function (e) {
  46.         // Save the initial event details and container state
  47.         this.event_state.container_width = this.container.width();
  48.         this.event_state.container_height = this.container.height();
  49.         this.event_state.container_left = this.container.offset().left;
  50.         this.event_state.container_top = this.container.offset().top;
  51.         this.event_state.mouse_x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + jQuery($(window)).scrollLeft();
  52.         this.event_state.mouse_y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + jQuery($(window)).scrollTop();
  53.  
  54.         // This is a fix for mobile safari
  55.         // For some reason it does not allow a direct copy of the touches property
  56.         if (typeof e.originalEvent.touches !== 'undefined') {
  57.             this.event_state.touches = [];
  58.             $.each(e.originalEvent.touches, function (i, ob) {
  59.                 this.event_state.touches[i] = {};
  60.                 this.event_state.touches[i].clientX = 0 + ob.clientX;
  61.                 this.event_state.touches[i].clientY = 0 + ob.clientY;
  62.             });
  63.         }
  64.         this.event_state.evnt = e;
  65.     };
  66.  
  67.     this.resizing = function (e) {
  68.         var mouse = {}, width, height, left, top;
  69.         mouse.x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + jQuery($(window)).scrollLeft();
  70.         mouse.y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + jQuery($(window)).scrollTop();
  71.  
  72.         // Position image differently depending on the corner dragged and constraints
  73.  
  74.         if ($(this.event_state.evnt.target).hasClass('resize-handle-se')) {
  75.             width = mouse.x - this.event_state.container_left;
  76.             height = mouse.y - this.event_state.container_top;
  77.             left = this.event_state.container_left;
  78.             top = this.event_state.container_top;
  79.         } else if ($(this.event_state.evnt.target).hasClass('resize-handle-sw')) {
  80.             width = this.event_state.container_width - (mouse.x - this.event_state.container_left);
  81.             height = mouse.y - this.event_state.container_top;
  82.             left = mouse.x;
  83.             top = this.event_state.container_top;
  84.         } else if ($(this.event_state.evnt.target).hasClass('resize-handle-nw')) {
  85.             width = this.event_state.container_width - (mouse.x - this.event_state.container_left);
  86.             height = this.event_state.container_height - (mouse.y - this.event_state.container_top);
  87.             left = mouse.x;
  88.             top = mouse.y;
  89.             if (this.constrain || e.shiftKey) {
  90.                 top = mouse.y - ((width / this.orig_src.width * this.orig_src.height) - height);
  91.             }
  92.         } else if ($(this.event_state.evnt.target).hasClass('resize-handle-ne')) {
  93.             width = mouse.x - this.event_state.container_left;
  94.             height = this.event_state.container_height - (mouse.y - this.event_state.container_top);
  95.             left = this.event_state.container_left;
  96.             top = mouse.y;
  97.             if (this.constrain || e.shiftKey) {
  98.                 top = mouse.y - ((width / this.orig_src.width * this.orig_src.height) - height);
  99.             }
  100.         }
  101.  
  102.         // Optionally maintain aspect ratio
  103.         if (this.constrain || e.shiftKey) {
  104.             height = width / this.orig_src.width * this.orig_src.height;
  105.         }
  106.  
  107.         if ((width > this.min_width)
  108.             && (height > this.min_height)
  109.             && (left - this.offsetLeft <= this.overlay.offsetLeft)
  110.             && (top - this.offsetTop <= this.overlay.offsetTop)
  111.             && (left - this.offsetLeft + width >= this.overlay.offsetLeft + this.min_width)
  112.             && (top - this.offsetTop + height >= this.overlay.offsetTop + this.min_height)) {
  113.             // To improve performance you might limit how often resizeImage() is called
  114.             this.resizeImage(width, height);
  115.             // Without this Firefox will not re-calculate the the image dimensions until drag end
  116.             this.container.offset({'left': left, 'top': top});
  117.         }
  118.     };
  119.  
  120.     this.resizeImage = function (width, height) {
  121.         this.resize_canvas.width = width;
  122.         this.resize_canvas.height = height;
  123.         this.resize_canvas.getContext('2d').drawImage(this.orig_src, 0, 0, width, height);
  124.         jQuery($(image_target)).attr('src', this.resize_canvas.toDataURL("image/png"));
  125.     };
  126.  
  127.     this.startMoving = function (e) {
  128.         e.preventDefault();
  129.         e.stopPropagation();
  130.         this.saveEventState(e);
  131.         jQuery($(document)).on('mousemove touchmove', this.moving.bind(this));
  132.         jQuery($(document)).on('mouseup touchend', this.endMoving.bind(this));
  133.     };
  134.  
  135.     this.endMoving = function (e) {
  136.         e.preventDefault();
  137.         jQuery($(document)).off('mouseup touchend');
  138.         jQuery($(document)).off('mousemove touchmove');
  139.         this.crop();
  140.     };
  141.  
  142.     this.moving = function (e) {
  143.         var mouse = {}, touches;
  144.         e.preventDefault();
  145.         e.stopPropagation();
  146.  
  147.         touches = e.originalEvent.touches;
  148.  
  149.         mouse.x = (e.clientX || e.pageX || touches[0].clientX) + jQuery($(window)).scrollLeft();
  150.         mouse.y = (e.clientY || e.pageY || touches[0].clientY) + jQuery($(window)).scrollTop();
  151.  
  152.         var left = mouse.x - ( this.event_state.mouse_x - this.event_state.container_left );
  153.         var top = mouse.y - ( this.event_state.mouse_y - this.event_state.container_top);
  154.  
  155.         if (left - this.offsetLeft <= this.overlay.offsetLeft
  156.             && top - this.offsetTop <= this.overlay.offsetTop
  157.             && left + this.container.width() - this.offsetLeft >= this.overlay.offsetLeft + this.overlay.offsetWidth
  158.             && top + this.container.height() - this.offsetTop >= this.overlay.offsetTop + this.overlay.offsetHeight) {
  159.             this.container.offset({
  160.                 'left': left,
  161.                 'top': top
  162.             });
  163.         }
  164.         // Watch for pinch zoom gesture while moving
  165.         if (this.event_state.touches && this.event_state.touches.length > 1 && touches.length > 1) {
  166.             var width = this.event_state.container_width, height = this.event_state.container_height;
  167.             var a = this.event_state.touches[0].clientX - this.event_state.touches[1].clientX;
  168.             a = a * a;
  169.             var b = this.event_state.touches[0].clientY - this.event_state.touches[1].clientY;
  170.             b = b * b;
  171.             var dist1 = Math.sqrt(a + b);
  172.  
  173.             a = e.originalEvent.touches[0].clientX - touches[1].clientX;
  174.             a = a * a;
  175.             b = e.originalEvent.touches[0].clientY - touches[1].clientY;
  176.             b = b * b;
  177.             var dist2 = Math.sqrt(a + b);
  178.  
  179.             var ratio = dist2 / dist1;
  180.  
  181.             width = width * ratio;
  182.             height = height * ratio;
  183.             // To improve performance you might limit how often resizeImage() is called
  184.             this.resizeImage(width, height);
  185.         }
  186.     };
  187.  
  188.     this.crop = function () {
  189.         //Find the part of the image that is inside the crop box
  190.         var crop_canvas,
  191.             left = jQuery('.overlay').offset().left - this.container.offset().left,
  192.             top = jQuery('.overlay').offset().top - this.container.offset().top,
  193.             width = jQuery('.overlay').width(),
  194.             height = jQuery('.overlay').height();
  195.  
  196.         crop_canvas = document.createElement('canvas');
  197.         crop_canvas.width = width;
  198.         crop_canvas.height = height;
  199.  
  200.         crop_canvas.getContext('2d').drawImage(image_target, left, top, width, height, 0, 0, width, height);
  201.         jQuery('*[name=' + image_target.name + '-crop]').val(crop_canvas.toDataURL("image/png"));
  202.     };
  203.  
  204.     this.init(image_target, min_width, min_height);
  205.     this.resizeImage(jQuery(this.container).parent().width(), jQuery(this.container).parent().height());
  206.  
  207. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement