使用光标事件缩放图像的选定部分

时间:2014-06-16 10:51:14

标签: javascript jquery

我有这个jsfiddle:http://jsfiddle.net/seekpunk/JDU9f/1/

我想要的是当用户进行选择时,所选部分被放大。无论如何要实现这一点吗?

到目前为止这是代码:

  var canvas = document.getElementById("MyCanvas");
    var ctx = canvas.getContext('2d'),
        w = canvas.width,
        h = canvas.height,
        x1,
        y1,
        isDown = false;
    var img = new Image();
    img.src = "http://www.stockfreeimages.com/static/homepage/female-chaffinch-free-stock-photo-106202.jpg";
    canvas.onmousedown = function (e) {
        var rect = canvas.getBoundingClientRect();
        x1 = e.clientX - rect.left;
        y1 = e.clientY - rect.top;
        isDown = true;
    }
    canvas.onmouseup = function () {
        isDown = false;
    }
    canvas.onmousemove = function (e) {

        if (!isDown) return;

        var rect = canvas.getBoundingClientRect(),
            x2 = e.clientX - rect.left,
            y2 = e.clientY - rect.top;
        ctx.clearRect(0, 0, w, h);
        ctx.drawImage(img, 0, 0, w, h);
        ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
    }

    img.onload = function () {
        ctx.drawImage(img, 0, 0, w, h);
    };

我可以进行选择但是如何仅缩放所选部分?像这个例子:http://canvasjs.com/docs/charts/basics-of-creating-html5-chart/zooming-panning/

1 个答案:

答案 0 :(得分:2)

对于那些在不使用画布的情况下寻找缩放功能的人,这是一个使用简单<img />的非常简单的解决方案:

