Ingrandisci un punto (usando la scala e traduci)


156

Voglio essere in grado di ingrandire il punto sotto il mouse in una tela HTML 5, come lo zoom su Google Maps . Come posso raggiungerlo?


2
L'ho usato per ingrandire la mia tela e funziona benissimo! L'unica cosa che devo aggiungere è che il calcolo dell'importo dello zoom non è come ci si aspetterebbe. "var zoom = 1 + wheel / 2;" ciò significa che si ottiene 1,5 per lo zoom avanti e 0,5 per lo zoom indietro. Ho modificato questo nella mia versione in modo da avere 1,5 per lo zoom in avanti e 1 / 1.5 per lo zoom indietro, il che rende la quantità di ingrandimento e zoom indietro uguale. Quindi, se ingrandisci una volta e esegui lo zoom indietro, otterrai la stessa immagine di prima dello zoom.
Chris,

2
Nota che questo non funziona su Firefox, ma il metodo può essere facilmente applicato al plug-in rotellina del mouse jQuery . Grazie per la condivisione!
johndodo,

2
var zoom = Math.pow (1.5f, ruota); // Usa questo per calcolare lo zoom. Ha il vantaggio che lo zoom con ruota = 2 equivale allo zoom due volte con ruota = 1. Inoltre, ingrandendo di +2 e diminuendo di +2 ripristina la scala originale.
Matt,

Risposte:


126

La soluzione migliore è semplicemente spostare la posizione del viewport in base alla modifica dello zoom. Il punto di zoom è semplicemente il punto nel vecchio zoom e nel nuovo zoom che si desidera mantenere invariati. Vale a dire che il viewport pre-zoomato e il viewport post-zoom hanno lo stesso punto di zoom rispetto al viewport. Dato che stiamo ridimensionando rispetto all'origine. È possibile regolare la posizione della finestra di conseguenza:

scalechange = newscale - oldscale;
offsetX = -(zoomPointX * scalechange);
offsetY = -(zoomPointY * scalechange);

Quindi davvero puoi semplicemente spostarti verso il basso e verso destra quando ingrandisci, in base a quanto hai ingrandito, rispetto al punto su cui hai ingrandito.

inserisci qui la descrizione dell'immagine


2
Più prezioso del codice taglia e incolla è la spiegazione di quale sia la soluzione migliore e perché funzioni senza il bagaglio, specialmente se è lungo tre righe.
Tatarize,

2
scalechange = newscale / oldscale?
Tejesh Alimilli,

4
Inoltre, vorrei aggiungere per quelli che cercano di ottenere una mappa come il componente pan-zoom, che il mouse X, Y dovrebbe essere (mousePosRelativeToContainer - currentTransform) / currentScale altrimenti tratterà l'attuale posizione del mouse come relativa al contenitore.
Gilad,

1
Sì, questa matematica presuppone che lo zoom e la panoramica siano nei contorni pertinenti all'origine. Se sono relativi alla finestra, è necessario regolarli in modo appropriato. Anche se suppongo che la matematica corretta sia zoomPoint = (mousePosRelativeToContainer + currentTranslation). Questa matematica presuppone anche che il punto di origine sia in genere nella parte superiore sinistra del campo. Tuttavia, adattarsi a situazioni leggermente atipiche è molto più semplice data la semplicità.
Tatarize

1
@ C.Finke Il secondo modo in cui può essere fatto è usando le traduzioni all'interno del ctx. Disegni tutto della stessa dimensione e nelle stesse posizioni. Tuttavia, è sufficiente utilizzare le moltiplicazioni di matrice all'interno dell'area di disegno javascript per impostare la panoramica e la scala (zoom) del contesto. Quindi, piuttosto che ridisegnare tutte le forme in una posizione diversa. Li disegni nello stesso posto e sposti la finestra all'interno di javascript. Questo metodo richiederebbe anche di prendere gli eventi del mouse e tradurli all'indietro. Quindi sottrarre la panoramica, quindi invertire il fattore con lo zoom.
Tatarize

68

Finalmente risolto:

var zoomIntensity = 0.2;

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = 600;
var height = 200;

var scale = 1;
var originx = 0;
var originy = 0;
var visibleWidth = width;
var visibleHeight = height;


