HTML5 Canvas:缩放

jac*_*ore 48 javascript canvas

有没有简单的方法如何在画布(JavaScript)中放大和缩小?基本上我有一个400x400px画布,我希望能够使用'mousedown'(2x)进行放大,然后使用'mouseup'返回.

花了两天的谷歌搜索,但到目前为止没有运气.:(

感谢帮助.

Cas*_*nge 58

基于使用drawImage的建议,您还可以将其与缩放功能结合使用.

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

ctx.scale(2, 2) // Doubles size of anything draw to canvas.
Run Code Online (Sandbox Code Playgroud)

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

  • 警告!如果你不关心你的图像像素化这将很好.否则,您应该按比例将所有尺寸和运动数据相乘.您可以将其存储在相机对象中,并根据缩放级别输出比率. (9认同)

GOK*_*GOK 16

试试吧:

<!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>
Run Code Online (Sandbox Code Playgroud)

通过缩放和鼠标移动为我完美的工作..你可以自定义鼠标滚轮向上和向下Njoy!


小智 8

如果您有一个源图像或画布元素以及您想要绘制的 400x400 画布,则可以使用 drawImage 方法来实现缩放。

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

ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
Run Code Online (Sandbox Code Playgroud)

放大的视图可能是这样的

ctx.drawImage(img, img.width / 4, img.height / 4, img.width / 2, img.height / 2, 0, 0, canvas.width, canvas.height);
Run Code Online (Sandbox Code Playgroud)

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

您只需要根据缩放级别选择源样本的宽度和高度,并根据单击鼠标的位置减去计算的宽度和高度的一半来选择 x 和 y(但您需要确保矩形不是越界)。


小智 7

画布缩放和平移

<!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>
Run Code Online (Sandbox Code Playgroud)

  • 不过,平移不会根据缩放级别进行调整。 (2认同)

Kar*_*arl 6

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

最好的办法是在内存中保留两份副本(缩放和非缩放)并在鼠标单击时交换它们.

  • 不,这不是您最好的选择,那么您必须为每种可能的比例存储一个 (2认同)