$(window).on("load",function() {
  //VARS===================================================
  var zoom = {
    zoomboxLeft:null, zoomboxTop:null, //zoombox
    cursorStartX:null, cursorStartY:null, //cursor
    imgStartLeft:null, imgStartTop:null, //image
    minDragLeft:null,maxDragLeft:null, minDragTop:null,maxDragTop:null
  };
  
  //KEY-HANDLERS===========================================
  $(document).keydown(function(e) {
    if (e.which==32) {e.preventDefault(); if (!$(".zoombox img").hasClass("moving")) {$(".zoombox img").addClass("drag");}} //SPACE
  });
  $(document).keyup(function(e) {
    if (e.which==32) {if (!$(".zoombox img").hasClass("moving")) {$(".zoombox img").removeClass("drag");}} //SPACE
  });
  
  //RESET IMAGE SIZE=======================================
  $(".reset").on("click",function() {
    var zoombox = "#"+$(this).parent().attr("id")+" .zoombox";
    $(zoombox+" img").css({"left":0, "top":0, "width":$(zoombox).width(), "height":$(zoombox).height()});
  }).click();
  
  //ZOOM&DRAG-EVENTS=======================================
  //MOUSEDOWN----------------------------------------------
  $(".zoombox img").mousedown(function(e) {
    e.preventDefault();
    $(".zoombox img").addClass("moving");
    var selector = $(this).next();
    var zoombox = $(this).parent();
    $(zoombox).addClass("active");
    
    //store zoombox left&top
    zoom.zoomboxLeft = $(zoombox).offset().left + parseInt($(zoombox).css("border-left-width").replace(/\D+/,""));
    zoom.zoomboxTop = $(zoombox).offset().top + parseInt($(zoombox).css("border-top-width").replace(/\D+/,""));
    
    //store starting positions of cursor (relative to zoombox)
    zoom.cursorStartX = e.pageX - zoom.zoomboxLeft;
    zoom.cursorStartY = e.pageY - zoom.zoomboxTop;
    
    if ($(".zoombox img").hasClass("drag")) {
      //store starting positions of image (relative to zoombox)
      zoom.imgStartLeft = $(this).position().left;
      zoom.imgStartTop = $(this).position().top;
      
      //set drag boundaries (relative to zoombox)
      zoom.minDragLeft = $(zoombox).width() - $(this).width();
      zoom.maxDragLeft = 0;
      zoom.minDragTop = $(zoombox).height() - $(this).height();
      zoom.maxDragTop = 0;
    } else {
      //set drag boundaries (relative to zoombox)
      zoom.minDragLeft = 0;
      zoom.maxDragLeft = $(zoombox).width();
      zoom.minDragTop = 0;
      zoom.maxDragTop = $(zoombox).height();
      
      //activate zoom-selector
      $(selector).css({"display":"block", "width":0, "height":0, "left":zoom.cursorStartX, "top":zoom.cursorStartY});
    }
  });
  
  //MOUSEMOVE----------------------------------------------
  $(document).mousemove(function(e) {
    if ($(".zoombox img").hasClass("moving")) {
      if ($(".zoombox img").hasClass("drag")) {
        var img = $(".zoombox.active img")[0];
        
        //update image position (relative to zoombox)
        $(img).css({
          "left": zoom.imgStartLeft + (e.pageX-zoom.zoomboxLeft)-zoom.cursorStartX,
          "top": zoom.imgStartTop + (e.pageY-zoom.zoomboxTop)-zoom.cursorStartY
        });
        //prevent dragging in prohibited areas (relative to zoombox)
        if ($(img).position().left <= zoom.minDragLeft) {$(img).css("left",zoom.minDragLeft);} else 
        if ($(img).position().left >= zoom.maxDragLeft) {$(img).css("left",zoom.maxDragLeft);}
        if ($(img).position().top <= zoom.minDragTop) {$(img).css("top",zoom.minDragTop);} else 
        if ($(img).position().top >= zoom.maxDragTop) {$(img).css("top",zoom.maxDragTop);}
      } else {
        //calculate selector width and height (relative to zoombox)
        var width = (e.pageX-zoom.zoomboxLeft)-zoom.cursorStartX;
        var height = (e.pageY-zoom.zoomboxTop)-zoom.cursorStartY;
        
        //prevent dragging in prohibited areas (relative to zoombox)
        if (e.pageX-zoom.zoomboxLeft <= zoom.minDragLeft) {width = zoom.minDragLeft - zoom.cursorStartX;} else 
        if (e.pageX-zoom.zoomboxLeft >= zoom.maxDragLeft) {width = zoom.maxDragLeft - zoom.cursorStartX;}
        if (e.pageY-zoom.zoomboxTop <= zoom.minDragTop) {height = zoom.minDragTop - zoom.cursorStartY;} else 
        if (e.pageY-zoom.zoomboxTop >= zoom.maxDragTop) {height = zoom.maxDragTop - zoom.cursorStartY;}
        
        //update zoom-selector
        var selector = $(".zoombox.active .selector")[0];
        $(selector).css({"width":Math.abs(width), "height":Math.abs(height)});
        if (width<0) {$(selector).css("left",zoom.cursorStartX-Math.abs(width));}
        if (height<0) {$(selector).css("top",zoom.cursorStartY-Math.abs(height));}
      }
    }
  });
  
  //MOUSEUP------------------------------------------------
  $(document).mouseup(function() {
    if ($(".zoombox img").hasClass("moving")) {
      if (!$(".zoombox img").hasClass("drag")) {
        var img = $(".zoombox.active img")[0];
        var selector = $(".zoombox.active .selector")[0];
        
        if ($(selector).width()>0 && $(selector).height()>0) {
          //resize zoom-selector and image
          var magnification = ($(selector).width()<$(selector).height() ? $(selector).parent().width()/$(selector).width() : $(selector).parent().height()/$(selector).height()); //go for the highest magnification
          var hFactor = $(img).width() / ($(selector).position().left-$(img).position().left);
          var vFactor = $(img).height() / ($(selector).position().top-$(img).position().top);
          $(selector).css({"width":$(selector).width()*magnification, "height":$(selector).height()*magnification});
          $(img).css({"width":$(img).width()*magnification, "height":$(img).height()*magnification});
          //correct for misalignment during magnification, caused by size-factor
          $(img).css({
            "left": $(selector).position().left - ($(img).width()/hFactor),
            "top": $(selector).position().top - ($(img).height()/vFactor)
          });
          
          //reposition zoom-selector and image (relative to zoombox)
          var selectorLeft = ($(selector).parent().width()/2) - ($(selector).width()/2);
          var selectorTop = ($(selector).parent().height()/2) - ($(selector).height()/2);
          var selectorDeltaLeft = selectorLeft - $(selector).position().left;
          var selectorDeltaTop = selectorTop - $(selector).position().top;
          $(selector).css({"left":selectorLeft, "top":selectorTop});
          $(img).css({"left":"+="+selectorDeltaLeft, "top":"+="+selectorDeltaTop});
        }
        //deactivate zoom-selector
        $(selector).css({"display":"none", "width":0, "height":0, "left":0, "top":0});
      } else {$(".zoombox img").removeClass("drag");}
      $(".zoombox img").removeClass("moving");
      $(".zoombox.active").removeClass("active");
    }
  });
});
/*CONTAINER-------------------*/
#container {
  width: 234px;
  height: 199px;
  margin-left: auto;
  margin-right: auto;
}

/*ZOOMBOX=====================*/
/*IMAGE-----------------------*/
.zoombox {
  position:relative;
  width: 100%;
  height: 100%;
  border: 2px solid #AAAAAA;
  background-color: #666666;
  overflow: hidden;
}
.zoombox img {position:relative;}
.zoombox img.drag {cursor:move;}
.zoombox .selector {
  display: none;
  position: absolute;
  border: 1px solid #999999;
  background-color: rgba(255,255,255, 0.3);
}
/*CONTROL---------------------*/
.reset {float:left;}
.info {float:right;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="container">
  <!--ZOOMBOX-->
  <div class="zoombox">
    <img src="http://www.w3schools.com/colors/img_colormap.gif" />
    <div class="selector"></div>
  </div>
  <input type="button" class="reset" value="Reset" /><span class="info">Press SPACE to drag</span>
</div>
jsfiddle:http://jsfiddle.net/2nt8k8e6/

  • container元素可以是任何内容,只需将.zoombox放在您的网页上即可。
  • 您甚至应该能够在同一个容器元素中将多个.zoombox es放在一起。我没有测试过它。

它不是太复杂,没有很多注释,但变量名称非常明显,使代码易于阅读,所有jquery函数都可以查找。

代码主要分为三个处理程序:.mousedown().mousemove().mouseup()
  - 在mousedown中,某些值存储在变量中(例如选择器的起始坐标),这些值在mousemovemouseup中用作参考。

如果你想确切知道发生了什么,只需查看代码,就像我说的那样并不太难。