function draw(){
    // Clear screen to white.
    context.fillStyle = "white";
    context.fillRect(originx,originy,800/scale,600/scale);
    // Draw the black square.
    context.fillStyle = "black";
    context.fillRect(50,50,100,100);
}
// Draw loop at 60FPS.
setInterval(draw, 1000/60);

canvas.onwheel = function (event){
    event.preventDefault();
    // Get mouse offset.
    var mousex = event.clientX - canvas.offsetLeft;
    var mousey = event.clientY - canvas.offsetTop;
    // Normalize wheel to +1 or -1.
    var wheel = event.deltaY < 0 ? 1 : -1;

    // Compute zoom factor.
    var zoom = Math.exp(wheel*zoomIntensity);
    
    // Translate so the visible origin is at the context's origin.
    context.translate(originx, originy);
  
    // Compute the new visible origin. Originally the mouse is at a
    // distance mouse/scale from the corner, we want the point under
    // the mouse to remain in the same place after the zoom, but this
    // is at mouse/new_scale away from the corner. Therefore we need to
    // shift the origin (coordinates of the corner) to account for this.
    originx -= mousex/(scale*zoom) - mousex/scale;
    originy -= mousey/(scale*zoom) - mousey/scale;
    
    // Scale it (centered around the origin due to the trasnslate above).
    context.scale(zoom, zoom);
    // Offset the visible origin to it's proper position.
    context.translate(-originx, -originy);

    // Update scale and others.
    scale *= zoom;
    visibleWidth = width / scale;
    visibleHeight = height / scale;
}
<canvas id="canvas" width="600" height="200"></canvas>

La chiave, come ha sottolineato @Tatarize , è calcolare la posizione dell'asse in modo che il punto di zoom (puntatore del mouse) rimanga nello stesso posto dopo lo zoom.

