【发布时间】:2012-10-06 19:55:38
【问题描述】:
如何在浏览器中扭曲 SVG 中的路径,以便使用可能的 javascript 或 css 将它们扭曲到某些角度?透视扭曲可以在 Photoshop、Illustrator 等中轻松制作,但是浏览器呢?
这是源路径:
这是改造后的路径:
【问题讨论】:
标签: javascript css svg transformation perspective
如何在浏览器中扭曲 SVG 中的路径,以便使用可能的 javascript 或 css 将它们扭曲到某些角度?透视扭曲可以在 Photoshop、Illustrator 等中轻松制作,但是浏览器呢?
这是源路径:
这是改造后的路径:
【问题讨论】:
标签: javascript css svg transformation perspective
这是我的拖动扭曲提案 (share you knowledge, Q&A-style)。
现场示例在http://jsfiddle.net/xjHUk/278/,主要代码如下:
(仅输出窗口:http://jsfiddle.net/xjHUk/279/embedded/result/)
结果被正确地扭曲为透视图(两个消失点一)。两点透视计算的原理是here。如果满足以下要求,该脚本可以处理 SVG 路径数据:
弧可以被规范化,但我还没有找到任何跨浏览器的方式。 V 和 H 到 L 是简单的任务,你必须得到最后使用的 x 或 y 坐标,并在 L 之后添加缺少的一个。
相同的脚本也可以处理路径中的曲线(曲线来自时代)。以下是完全相同的代码,但路径属性(“d”)不同:
http://jsfiddle.net/xjHUk/277/function dummy(a) {return a;}
(此代码没有检查无效位置,如上)。
以上示例的路径来自于 Arial 和 Times 的 SVG 版本。请注意字体使用Cartesian coordinate system,向上时y坐标增加。否则 SVG 使用极坐标系,用于位图图像和 css。这意味着当在上述代码中使用来自 SVG 字体的路径时,路径必须垂直翻转并缩放到所需的字体大小。 TTF 字体(及其对应的 SVG 字体)通常 em 大小为 2048,因此字形的边界框没有缩放 2048 px,这在 SVG 字形路径转换为 SVG 路径时通常太大了。
但如果您想扭曲其他 SVG 路径,则无需进行翻转和缩放。
这是相当长的代码(很大程度上是因为拖动功能),但我认为同样的效果也可以通过一些 css-3D-transform-way 实现,但在这样的实现中还没有运气......
为了比较一个非透视扭曲的例子(SVG的主要竞争对手SWF):
http://www.rubenswieringa.com/code/as3/flex/DistortImage/
还有一个 VALID 透视计算示例:
http://zehfernando.com/f/TriangleTest.swf
【讨论】:
所选答案已过时。
尽管 SVG 不支持改变元素的视角,但可以通过使用 CSS3 变换来实现。
CSS3 是一种非常强大的动画对象方法。可以使用 Javascript 实时创建和应用 CSS3 变换。
对 CSS3 Transform 有很好的支持,所有最新版本的主要浏览器都支持它。 (IE 8+、Chrome 31+、Safari 7.1+、Opera 26+、Firefox 34+、Android 浏览器 4.1+)。更多信息:http://caniuse.com/#feat=transforms2d
对于某些浏览器版本,您需要使用特定于浏览器的前缀来创建转换。但是,有一个非常简洁的网站解释了处理该问题的好方法: http://bl.ocks.org/mbostock/10571478
一些 CSS3 转换属性是:rotate(angle)、scale(dimension)。我知道,它们看起来与 SVG 变换 rotate(angle)、scale(x y) 非常相似,但最好不要把它们等同起来,因为两者之间存在根本差异,CSS3 比 SVG 变换强大得多。此外,CSS3 Transforms 有一个属性perspective,你肯定需要看看。
没有比 W3 更好的地方可以找到有关 CSS3 转换的更多信息:http://www.w3.org/TR/css3-transforms/
这是一个代码sn-p:
div {
height: 150px;
width: 150px;
}
.container {
perspective: 500px;
border: 1px solid black;
background: gray;
}
.transformed {
transform: rotateY(50deg);
background: blue;
}
<!doctype html>
<html>
<body>
<div class="container">
<div class="transformed"> Hola! He sido transformado!</div>
</div>
</body>
</html>
变身快乐!
【讨论】: