2012-09-28 17 views
9

¿Hay alguna manera de acercarse y moverse en un lienzo usando KineticJS? Encontré esta biblioteca kineticjs-viewport, pero me pregunto si hay alguna otra forma de lograr esto porque esta biblioteca parece estar utilizando tantas bibliotecas adicionales y no estoy seguro de cuáles son absolutamente necesarias para hacer el trabajo.Zoom y panorámica en KineticJS

Alternativamente, estoy abierto a la idea de dibujar un rectángulo alrededor de la región de interés y acercarme a esa área en particular. ¿Alguna idea sobre cómo lograr esto? ¡Un ejemplo de JSFiddle sería increíble!

Respuesta

25

Simplemente puede agregar .setDraggable("draggable") a una capa y podrá arrastrarlo mientras haya un objeto debajo del cursor. Puede agregar un rect grande y transparente para que todo sea arrastrable. El zoom se puede lograr configurando la escala de la capa. En este ejemplo, lo estoy controlando a través de la rueda del mouse, pero es simplemente una función en la que se pasa la cantidad que desea ampliar (positivo para acercar, negativo para alejarse). Aquí está el código:

var stage = new Kinetic.Stage({ 
    container: "canvas", 
    width: 500, 
    height: 500 
}); 

var draggableLayer = new Kinetic.Layer(); 
draggableLayer.setDraggable("draggable"); 

//a large transparent background to make everything draggable 
var background = new Kinetic.Rect({ 
    x: -1000, 
    y: -1000, 
    width: 2000, 
    height: 2000, 
    fill: "#000000", 
    opacity: 0 
}); 

draggableLayer.add(background); 


//don't mind this, just to create fake elements 
var addCircle = function(x, y, r){ 
    draggableLayer.add(new Kinetic.Circle({ 
     x: x*700, 
     y: y*700, 
     radius: r*20, 
     fill: "rgb("+ parseInt(255*r) +",0,0)" 
    }) 
); 
} 

var circles = 300 
while (circles) { 
    addCircle(Math.random(),Math.random(), Math.random()) 
    circles--; 
} 

var zoom = function(e) { 
    var zoomAmount = e.wheelDeltaY*0.001; 
    draggableLayer.setScale(draggableLayer.getScale().x+zoomAmount) 
    draggableLayer.draw(); 
} 

document.addEventListener("mousewheel", zoom, false) 

stage.add(draggableLayer) 

http://jsfiddle.net/zAUYd/

+0

Esto funciona muy bien, excepto en IE9. ¿Tendría alguna idea de por qué? La consola de depuración tampoco arroja ningún error ... – Legend

+0

Parece que funciona si uso 'e.wheelDelta' en lugar de' e.wheelDeltaY'. ¿Alguna idea de por qué? – Legend

+1

Creo que IE usa deltaY. El zoom de la rueda del mouse fue solo un ejemplo; si tiene la intención de conservarlo, debe usar un ajuste que compensa la diferencia en las implementaciones del navegador, como https://github.com/cobbweb/jquery-mousewheel – Duopixel

2

Como estaba trabajando con Kinetic hoy encontré un SO question que podría interesarle.

Sé que sería mejor como comentario, pero no tengo suficientes representantes para eso, de todos modos, espero que eso ayude.

4

Aquí es una implementación muy rápida y sencilla de zoom y panorámica de una capa. Si tuviera más capas que necesitarían desplazarse y hacer zoom al mismo tiempo, le sugiero que las agrupe y luego aplique las (en "clic") s a ese grupo para obtener el mismo efecto.

http://jsfiddle.net/renyn/56/

Si no es obvio, los cuadrados de color azul claro en la parte superior izquierda se hace clic para acercar y alejar, y se hace clic en las casillas de color rosa en la parte inferior izquierda a la sartén izquierda y derecha.

Editar: Como nota, esto podría por supuesto cambiarse para admitir "mousedown" u otros eventos, y no veo por qué las transformaciones no podrían implementarse como Kinetic. Anotaciones para que sean más suaves.

+0