Inizialmente il mouse si trova ad una distanza mouse/scaledall'angolo, vogliamo che il punto sotto il mouse rimanga nello stesso posto dopo lo zoom, ma questo è mouse/new_scalelontano dall'angolo. Pertanto è necessario spostare le origin(coordinate dell'angolo) per tenere conto di ciò.

originx -= mousex/(scale*zoom) - mousex/scale;
originy -= mousey/(scale*zoom) - mousey/scale;
scale *= zoom

Il codice rimanente deve quindi applicare il ridimensionamento e tradurre nel contesto di disegno in modo che l'origine coincida con l'angolo della tela.


Grazie amico, quasi perso 2 giorni, prima di trovare il tuo codice
Velaro

Ehi, stavo solo cercando qualcosa del genere e volevo solo dire che mi hai fatto impazzire!
chrisallick,

26

Questo è in realtà un problema molto difficile (matematicamente), e sto lavorando quasi alla stessa cosa. Ho fatto una domanda simile su StackOverflow ma non ho ricevuto risposta, ma ho pubblicato in DocType (StackOverflow per HTML / CSS) e ho ottenuto una risposta. Dai un'occhiata http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example

Sono nel mezzo della creazione di un plug-in jQuery che esegue questa operazione (zoom in stile Google Maps con trasformazioni CSS3). Ho lo zoom sul bit del cursore del mouse che funziona bene, ancora cercando di capire come consentire all'utente di trascinare la tela come puoi fare su Google Maps. Quando avrò funzionato pubblicherò il codice qui, ma controlla il link sopra per la parte del mouse-zoom-to-point.

Non mi ero reso conto che esistessero metodi di ridimensionamento e traduzione nel contesto di Canvas, puoi ottenere la stessa cosa usando ad esempio CSS3. usando jQuery:

$('div.canvasContainer > canvas')
    .css('-moz-transform', 'scale(1) translate(0px, 0px)')
    .css('-webkit-transform', 'scale(1) translate(0px, 0px)')
    .css('-o-transform', 'scale(1) translate(0px, 0px)')
    .css('transform', 'scale(1) translate(0px, 0px)');

Assicurati di impostare CSS3 transform-origin su 0, 0 (-moz-transform-origin: 0 0). L'uso della trasformazione CSS3 ti consente di ingrandire qualsiasi cosa, assicurati solo che il contenitore DIV sia impostato in modo da traboccare: nascosto per impedire ai bordi ingranditi di fuoriuscire dai lati.

Sia che tu usi trasformazioni CSS3, sia la scala di canvas e i metodi di traduzione, dipende da te, ma controlla il link sopra per i calcoli.


Aggiornamento: Meh! Pubblicherò semplicemente il codice qui invece di farti seguire un link:

$(document).ready(function()
{
    var scale = 1;  // scale of the image
    var xLast = 0;  // last x location on the screen
    var yLast = 0;  // last y location on the screen
    var xImage = 0; // last x location on the image
    var yImage = 0; // last y location on the image

    // if mousewheel is moved
    $("#mosaicContainer").mousewheel(function(e, delta)
    {
        // find current location on screen 
        var xScreen = e.pageX - $(this).offset().left;
        var yScreen = e.pageY - $(this).offset().top;

        // find current location on the image at the current scale
        xImage = xImage + ((xScreen - xLast) / scale);
        yImage = yImage + ((yScreen - yLast) / scale);

        // determine the new scale
        if (delta > 0)
        {
            scale *= 2;
        }
        else
        {
            scale /= 2;
        }
        scale = scale < 1 ? 1 : (scale > 64 ? 64 : scale);

        // determine the location on the screen at the new scale
        var xNew = (xScreen - xImage) / scale;
        var yNew = (yScreen - yImage) / scale;

        // save the current screen location
        xLast = xScreen;
        yLast = yScreen;

        // redraw
        $(this).find('div').css('-moz-transform', 'scale(' + scale + ')' + 'translate(' + xNew + 'px, ' + yNew + 'px' + ')')
                           .css('-moz-transform-origin', xImage + 'px ' + yImage + 'px')
        return false;
    });
});

Ovviamente dovrai adattarlo per usare la scala della tela e tradurre i metodi.


Aggiornamento 2: Ho appena notato che sto usando Transform-Origin insieme a Translate. Sono riuscito a implementare una versione che utilizza solo la scala e la traduzione da sola, controlla qui http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Attendi il download delle immagini quindi usa il tuo la rotellina del mouse per lo zoom, supporta anche la panoramica trascinando l'immagine. Sta usando CSS3 Transforms ma dovresti essere in grado di usare gli stessi calcoli per il tuo Canvas.


finalmente ho risolto, mi ci sono voluti 3 minuti ora dopo circa 2 settimane di fare qualcos'altro
CSI

Il link @Synday Ironfoot sul suo aggiornamento non funziona. Questo link: dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html voglio questo impelementation. Puoi pubblicare qui il codice? grazie
Bogz,

2
ad oggi (settembre 2014) il link a MosaicTest.html è morto.
Chris,

la demo del mosaico è sparita. Uso di solito js alla vaniglia e non jQuery. a cosa si riferisce $ (questo)? il document.body.offsetTop? Voglio davvero vedere la demo del mosaico che il mio progetto foreverscape.com potrebbe davvero trarne beneficio.
FlavorScape

2
La pagina demo del mosaico è salvata su archive.org: web.archive.org/web/20130126152008/http://…
Chris

9

Mi sono imbattuto in questo problema usando c ++, che probabilmente non avrei dovuto avere con le matrici OpenGL per cominciare ... comunque, se stai usando un controllo la cui origine è l'angolo in alto a sinistra, e vuoi pan / zoom come google maps, ecco il layout (usando allegro come gestore dell'evento):

// initialize
double originx = 0; // or whatever its base offset is
double originy = 0; // or whatever its base offset is
double zoom = 1;

.
.
.

main(){

    // ...set up your window with whatever
    //  tool you want, load resources, etc

    .
    .
    .
    while (running){
        /* Pan */
        /* Left button scrolls. */
        if (mouse == 1) {
            // get the translation (in window coordinates)
            double scroll_x = event.mouse.dx; // (x2-x1) 
            double scroll_y = event.mouse.dy; // (y2-y1) 

            // Translate the origin of the element (in window coordinates)      
            originx += scroll_x;
            originy += scroll_y;
        }

        /* Zoom */ 
        /* Mouse wheel zooms */
        if (event.mouse.dz!=0){    
            // Get the position of the mouse with respect to 
            //  the origin of the map (or image or whatever).
            // Let us call these the map coordinates
            double mouse_x = event.mouse.x - originx;
            double mouse_y = event.mouse.y - originy;

            lastzoom = zoom;

            // your zoom function 
            zoom += event.mouse.dz * 0.3 * zoom;

            // Get the position of the mouse
            // in map coordinates after scaling
            double newx = mouse_x * (zoom/lastzoom);
            double newy = mouse_y * (zoom/lastzoom);

            // reverse the translation caused by scaling
            originx += mouse_x - newx;
            originy += mouse_y - newy;
        }
    }
}  

