简体   繁体   English

HTML5 Canvas:缩放

[英]HTML5 Canvas: Zooming

Is there any easy way how to zoom in and back out in canvas (JavaScript)?有没有什么简单的方法可以在画布(JavaScript)中放大和缩小? Basically I have a 400x400px canvas and I'd like to be able to zoom in with 'mousedown' (2x) and go back with 'mouseup'.基本上我有一个 400x400 像素的画布,我希望能够使用“鼠标向下”(2x)放大并使用“鼠标向上”返回。

Spent last two days googling, but no luck so far.最后两天在谷歌上搜索,但到目前为止还没有运气。 :( :(

Building on the suggestion of using drawImage you could also combine this with scale function.基于使用 drawImage 的建议,您还可以将其与缩放功能结合使用。

So before you draw the image scale the context to the zoom level you want:因此,在绘制图像之前,将上下文缩放到您想要的缩放级别:

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

I've created a small example here http://jsfiddle.net/mBzVR/4/ that uses drawImage and scale to zoom in on mousedown and out on mouseup.我在这里创建了一个小例子http://jsfiddle.net/mBzVR/4/ ,它使用 drawImage 和 scale 在 mousedown 上放大和在 mouseup 上缩小。

Try this out:试试这个:

 <!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>

This works perfectly for me with zooming and mouse movement.这对我来说非常适合缩放和鼠标移动。 You can customize it to use the mouse wheel up & down.您可以自定义它以使用鼠标滚轮上下。

Here is a fiddle这是一个小提琴

If you have a source image or canvas element and your 400x400 canvas you want to draw into you can use the drawImage method to achieve zooming.如果您有一个源图像或画布元素以及您想要绘制的 400x400 画布,则可以使用 drawImage 方法来实现缩放。

So for example, the full view might be like this例如,完整视图可能是这样的

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

And a zoomed view might be like this放大的视图可能是这样的

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

The first parameter to drawImage is the image element or canvas element to draw, the next 4 are the x, y, width and height to sample from the source and the last 4 parameters are the x, y, width and height of the region to draw in the canvas. drawImage 的第一个参数是要绘制的图像元素或画布元素,接下来的 4 个参数是要从源中采样的 x、y、宽度和高度,最后 4 个参数是要绘制的区域的 x、y、宽度和高度在画布中绘制。 It will then handle the scaling for you.然后它将为您处理缩放。

You would just need to pick the width and height for the source sample based on the zoom level and the x and y based on where the mouse is clicked minus half the calculated width and height (but you will need to ensure the rectangle isn't out of bounds).您只需要根据缩放级别选择源样本的宽度和高度,并根据单击鼠标的位置减去计算的宽度和高度的一半来选择 x 和 y(但您需要确保矩形不是越界)。

IIRC Canvas is a raster style bitmap. IIRC Canvas 是一种光栅样式的位图。 it wont be zoomable because there's no stored information to zoom to.它不会是可缩放的,因为没有可缩放的存储信息。

Your best bet is to keep two copies in memory (zoomed and non) and swap them on mouse click.最好的办法是在内存中保留两个副本(缩放的和非缩放的)并在单击鼠标时交换它们。

Canvas zoom and pan画布缩放和平移

 <!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=ex;py=ey;canvas.onmousemove=(e)=>{ox-=(ex-px);oy-=(ey-py);px=ex;py=ey;} } canvas.onmouseup=()=>{canvas.onmousemove=null;} canvas.onwheel =(e)=>{let bfzx,bfzy,afzx,afzy;[bfzx,bfzy]=StoW(ex,ey);scx-=10*scx/e.deltaY;scy-=10*scy/e.deltaY; [afzx,afzy]=StoW(ex,ey); 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>

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM