2011-01-23 11 views
5

Estoy trabajando en algunos códigos JavaScript para representar elementos 2D SVG/Canvas estándar (dibujados con Raphael-JS) en una vista isométrica 3Dish.Traducir elementos SVG para una vista isométrica

Supongamos que tenemos dos rectángulos dibujados uno al lado del otro. Luego los redibujo en los ángulos correctos (básicamente un giro de 30 grados) para una vista isométrica.

alt text

(En la imagen anterior he demostrado el origen de dos elementos correspondientes.)

Mi problema es que no sé cómo traducir correctamente todos los elementos individuales, de manera que "mosaico" correctamente en lugar de simplemente superponerse.

Si bien el uso de los mosaicos facilitaría las cosas, ya que podría basar la colocación de cada uno de los mosaicos en el anterior, los mosaicos no funcionarán en este caso. Todo es dinámico y será más complejo que simples planos x/y.

Here is an image of some isometric tiles si hay confusiones en cuanto a cómo quiero que se coloquen estos objetos.

+0

Su título parece indicar que está utilizando el elemento canvas HTML. Dado que Raphael usa SVG (aunque también están hablando de lienzos), puede aclarar esto para obtener algunas respuestas. ¡Interesante pregunta, sin embargo! – polarblau

+0

Gracias por la pista, polarblau. Trataré de aclarar mi pregunta. –

+0

Tenga en cuenta que el gráfico que ha proporcionado en su pregunta no es una proyección isométrica correcta, suponiendo que los dos cuadrados están a la misma altura desde el suelo. Como se muestra en la url que proporcionó, los bordes de los mosaicos adyacentes deben permanecer alineados después de la proyección. Si estaba tratando de mostrar su problema, quizás debería dejar más claro que este es el resultado actual/incorrecto que está mostrando. – Phrogz

Respuesta

2

No debe aplicar la transformación a los elementos individuales, sino a los elementos de origen como una colección. En Rafael, usted podría utilizar algo como

var s = paper.set(); 
s.push(square1, square2); 

y ahora hacer las transformaciones sin demasiada matemáticas, que se supone que funciona de esta manera:

// s.clone(); // if you want to keep originals 
s.rotate(45, 0, 0).scale(1, .7).translate(100, 0); 

(Sin embargo, la escala de los objetos rotados parece haber roto en RaphaelJS)

Llanura SVG ejemplo:.

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
    viewBox="-200,-500 1000,1000"> 
    <title>Isometric</title> 
     <g id="source"> <!-- group --> 
      <circle cx="-50" cy="-50" r="50"/> 
      <rect width="100" height="100"/> 
      <rect width="100" height="100" x="101"/> 
      <rect width="100" height="100" x="50" y="-200"/> 
     </g> 
     <!-- make copy of group and apply transformations --> 
     <use xlink:href="#source" transform="translate(500) scale(1, .7) rotate(-45)"/> 
</svg> 
+0

Gracias por la respuesta, Pumbaa80.Lamentablemente, esta solución no me parece adecuada. Lo que me gustaría es eventualmente poder ingresar algunas coordenadas de, digamos, un plano básico. Luego represente esas coordenadas en una proyección isométrica y extruya el eje z (altura) desde la "base" del elemento. Más tarde, a través de JavaScript, quiero poder manipular los elementos individuales: moverlos, eliminarlos, agregarlos y modificarlos. Realmente no puedo dibujar z-axises (hacer cubos desde las huellas) y luego rotar el conjunto. Supongo que * podría * ser posible rotar todo y luego extruir -continuación-> –

+0

<-continuación de alturas volviendo a medir las coordenadas de cada elemento. Hacerlo podría funcionar, pero parece bastante feo, problemático. Por otra parte, tal vez es más simple de esa manera. Voy a tratar de salir. –

+0

Para el beneficio de cualquier otra persona, aquí está mi publicación de Grupos de Google de Raphael-JS sobre la escalación de elementos girados: http://groups.google.com/group/raphaeljs/browse_thread/thread/217a5edb9db22419 –

3

Usando Raphel.js 2.0 puede hacerlo utilizando el método .transform() y proporcionando una cadena de transformación que gira 45 grados y se escala verticalmente al 70% (o el tono que desee). Es importante prestar atención a la posición en la que está girando y escalando también, en este caso estoy usando 0,0. También notarás que estoy traduciendo 100 hacia la derecha para compensar la rotación.

Las cadenas de transformación también son excelentes para este caso de uso porque puede anteponer la transformación de proyección a la transformación de otros objetos en la escena y todos terminarán en el lugar correcto.

Por ejemplo (ver http://jsfiddle.net/k22yG/):

var paper = Raphael(10, 10, 320, 240), 
    set = paper.set(); 

// Build a set to make it easier to transform them all at once 
set.push(
    // Grid of rectangles 
    paper.rect(0, 0, 50, 50), 
    paper.rect(60, 0, 50, 50), 
    paper.rect(0, 60, 50, 50), 
    paper.rect(60, 60, 50, 50) 
); 

// Rotate, then scale, then move (describe in "reverse" order) 
set.transform('t100,0s1,0.7,0,0r45,0,0');​ 
Cuestiones relacionadas