【问题标题】:HTML5 Canvas: ZoomingHTML5 画布:缩放
【发布时间】:2010-08-06 04:21:30
【问题描述】:

有没有什么简单的方法可以放大和缩小画布(JavaScript)?基本上我有一个 400x400px 的画布,我希望能够使用“mousedown”(2x)放大并使用“mouseup”返回。

过去两天用谷歌搜索,但到目前为止没有运气。 :(

【问题讨论】:

    标签: javascript canvas


    【解决方案1】:

    根据使用 drawImage 的建议,您还可以将其与缩放功能结合使用。

    因此,在您绘制图像之前,将上下文缩放到您想要的缩放级别:

    ctx.scale(2, 2) // Doubles size of anything draw to canvas.
    

    我在这里创建了一个小示例http://jsfiddle.net/mBzVR/4/,它使用 drawImage 和 scale 来放大 mousedown 和缩小 mouseup。

    【讨论】:

    • 警告!如果您不关心图像像素化,这将正常工作。否则,您应该将所有尺寸和运动数据乘以一个比率。您可以将其存储在相机对象中并根据缩放级别输出比例。
    • O,理论上你应该能够通过将图像渲染成大尺寸来修复像素化问题。
    • 还请记住,所有内容都会按比例放大,包括边框。如果您想在不加粗轮廓的情况下增加形状的大小,则必须在绘制它们时手动乘以它们的宽度、高度和位置。
    • 我想用鼠标滚轮在画布上缩放 pdf。我可以用画布吗
    • @AshBlue 你有使用你方法的例子吗?
    【解决方案2】:

    试试这个:

    <!DOCTYPE HTML>
    <html>
    
    <head>
      <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
      <style>
        body {
          margin: 0px;
          padding: 0px;
        }
        
        #wrapper {
          position: relative;
          border: 1px solid #9C9898;
          width: 578px;
          height: 200px;
        }
        
        #buttonWrapper {
          position: absolute;
          width: 30px;
          top: 2px;
          right: 2px;
        }
        
        input[type="button"] {
          padding: 5px;
          width: 30px;
          margin: 0px 0px 2px 0px;
        }
      </style>
      <script>
        function draw(scale, translatePos) {
          var canvas = document.getElementById("myCanvas");
          var context = canvas.getContext("2d");
    
          // clear canvas
          context.clearRect(0, 0, canvas.width, canvas.height);
    
          context.save();
          context.translate(translatePos.x, translatePos.y);
          context.scale(scale, scale);
          context.beginPath(); // begin custom shape
          context.moveTo(-119, -20);
          context.bezierCurveTo(-159, 0, -159, 50, -59, 50);
          context.bezierCurveTo(-39, 80, 31, 80, 51, 50);
          context.bezierCurveTo(131, 50, 131, 20, 101, 0);
          context.bezierCurveTo(141, -60, 81, -70, 51, -50);
          context.bezierCurveTo(31, -95, -39, -80, -39, -50);
          context.bezierCurveTo(-89, -95, -139, -80, -119, -20);
          context.closePath(); // complete custom shape
          var grd = context.createLinearGradient(-59, -100, 81, 100);
          grd.addColorStop(0, "#8ED6FF"); // light blue
          grd.addColorStop(1, "#004CB3"); // dark blue
          context.fillStyle = grd;
          context.fill();
    
          context.lineWidth = 5;
          context.strokeStyle = "#0000ff";
          context.stroke();
          context.restore();
        }
    
        window.onload = function() {
          var canvas = document.getElementById("myCanvas");
    
          var translatePos = {
            x: canvas.width / 2,
            y: canvas.height / 2
          };
    
          var scale = 1.0;
          var scaleMultiplier = 0.8;
          var startDragOffset = {};
          var mouseDown = false;
    
          // add button event listeners
          document.getElementById("plus").addEventListener("click", function() {
            scale /= scaleMultiplier;
            draw(scale, translatePos);
          }, false);
    
          document.getElementById("minus").addEventListener("click", function() {
            scale *= scaleMultiplier;
            draw(scale, translatePos);
          }, false);
    
          // add event listeners to handle screen drag
          canvas.addEventListener("mousedown", function(evt) {
            mouseDown = true;
            startDragOffset.x = evt.clientX - translatePos.x;
            startDragOffset.y = evt.clientY - translatePos.y;
          });
    
          canvas.addEventListener("mouseup", function(evt) {
            mouseDown = false;
          });
    
          canvas.addEventListener("mouseover", function(evt) {
            mouseDown = false;
          });
    
          canvas.addEventListener("mouseout", function(evt) {
            mouseDown = false;
          });
    
          canvas.addEventListener("mousemove", function(evt) {
            if (mouseDown) {
              translatePos.x = evt.clientX - startDragOffset.x;
              translatePos.y = evt.clientY - startDragOffset.y;
              draw(scale, translatePos);
            }
          });
    
          draw(scale, translatePos);
        };
    
    
    
        jQuery(document).ready(function() {
          $("#wrapper").mouseover(function(e) {
            $('#status').html(e.pageX + ', ' + e.pageY);
          });
        })
      </script>
    </head>
    
    <body onmousedown="return false;">
      <div id="wrapper">
        <canvas id="myCanvas" width="578" height="200">
        </canvas>
        <div id="buttonWrapper">
          <input type="button" id="plus" value="+"><input type="button" id="minus" value="-">
        </div>
      </div>
      <h2 id="status">
        0, 0
      </h2>
    </body>
    
    </html>

    这对我来说非常适合缩放和鼠标移动。您可以对其进行自定义以上下使用鼠标滚轮。

    Here is a fiddle

    【讨论】:

    • 嗨,GOK,想知道是否可以将您的代码应用于图像而不是您自己的绘图?我试过下面的代码,但它不允许我拖动。我可以知道它有什么问题吗? ` var imageObj = new Image(); imageObj.onload = function() { context.drawImage(imageObj, 69, 50); }; imageObj.src = 'html5canvastutorials.com/demos/assets/darth-vader.jpg';`
    • 嗨,GOK,还想知道您是否有解决方案来缩放与translatePos 的偏移量,以便视图保持居中。现在,如果您更改偏移和缩放,它将缩放图像的中心,而不是当前画布中心的位置。在重新缩放以保持缩放正确居中后,我找不到更新translatePos 的方法。有什么建议吗?
    【解决方案3】:

    如果您有源图像或画布元素,并且您想在 400x400 画布上进行绘制,则可以使用 drawImage 方法来实现缩放。

    例如,完整的视图可能是这样的

    ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);

    放大后的视图可能是这样的

    ctx.drawImage(img, img.width / 4, img.height / 4, img.width / 2, img.height / 2, 0, 0, canvas.width, canvas.height);

    drawImage的第一个参数是要绘制的图像元素或canvas元素,接下来的4个是要从源中采样的x、y、width和height,最后4个参数是x、y、width和height要在画布中绘制的区域。然后它将为您处理缩放。

    您只需要根据缩放级别选择源样本的宽度和高度,并根据鼠标点击的位置减去计算的宽度和高度的一半来选择 x 和 y(但您需要确保矩形没有超出范围)。

    【讨论】:

      【解决方案4】:

      画布缩放和平移

      <!DOCTYPE html>
      <html>
      <body>
      
      <canvas id="myCanvas" width="" height=""
      style="border:1px solid #d3d3d3;">
      Your browser does not support the canvas element.
      </canvas>
      
      <script>
      console.log("canvas")
      var ox=0,oy=0,px=0,py=0,scx=1,scy=1;
      var canvas = document.getElementById("myCanvas");
      canvas.onmousedown=(e)=>{px=e.x;py=e.y;canvas.onmousemove=(e)=>{ox-=(e.x-px);oy-=(e.y-py);px=e.x;py=e.y;} } 
      
      canvas.onmouseup=()=>{canvas.onmousemove=null;}
      canvas.onwheel =(e)=>{let bfzx,bfzy,afzx,afzy;[bfzx,bfzy]=StoW(e.x,e.y);scx-=10*scx/e.deltaY;scy-=10*scy/e.deltaY;
      [afzx,afzy]=StoW(e.x,e.y);
      ox+=(bfzx-afzx);
      oy+=(bfzy-afzy);
      }
      var ctx = canvas.getContext("2d");
      
      function draw(){
      window.requestAnimationFrame(draw);
      ctx.clearRect(0,0,canvas.width,canvas.height);
      for(let i=0;i<=100;i+=10){
      let sx=0,sy=i;
      let ex=100,ey=i;
      [sx,sy]=WtoS(sx,sy);
      [ex,ey]=WtoS(ex,ey);
      ctx.beginPath();
      ctx.moveTo(sx, sy);
      ctx.lineTo(ex, ey);
      ctx.stroke();
      }
      for(let i=0;i<=100;i+=10){
      let sx=i,sy=0;
      let ex=i,ey=100;
      [sx,sy]=WtoS(sx,sy);
      [ex,ey]=WtoS(ex,ey);
      ctx.beginPath();
      ctx.moveTo(sx, sy);
      ctx.lineTo(ex, ey);
      ctx.stroke();
      }
      }
      draw()
      function WtoS(wx,wy){
      let sx=(wx-ox)*scx;
      let sy=(wy-oy)*scy;
      return[sx,sy];
      }
      function StoW(sx,sy){
      let wx=sx/scx+ox;
      let wy=sy/scy+oy;
      return[wx,wy];
      }
      
      </script>
      
      </body>
      </html>

      【讨论】:

      • 平移无法调整到缩放级别。
      【解决方案5】:

      IIRC Canvas 是一种光栅样式的位图。它不能缩放,因为没有可缩放的存储信息。

      您最好的选择是在内存中保留两个副本(放大的和非放大的)并在单击鼠标时交换它们。

      【讨论】:

      • 不,这不是您最好的选择,那么您必须为每个可能的比例存储一个
      【解决方案6】:

      一种选择是使用 css 缩放功能:

      $("#canvas_id").css("zoom","x%"); 
      

      【讨论】:

        猜你喜欢
        • 2012-12-06
        • 2014-01-04
        • 1970-01-01
        • 2014-09-14
        • 2015-03-06
        • 2011-04-17
        • 2014-08-21
        • 2014-08-27
        • 1970-01-01
        相关资源
        最近更新 更多