简体   繁体   中英

Resizing canvas without maintaining proportions

In this program, I have a bit of code that changes the width of a canvas in response to a change of a slider. However, I noticed that the canvas resizes to maintain its aspect ratio.

Is there any way to prevent this from happening so that the canvas simply gets squished/expanded from the sides? Alternatively, could I make it so that the balls do not change size with the canvas and maintain their original sizes?

Code:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <style>
    </style>
    <body>
        <canvas id="my_canvas" width="600px" height="300px"></canvas>
        <script>
            var canvas = document.getElementById("my_canvas");
            var c = canvas.getContext("2d");

            //create ball container
            var container = {
                x: 0,
                y: 0,
                width: 600,
                height: 300
            };

            //make balls array
            var balls = [{
                x: 50,
                y: 100,
                r: 20,
                vx: 10,
                vy:10,
                color: 125
            }, {
                x: 150,
                y: 80,
                r: 20,
                vx: 10,
                vy: 10,
                color: 105
            }, {
                x: 90,
                y: 150,
                r: 20,
                vx: 10,
                vy: 10,
                color: 20
            }, {
                x: 100,
                y: 50,
                r: 20,
                vx: 10,
                vy: 10,
                color: 80
            }];

            function animate() {
                //draw container
                c.fillStyle = "#000000";
                c.fillRect(container.x, container.y, container.width,      container.height);

                //loop  balls array
                for (var i = 0; i < balls.length; i++) {
                    //draw balls
                    c.fillStyle = 'hsl(' + balls[i].color++ + ', 100%, 50%)';
                    c.beginPath();
                    c.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI * 2, true);
                    c.fill();

                    //animate balls
                    if (balls[i].x - balls[i].r + balls[i].vx < container.x || balls[i].x +   balls[i].r +  balls[i].vx > container.x + container.width) {
                        balls[i].vx = -balls[i].vx;
                    }

                    if (balls[i].y + balls[i].r + balls[i].vy > container.y + container.height || balls[i].y - balls[i].r + balls[i].vy < container.y) {
                        balls[i].vy = -balls[i].vy;
                    }

                    balls[i].x += balls[i].vx;
                    balls[i].y += balls[i].vy;
                }
                requestAnimationFrame(animate);
            }
            requestAnimationFrame(animate);

            function myFunction () {
                document.getElementById("my_canvas").style.width = document.getElementById("VolumeInputId").value + "px";
            }
        </script>
        <form name = "volume">
            <label for="volume">Volume</label>
            <input type="range" name="VolumeInputName" id="VolumeInputId" value=600  min="300" max="600" onchange="myFunction()">
            <output name="VolumeOutputName" id="VolumeOutputId"></output>
        </form>
    </body>
</html>

Resizing the canvas with style should not be done unless you want to see a pixelated picture.

 var canvas = document.getElementById("my_canvas"); var c = canvas.getContext("2d"); c.beginPath(); c.moveTo(0,0); c.lineTo(30,30); c.stroke(); document.getElementById("my_canvas").style.width = "280px"; 
 canvas { border: 1px solid black; } 
 <canvas id="my_canvas" width="60px" height="30px"></canvas> 

As you can see a 60 x 30 canvas when scaled via style to 280px shows a pixelated straight line.

But if you use canvas.width and canvas.height you can change each one independently and without interpolated pixels.

 var canvas = document.getElementById("my_canvas"); var c = canvas.getContext("2d"); canvas.width = 280; canvas.height = 200; c.beginPath(); c.moveTo(0,0); c.lineTo(30,30); c.stroke(); 
 canvas { border: 1px solid black; } 
 <canvas id="my_canvas" width="60px" height="30px"></canvas> 

In this case the canvas width and height are changed independently and the stright line size is still the same.

height and width are properties of the canvas object (not the context).

Here is a detailed fiddle with the original, resized by style and resized by properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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