使用光标事件缩放图像的选定部分 [英] zooming a selected part of image with cursor event

查看:103
本文介绍了使用光标事件缩放图像的选定部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个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/

解决方案

对于那些在不使用画布的情况下寻求缩放功能 的人来说,这是一个使用简单的<img />的万无一失的解决方案: /p>

 $(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放在同一容器元素中并排放置.我还没有测试过.

并不太复杂,没有很多注释,但是变量名非常不言自明,使代码易于阅读,并且可以查找所有jquery函数.

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

如果您想确切了解正在发生的事情,请看一下代码,正如我所说的那样,并不太困难.

I have this jsfiddle : http://jsfiddle.net/seekpunk/JDU9f/1/

what I want is when the user do a selection the selected part is zoomed in .Is there anyway to achieve this ?

this is the code so far :

  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);
    };

I can make the selection but how can i zoom the selected part only ? like this example : http://canvasjs.com/docs/charts/basics-of-creating-html5-chart/zooming-panning/

解决方案

For those looking for zooming functionality without the use of a canvas, here's a pretty foolproof solution using a simple <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/

  • The container element can be anything, just place the .zoombox on your webpage and it should work.
  • You should even be able to put multiple .zoomboxes next to each other in the same container-element. I haven't tested it though.

It's not too complicated, there's not a whole lot of comments, but the variable names are pretty self-explanatory and make the code easy enough to read, and all the jquery-functions can be looked up.

The code is essentially divided into three handlers: .mousedown(), .mousemove(), .mouseup().
- In mousedown some values are stored into variables (like the start-coordinates for the selector), which are used in mousemove and mouseup as a reference.

If you want to know exactly what's happening, just have a look at the code, as I said it's not too difficult.

这篇关于使用光标事件缩放图像的选定部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