.
.
.

draw(originx,originy,zoom){
    // NOTE:The following is pseudocode
    //          the point is that this method applies so long as
    //          your object scales around its top-left corner
    //          when you multiply it by zoom without applying a translation.

    // draw your object by first scaling...
    object.width = object.width * zoom;
    object.height = object.height * zoom;

    //  then translating...
    object.X = originx;
    object.Y = originy; 
}

9

Mi piace la risposta di Tatarize , ma fornirò un'alternativa. Questo è un banale problema di algebra lineare e il metodo che presento funziona bene con pan, zoom, inclinazione, ecc. Cioè, funziona bene se la tua immagine è già trasformata.

Quando una matrice viene ridimensionata, la scala si trova nel punto (0, 0). Quindi, se hai un'immagine e la ridimensioni di un fattore 2, il punto in basso a destra raddoppierà in entrambe le direzioni xey (usando la convenzione che [0, 0] è la parte in alto a sinistra dell'immagine).

Se invece desideri ingrandire l'immagine attorno al centro, una soluzione è la seguente: (1) traduci l'immagine in modo che il suo centro sia su (0, 0); (2) ridimensiona l'immagine in base ai fattori xey; (3) traduci l'immagine indietro. vale a dire

myMatrix
  .translate(image.width / 2, image.height / 2)    // 3
  .scale(xFactor, yFactor)                         // 2
  .translate(-image.width / 2, -image.height / 2); // 1

Più astrattamente, la stessa strategia funziona per qualsiasi punto. Se, ad esempio, vuoi ridimensionare l'immagine in un punto P:

myMatrix
  .translate(P.x, P.y)
  .scale(xFactor, yFactor)
  .translate(-P.x, -P.y);

Infine, se l'immagine è già stata trasformata in qualche modo (ad esempio, se è ruotata, inclinata, tradotta o ridimensionata), è necessario conservare la trasformazione corrente. In particolare, la trasformazione sopra definita deve essere post-moltiplicata (o moltiplicata a destra) per la trasformazione corrente.

myMatrix
  .translate(P.x, P.y)
  .scale(xFactor, yFactor)
  .translate(-P.x, -P.y)
  .multiply(myMatrix);

Ecco qua. Ecco un plunk che lo mostra in azione. Scorri con la rotellina del mouse sui punti e vedrai che rimangono costantemente posizionati. (Testato solo su Chrome.) Http://plnkr.co/edit/3aqsWHPLlSXJ9JCcJzgH?p=preview


1
Devo dire che se hai una matrice di trasformazione affine a tua disposizione, usala con entusiasmo. Molte matrici di trasformazione avranno anche funzioni di zoom (sx, sy, x, y) che fanno esattamente questo. Vale quasi la pena cucinarne uno se non ne hai uno da usare.
Tatarize il

In effetti, confesso che nel codice in cui ho usato questa soluzione, da allora è stata sostituita con una classe matrix. E ho fatto esattamente questa cosa più volte e ho preparato classi di matrici non meno di due volte. ( github.com/EmbroidePy/pyembroidery/blob/master/pyembroidery/… ), ( github.com/EmbroidePy/EmbroidePy/blob/master/embroidepy/… ). Se vuoi qualcosa di più complesso di queste operazioni, una matrice è sostanzialmente la risposta corretta e una volta che hai una maniglia sull'algebra lineare ti rendi conto che questa risposta è in realtà la risposta migliore.
Tatarize,

6

Ecco la mia soluzione per un'immagine orientata al centro:

var MIN_SCALE = 1;
var MAX_SCALE = 5;
var scale = MIN_SCALE;

var offsetX = 0;
var offsetY = 0;

var $image     = $('#myImage');
var $container = $('#container');

var areaWidth  = $container.width();
var areaHeight = $container.height();

