web-dev-qa-db-fra.com

Toile HTML5: Zoom

Existe-t-il un moyen simple de zoomer et de reculer dans le canevas (JavaScript)? Fondamentalement, j'ai une toile 400x400px et j'aimerais pouvoir zoomer avec 'mousedown' (2x) et revenir avec 'mouseup'.

J'ai passé deux jours à googler, mais pas de chance jusqu'à présent. :(

46
jack moore

En vous appuyant sur la suggestion d'utiliser drawImage, vous pouvez également combiner cela avec la fonction d'échelle.

Donc, avant de dessiner l'image, redimensionnez le contexte au niveau de zoom souhaité:

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

J'ai créé un petit exemple ici http://jsfiddle.net/mBzVR/4/ qui utilise drawImage et scale pour zoomer sur mousedown et out sur mouseup.

55
Castrohenge

Essayez ceci:

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

Fonctionne parfaitement pour moi avec le zoom et le mouvement de la souris .. vous pouvez le personnaliser pour monter et descendre la molette de la souris Njoy !!!

16
GOK

IIRC Canvas est un bitmap de style raster. il ne sera pas zoomable car il n'y a aucune information stockée sur laquelle zoomer.

Votre meilleur pari est de garder deux copies en mémoire (zoomées et non) et de les échanger en un clic de souris.

6
Karl

Si vous avez une image source ou un élément de canevas et votre canevas 400x400 dans lequel vous souhaitez dessiner, vous pouvez utiliser la méthode drawImage pour effectuer un zoom.

Ainsi, par exemple, la vue complète pourrait ressembler à ceci

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

Et une vue agrandie pourrait ressembler à ceci

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

Le premier paramètre à drawImage est l'élément image ou l'élément canvas à dessiner, les 4 suivants sont les x, y, largeur et hauteur à échantillonner à partir de la source et les 4 derniers paramètres sont les x, y, largeur et hauteur de la région à dessiner dans la toile. Il gérera ensuite la mise à l'échelle pour vous.

Vous auriez juste besoin de choisir la largeur et la hauteur de l'échantillon source en fonction du niveau de zoom et des x et y en fonction de l'endroit où la souris est cliquée moins la moitié de la largeur et de la hauteur calculées (mais vous devrez vous assurer que le rectangle n'est pas hors limites).

4
Kyle Jones