title: Javascript resize and crop on mobile devices
body: <p>I implement this resize and crop tool on my website : <a href="http://tympanus.net/codrops/2014/10/30/resizing-cropping-images-canvas/" rel="nofollow">http://tympanus.net/codrops/2014/10/30/resizing-cropping-images-canvas/</a></p>
  
  <p>I changed some codes to have what I want, like a final crop picture with a size of 390px * 390px.</p>
  
  <p>It works fine, but my site is responsive, and on a mobile device, the website width is 320px.</p>
  
  <p>How can I changed my code to, on mobile version, have a smallest crop zone, but a final picture of 390px * 390px ?</p>
  
  <p>Thanks.</p>
  
  <p>Javascript code :</p>
  
  <pre><code>var resizeableImage = function(image_target) {
    // Some variable and settings
    var $container,
        orig_src = new Image(),
        image_target = $(image_target).get(0),
        event_state = {},
        constrain = false,
        min_width = 100, // Change as required
        min_height = 100,
        max_width = 900, // Change as required
        max_height = 900,
        resize_canvas = document.createElement('canvas');
  
    init = function(){
  
      // When resizing, we will always use this copy of the original as the base
      orig_src.src=image_target.src;
  
      // Wrap the image with the container and add resize handles
      $(image_target).wrap('&lt;div class="resize-container"&gt;&lt;/div&gt;')
      .before('&lt;span class="resize-handle resize-handle-nw"&gt;&lt;/span&gt;')
      .before('&lt;span class="resize-handle resize-handle-ne"&gt;&lt;/span&gt;')
      .after('&lt;span class="resize-handle resize-handle-se"&gt;&lt;/span&gt;')
      .after('&lt;span class="resize-handle resize-handle-sw"&gt;&lt;/span&gt;');
  
      // Assign the container to a variable
      $container =  $(image_target).parent('.resize-container');
  
      // Add events
      $container.on('mousedown touchstart', '.resize-handle', startResize);
      $container.on('mousedown touchstart', 'img', startMoving);
      $('.js-crop').on('click', crop);
    };
  
    startResize = function(e){
      e.preventDefault();
      e.stopPropagation();
      saveEventState(e);
      $(document).on('mousemove touchmove', resizing);
      $(document).on('mouseup touchend', endResize);
    };
  
    endResize = function(e){
      e.preventDefault();
      $(document).off('mouseup touchend', endResize);
      $(document).off('mousemove touchmove', resizing);
    };
  
    saveEventState = function(e){
      // Save the initial event details and container state
      event_state.container_width = $container.width();
      event_state.container_height = $container.height();
      event_state.container_left = $container.offset().left; 
      event_state.container_top = $container.offset().top;
      event_state.mouse_x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + $(window).scrollLeft(); 
      event_state.mouse_y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + $(window).scrollTop();
  
      // This is a fix for mobile safari
      // For some reason it does not allow a direct copy of the touches property
      if(typeof e.originalEvent.touches !== 'undefined'){
          event_state.touches = [];
          $.each(e.originalEvent.touches, function(i, ob){
            event_state.touches[i] = {};
            event_state.touches[i].clientX = 0+ob.clientX;
            event_state.touches[i].clientY = 0+ob.clientY;
          });
      }
      event_state.evnt = e;
    };
  
    resizing = function(e){
      var mouse={},width,height,left,top,offset=$container.offset();
      mouse.x = (e.clientX || e.pageX || e.originalEvent.touches[0].clientX) + $(window).scrollLeft(); 
      mouse.y = (e.clientY || e.pageY || e.originalEvent.touches[0].clientY) + $(window).scrollTop();
  
      // Position image differently depending on the corner dragged and constraints
      if( $(event_state.evnt.target).hasClass('resize-handle-se') ){
        width = mouse.x - event_state.container_left;
        height = mouse.y  - event_state.container_top;
        left = event_state.container_left;
        top = event_state.container_top;
      } else if($(event_state.evnt.target).hasClass('resize-handle-sw') ){
        width = event_state.container_width - (mouse.x - event_state.container_left);
        height = mouse.y  - event_state.container_top;
        left = mouse.x;
        top = event_state.container_top;
      } else if($(event_state.evnt.target).hasClass('resize-handle-nw') ){
        width = event_state.container_width - (mouse.x - event_state.container_left);
        height = event_state.container_height - (mouse.y - event_state.container_top);
        left = mouse.x;
        top = mouse.y;
        if(constrain || e.shiftKey){
          top = mouse.y - ((width / orig_src.width * orig_src.height) - height);
        }
      } else if($(event_state.evnt.target).hasClass('resize-handle-ne') ){
        width = mouse.x - event_state.container_left;
        height = event_state.container_height - (mouse.y - event_state.container_top);
        left = event_state.container_left;
        top = mouse.y;
        if(constrain || e.shiftKey){
          top = mouse.y - ((width / orig_src.width * orig_src.height) - height);
        }
      }
  
      // Optionally maintain aspect ratio
      if(constrain || e.shiftKey){
        height = width / orig_src.width * orig_src.height;
      }
  
      /*if(width &gt; min_width &amp;&amp; height &gt; min_height &amp;&amp; width &lt; max_width &amp;&amp; height &lt; max_height){
        // To improve performance you might limit how often resizeImage() is called
        resizeImage(width, height);  
        // Without this Firefox will not re-calculate the the image dimensions until drag end
        $container.offset({'left': left, 'top': top});
      }*/
  
      if(width &gt; min_width &amp;&amp; height &gt; min_height /*&amp;&amp; width &lt; max_width &amp;&amp; height &lt; max_height*/){
          // To improve performance you might limit how often resizeImage() is called
          resizeImage(width, height);
          // Without this Firefox will not re-calculate the the image dimensions until drag end
          $container.offset({'left': left, 'top': top});
      }
  
    }
  
    resizeImage = function(width, height){
      resize_canvas.width = width;
      resize_canvas.height = height;
      resize_canvas.getContext('2d').drawImage(orig_src, 0, 0, width, height);   
      $(image_target).attr('src', resize_canvas.toDataURL("image/png"));  
    };
  
    startMoving = function(e){
      e.preventDefault();
      e.stopPropagation();
      saveEventState(e);
      $(document).on('mousemove touchmove', moving);
      $(document).on('mouseup touchend', endMoving);
    };
  
    endMoving = function(e){
      e.preventDefault();
      $(document).off('mouseup touchend', endMoving);
      $(document).off('mousemove touchmove', moving);
    };
  
    moving = function(e){
      var  mouse={}, touches;
      e.preventDefault();
      e.stopPropagation();
  
      touches = e.originalEvent.touches;
  
      mouse.x = (e.clientX || e.pageX || touches[0].clientX) + $(window).scrollLeft(); 
      mouse.y = (e.clientY || e.pageY || touches[0].clientY) + $(window).scrollTop();
      $container.offset({
        'left': mouse.x - ( event_state.mouse_x - event_state.container_left ),
        'top': mouse.y - ( event_state.mouse_y - event_state.container_top ) 
      });
      // Watch for pinch zoom gesture while moving
      if(event_state.touches &amp;&amp; event_state.touches.length &gt; 1 &amp;&amp; touches.length &gt; 1){
        var width = event_state.container_width, height = event_state.container_height;
        var a = event_state.touches[0].clientX - event_state.touches[1].clientX;
        a = a * a; 
        var b = event_state.touches[0].clientY - event_state.touches[1].clientY;
        b = b * b; 
        var dist1 = Math.sqrt( a + b );
  
        a = e.originalEvent.touches[0].clientX - touches[1].clientX;
        a = a * a; 
        b = e.originalEvent.touches[0].clientY - touches[1].clientY;
        b = b * b; 
        var dist2 = Math.sqrt( a + b );
  
        var ratio = dist2 /dist1;
  
        width = width * ratio;
        height = height * ratio;
        // To improve performance you might limit how often resizeImage() is called
        resizeImage(width, height);
      }
    };
  
    crop = function(){
      //Find the part of the image that is inside the crop box
      var crop_canvas,
      left = $('.overlay').offset().left - $container.offset().left,
      top =  $('.overlay').offset().top - $container.offset().top,
      width = $('.overlay').width(),
      height = $('.overlay').height();
  
      crop_canvas = document.createElement('canvas');
      crop_canvas.width = width;
      crop_canvas.height = height;
  
      crop_canvas.getContext('2d').drawImage(image_target, left, top, width, height, 0, 0, width, height);
      //window.open(crop_canvas.toDataURL("image/png"));
      var canvasData = crop_canvas.toDataURL("image/png");
      var ajax = new XMLHttpRequest();
      ajax.open("POST",'upload_picture.php',false);
      ajax.setRequestHeader('Content-Type', 'application/upload');
      ajax.send(canvasData)
    }
  
    init();
  };
  </code></pre>
  
  <p>HTML code :</p>
  
  <pre><code>&lt;div id="crop_canvas"&gt;
      &lt;div class="overlay"&gt;
          &lt;div class="overlay-inner"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;img class="resize-image" src="mypicture.jpg" /&gt;
  &lt;/div&gt;
  &lt;button class="btn-crop js-crop"&gt;Découper&lt;/button&gt;
  </code></pre>
  
  <p>CSS code :</p>
  
  <pre><code>.resize-container {
      position: relative;
      display: inline-block;
      cursor: move;
      margin: 0 auto;
  }
  
  .resize-container img {
      display: block
  }
  
  .resize-container:hover img,
  .resize-container:active img {
      outline: 2px dashed rgba(222,60,80,.9);
  }
  
  .resize-handle-ne,
  .resize-handle-ne,
  .resize-handle-se,
  .resize-handle-nw,
  .resize-handle-sw {
      position: absolute;
      display: block;
      width: 10px;
      height: 10px;
      background: rgba(222,60,80,.9);
      z-index: 999;
  }
  
  .resize-handle-nw {
      top: -5px;
      left: -5px;
      cursor: nw-resize;
  }
  
  .resize-handle-sw {
      bottom: -5px;
      left: -5px;
      cursor: sw-resize;
  }
  
  .resize-handle-ne {
      top: -5px;
      right: -5px;
      cursor: ne-resize;
  }
  
  .resize-handle-se {
      bottom: -5px;
      right: -5px;
      cursor: se-resize;
  }
  
  .overlay {
      position: absolute;
      left:40%;
      top:31%;
      margin-left: -100px;
      margin-top: -100px;
      z-index: 999;
      width:390px;
      height:390px;
      border: solid 2px #f8b028;
      box-sizing: content-box;
      pointer-events: none;
  }
  
  .overlay:after,
  .overlay:before {
      content: '';
      position: absolute;
      display: block;
      width: 394px;
      height: 40px;
      border-left: dashed 2px #f8b028;
      border-right: dashed 2px #f8b028;
  }
  
  .overlay:before {
      top: 0;
      margin-left: -2px;
      margin-top: -40px;
  }
  
  .overlay:after {
      bottom: 0;
      margin-left: -2px;
      margin-bottom: -40px;
  }
  
  .overlay-inner:after,
  .overlay-inner:before {
      content: '';
      position: absolute;
      display: block;
      width: 40px;
      height: 394px;
      border-top: dashed 2px #f8b028;
      border-bottom: dashed 2px #f8b028;
  }
  
  .overlay-inner:before {
      left: 0;
      margin-left: -40px;
      margin-top: -2px;
  }
  
  .overlay-inner:after {
      right: 0;
      margin-right: -40px;
      margin-top: -2px;
  }
  
  .btn-crop {
      position: absolute;
      vertical-align: bottom;
      right:20px;
      bottom:13px;
      padding: 6px 10px;
      z-index: 999;
      background-color:#f8b028;
      border: none;
      border-radius:0 0 5px 5px;
      color: #FFF;
      font-weight:700;
      text-transform:uppercase;
  }
  
  #crop_modal .modal-dialog{width:980px;}
  
  #crop_modal .modal-content{
      background:#0082c6;
      border-radius:0;
      padding:10px 20px;
  }
  
  #crop_modal .modal-content p{
      color:#fff;
      font-size:12px;
  }
  
  #crop_canvas{
      background:#fff;
      border:3px solid #f8b028;
      height:600px;
      overflow:hidden;
      margin-bottom:35px;
      position:relative;
      width:100%;
  }
  </code></pre>
  
  <p>You can find a demo here : <a href="http://darkcid.olympe.in/" rel="nofollow">http://darkcid.olympe.in/</a></p>