impresionante! Esto es exactamente lo que quiero. Intenté usar los eventos del mouse sobre un escenario pero no tuve mucha suerte, así que estoy tentado de preguntarte: ¿podrías guiarme más para apoyar los eventos de mousedown y apoyar una animación más suave? – Legend

+0

No aconsejaría aplicarlos a todo el escenario, esto capturaría todos los eventos del mouse sin prejuicios. Intenta asignarlos a formas individuales como yo. No estoy seguro exactamente de qué orientación necesita, las API y los tutoriales de Kinetic son bastante útiles. –

+0

No me sorprende, 5.0.0 y 5.0.1 tienen muchos cambios de ruptura de 4.0.2. –

1

Desafortunadamente, el establecimiento del estado o capa impide que se pueden arrastrar objetos no pueden arrastrarse. La solución de acercamiento de Duopixel es buena, pero preferiría configurarla para el nivel de escenario, no para el nivel de capa.

ella es mi solución

var stage = new Kinetic.Stage({ 
    container : 'container', 
    width: $("#container").width(), 
    height: $("#container").height(), 
}); 
var layer = new Kinetic.Layer(); 

//layer.setDraggable("draggable"); 
var center = { x:stage.getWidth()/2, y: stage.getHeight()/2}; 

var circle = new Kinetic.Circle({ 
    x: center.x-100, 
    y: center.y, 
    radius: 50, 
    fill: 'green', 
    draggable: true 
}); 
layer.add(circle); 
layer.add(circle.clone({x: center.x+100})); 

// zoom by scrollong 
document.getElementById("container").addEventListener("mousewheel", function(e) { 
    var zoomAmount = e.wheelDeltaY*0.0001; 
    stage.setScale(stage.getScale().x+zoomAmount) 
    stage.draw(); 
    e.preventDefault(); 
}, false) 

// pan by mouse dragging on stage 
stage.on("dragstart dragmove", function(e) {window.draggingNode = true;}); 
stage.on("dragend", function(e) { window.draggingNode = false;}); 
$("#container").on("mousedown", function(e) { 
    if (window.draggingNode) return false; 
    if (e.which==1) { 
     window.draggingStart = {x: e.pageX, y: e.pageY, stageX: stage.getX(), stageY: stage.getY()}; 
     window.draggingStage = true; 
    } 
}); 
$("#container").on("mousemove", function(e) { 
    if (window.draggingNode || !window.draggingStage) return false; 
    stage.setX(window.draggingStart.stageX+(e.pageX-window.draggingStart.x)); 
    stage.setY(window.draggingStart.stageY+(e.pageY-window.draggingStart.y)); 
    stage.draw(); 
}); 
$("#container").on("mouseup", function(e) { window.draggingStage = false }); 

stage.add(layer); 

http://jsfiddle.net/bighostkim/jsqJ2/

3

realidad escribió kineticjs-ventana. Me alegra saber que estabas interesado en eso.

En realidad, está pensado para algo más que simplemente arrastrar. También permite el zoom y el recorte centrado en el rendimiento. Las cosas que están fuera de la región del clip no se representan en absoluto, por lo que puede obtener un excelente rendimiento de representación incluso si tiene una enorme capa con una tonelada de objetos.

Ese es el caso de uso que tuve.Por ejemplo, un gran mapa RTS que ve a través de una región de ventana gráfica más pequeña: piense en Starcraft.

Espero que esto ayude.

+1

¿Puede agregar un ejemplo sobre cómo usar la ventana gráfica para esto? – PiTheNumber

+1

Hay una página de demostración en el repositorio: https://kineticjs-viewport.googlecode.com/git/demo.html –

2

Estas respuestas parecen no funcionar con el KineticJS 5.1.0. Estos no funcionan principalmente para el cambio de la firma de la función de escala:

stage.setScale(newscale); --> stage.setScale({x:newscale,y:newscale}); 

Sin embargo, la siguiente solución parece funcionar con los KineticJS 5.1.0:

jsFiddle: http://jsfiddle.net/rpaul/ckwu7u86/3/

Cuestiones relacionadas