将SVG元素翻译为等轴测视图

7

我正在编写一些JavaScript代码,以在等距3Dish视图中呈现标准的2D SVG/Canvas元素(使用Raphael-JS绘制)。

假设我们有两个相邻的矩形。然后,我将它们重新绘制成正确的角度(基本上是30度扭曲),以获得等距视图。

alt text

在上面的图像中,我显示了两个相应元素的原点。

我的问题是我不知道如何正确地翻译所有单独的元素,使它们“平铺”而不仅仅重叠。

尽管实际使用图块会使事情变得更容易,因为我可以将任何给定图块的放置基于其之前的图块,但在这种情况下图块将无法使用。一切都是动态的,比简单的x/y平面更复杂。

如果对我想要放置这些对象的方式存在任何困惑,请参阅此处的等距图块的图像


你的标题似乎表明你正在使用HTML画布元素。由于Raphael使用SVG(即使他们也在谈论画布),您可能需要澄清一下以获得一些答案。不过,这是一个有趣的问题! - polarblau
感谢你的提示,polarblau。我会尽力澄清我的问题。 - Chris Cummings
请注意,您在问题中提供的图形不是正确的等轴投影,假设两个正方形与地面高度相同。如您提供的网址所示,在投影后,相邻瓷砖的边缘应保持对齐。如果您试图展示您的问题,则应该更清楚地表明这是您正在展示的当前/错误结果。 - Phrogz
2个回答

6

不应该将转换应用于单个元素,而应该将其作为集合应用于源元素。在Raphael中,您可以使用以下内容:

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

现在我们来进行转换,不用太多数学,应该按照以下方式进行操作:
// s.clone(); // if you want to keep originals
s.rotate(45, 0, 0).scale(1, .7).translate(100, 0);

然而,在RaphaelJS中,旋转的元素缩放似乎存在问题。
普通的SVG示例:
<!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>

谢谢您的回复,Pumbaa80。不幸的是,这个解决方案对我来说似乎不太合适。我想要的是最终能够输入一些坐标,比如一个基本的平面图。然后在等距投影中呈现这些坐标,并从元素的“底部”拉出z轴(高度)。稍后,通过JavaScript,我希望能够操作单个元素:移动、删除、添加和修改它们。我无法真正地绘制z轴(从足迹中制作立方体),然后旋转整个集合。我想可能可以先旋转一切,然后再拉出 -继续-> - Chris Cummings
通过重新测量每个元素的坐标来解决高度问题。这样做可能有效,但在问题上看起来相当丑陋。不过,也许这样更简单。我会试一下。 - Chris Cummings
为了其他人的利益,这是我在Raphael-JS Google Groups上发布的有关旋转元素缩放问题的帖子链接:http://groups.google.com/group/raphaeljs/browse_thread/thread/217a5edb9db22419 - Chris Cummings
@j33r Pumbaa80 是正确的,你不应该将变换应用于每个元素,而是应该应用于整个视图。 - Phrogz

4
使用Raphel.js 2.0,您可以使用.transform()方法并提供一个变换字符串来旋转45度并垂直缩放70%(或任何您想要的角度)。同样重要的是要注意您旋转和缩放的位置 - 在这种情况下,我正在使用0,0。您还会注意到我将100向右平移以补偿旋转。
变换字符串对于此用例也非常好,因为您可以简单地将投影变换前置到场景中其他对象的变换中,并且它们都将出现在正确的位置。
例如(请参见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');​

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接