$container.on('wheel', function(event) {
    event.preventDefault();
    var clientX = event.originalEvent.pageX - $container.offset().left;
    var clientY = event.originalEvent.pageY - $container.offset().top;

    var nextScale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, scale - event.originalEvent.deltaY / 100));

    var percentXInCurrentBox = clientX / areaWidth;
    var percentYInCurrentBox = clientY / areaHeight;

    var currentBoxWidth  = areaWidth / scale;
    var currentBoxHeight = areaHeight / scale;

    var nextBoxWidth  = areaWidth / nextScale;
    var nextBoxHeight = areaHeight / nextScale;

    var deltaX = (nextBoxWidth - currentBoxWidth) * (percentXInCurrentBox - 0.5);
    var deltaY = (nextBoxHeight - currentBoxHeight) * (percentYInCurrentBox - 0.5);

    var nextOffsetX = offsetX - deltaX;
    var nextOffsetY = offsetY - deltaY;

    $image.css({
        transform : 'scale(' + nextScale + ')',
        left      : -1 * nextOffsetX * nextScale,
        right     : nextOffsetX * nextScale,
        top       : -1 * nextOffsetY * nextScale,
        bottom    : nextOffsetY * nextScale
    });

    offsetX = nextOffsetX;
    offsetY = nextOffsetY;
    scale   = nextScale;
});
body {
    background-color: orange;
}
#container {
    margin: 30px;
    width: 500px;
    height: 500px;
    background-color: white;
    position: relative;
    overflow: hidden;
}
img {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    max-width: 100%;
    max-height: 100%;
    margin: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="container">
    <img id="myImage" src="http://s18.postimg.org/eplac6dbd/mountain.jpg">
</div>


4

Ecco un modo alternativo per farlo che utilizza setTransform () invece di scale () e translate (). Tutto è memorizzato nello stesso oggetto. Si presume che la tela sia a 0,0 sulla pagina, altrimenti dovrai sottrarre la sua posizione dai coord della pagina.

this.zoomIn = function (pageX, pageY) {
    var zoomFactor = 1.1;
    this.scale = this.scale * zoomFactor;
    this.lastTranslation = {
        x: pageX - (pageX - this.lastTranslation.x) * zoomFactor,
        y: pageY - (pageY - this.lastTranslation.y) * zoomFactor
    };
    this.canvasContext.setTransform(this.scale, 0, 0, this.scale,
                                    this.lastTranslation.x,
                                    this.lastTranslation.y);
};
this.zoomOut = function (pageX, pageY) {
    var zoomFactor = 1.1;
    this.scale = this.scale / zoomFactor;
    this.lastTranslation = {
        x: pageX - (pageX - this.lastTranslation.x) / zoomFactor,
        y: pageY - (pageY - this.lastTranslation.y) / zoomFactor
    };
    this.canvasContext.setTransform(this.scale, 0, 0, this.scale,
                                    this.lastTranslation.x,
                                    this.lastTranslation.y);
};

Codice di accompagnamento per gestire il panning:

this.startPan = function (pageX, pageY) {
    this.startTranslation = {
        x: pageX - this.lastTranslation.x,
        y: pageY - this.lastTranslation.y
    };
};
this.continuePan = function (pageX, pageY) {
    var newTranslation = {x: pageX - this.startTranslation.x,
                          y: pageY - this.startTranslation.y};
    this.canvasContext.setTransform(this.scale, 0, 0, this.scale,
                                    newTranslation.x, newTranslation.y);
};
this.endPan = function (pageX, pageY) {
    this.lastTranslation = {
        x: pageX - this.startTranslation.x,
        y: pageY - this.startTranslation.y
    };
};

Per ricavare tu stesso la risposta, considera che le stesse coordinate della pagina devono corrispondere alle stesse coordinate del canvas prima e dopo lo zoom. Quindi puoi fare un po 'di algebra a partire da questa equazione:

(pageCoords - traduzione) / scale = canvasCoords


3

Voglio mettere qui alcune informazioni per coloro che fanno separatamente il disegno dell'immagine e lo spostano - ingrandendolo.

Ciò può essere utile quando si desidera memorizzare gli zoom e la posizione della finestra.

Ecco il cassetto:

function redraw_ctx(){
   self.ctx.clearRect(0,0,canvas_width, canvas_height)
   self.ctx.save()
   self.ctx.scale(self.data.zoom, self.data.zoom) // 
   self.ctx.translate(self.data.position.left, self.data.position.top) // position second
   // Here We draw useful scene My task - image:
   self.ctx.drawImage(self.img ,0,0) // position 0,0 - we already prepared
   self.ctx.restore(); // Restore!!!
}

Nota che la scala DEVE essere la prima .

Ed ecco lo zoomer:

function zoom(zf, px, py){
    // zf - is a zoom factor, which in my case was one of (0.1, -0.1)
    // px, py coordinates - is point within canvas 
    // eg. px = evt.clientX - canvas.offset().left
    // py = evt.clientY - canvas.offset().top
    var z = self.data.zoom;
    var x = self.data.position.left;
    var y = self.data.position.top;

    var nz = z + zf; // getting new zoom
    var K = (z*z + z*zf) // putting some magic

    var nx = x - ( (px*zf) / K ); 
    var ny = y - ( (py*zf) / K);

    self.data.position.left = nx; // renew positions
    self.data.position.top = ny;   
    self.data.zoom = nz; // ... and zoom
    self.redraw_ctx(); // redraw context
    }

e, naturalmente, avremmo bisogno di un trascinatore:

this.my_cont.mousemove(function(evt){
    if (is_drag){
        var cur_pos = {x: evt.clientX - off.left,
                       y: evt.clientY - off.top}
        var diff = {x: cur_pos.x - old_pos.x,
                    y: cur_pos.y - old_pos.y}

        self.data.position.left += (diff.x / self.data.zoom);  // we want to move the point of cursor strictly
        self.data.position.top += (diff.y / self.data.zoom);

        old_pos = cur_pos;
        self.redraw_ctx();

    }


})

3
if(wheel > 0) {
    this.scale *= 1.1; 
    this.offsetX -= (mouseX - this.offsetX) * (1.1 - 1);
    this.offsetY -= (mouseY - this.offsetY) * (1.1 - 1);
}
else {
    this.scale *= 1/1.1; 
    this.offsetX -= (mouseX - this.offsetX) * (1/1.1 - 1);
    this.offsetY -= (mouseY - this.offsetY) * (1/1.1 - 1);
}

2

Ecco un'implementazione del codice della risposta di @ tatarize, usando PIXI.js. Ho una finestra che guarda parte di un'immagine molto grande (ad es. Stile Google Maps).

$canvasContainer.on('wheel', function (ev) {

    var scaleDelta = 0.02;
    var currentScale = imageContainer.scale.x;
    var nextScale = currentScale + scaleDelta;

    var offsetX = -(mousePosOnImage.x * scaleDelta);
    var offsetY = -(mousePosOnImage.y * scaleDelta);

    imageContainer.position.x += offsetX;
    imageContainer.position.y += offsetY;

    imageContainer.scale.set(nextScale);

    renderer.render(stage);
});
  • $canvasContainer è il mio contenitore HTML.
  • imageContainer è il mio contenitore PIXI che contiene l'immagine.
  • mousePosOnImage è la posizione del mouse rispetto all'intera immagine (non solo alla porta di visualizzazione).

Ecco come ho ottenuto la posizione del mouse:

  imageContainer.on('mousemove', _.bind(function(ev) {
    mousePosOnImage = ev.data.getLocalPosition(imageContainer);
    mousePosOnViewport.x = ev.data.originalEvent.offsetX;
    mousePosOnViewport.y = ev.data.originalEvent.offsetY;
  },self));

0

È necessario ottenere il punto nello spazio mondiale (in opposizione allo spazio dello schermo) prima e dopo lo zoom, quindi tradurre dal delta.

mouse_world_position = to_world_position(mouse_screen_position);
zoom();
mouse_world_position_new = to_world_position(mouse_screen_position);
translation += mouse_world_position_new - mouse_world_position;

La posizione del mouse è nello spazio dello schermo, quindi è necessario trasformarlo nello spazio del mondo. La trasformazione semplice dovrebbe essere simile a questa:

world_position = screen_position / scale - translation

0

puoi usare la funzione scrollto (x, y) per gestire la posizione della barra di scorrimento fino al punto in cui devi essere mostrato dopo lo zoom. per trovare la posizione del mouse usa event.clientX ed event.clientY. questo ti aiuterà


0

Una cosa importante ... se hai qualcosa del tipo:

body {
  zoom: 0.9;
}

Hai bisogno di rendere l'equivalente in tela:

canvas {
  zoom: 1.1;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.