65 votes

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. :(

Merci pour l'aide.

79voto

Castrohenge Points 2919

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.

24voto

GOK Points 668

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

7voto

Kyle Jones Points 348

Si vous avez une source de l'image ou de l'élément canvas et votre 400x400 toile que vous voulez dessiner, vous pouvez utiliser la méthode drawImage pour atteindre le zoom.

Ainsi, par exemple, la vue complète pourrait être comme ceci

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

Et une vue agrandie, peut-être comme 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ément canvas pour dessiner, les 4 sont x, y, largeur et hauteur de l'échantillon à partir de la source et les 4 derniers paramètres sont les x, y, largeur et hauteur de la région de dessiner sur le canevas. Il prendra alors en charge la mise à l'échelle pour vous.

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

4voto

Karl Points 3336

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X