Tim*_*nen 29 javascript css svg transformation perspective
如何在浏览器中扭曲SVG中的路径,以便使用javascript或css将它们扭曲到某个角度?透视扭曲可以在Photoshop,Illustrator等中轻松实现,但是浏览器呢?
这是源路径:

这是转型后的道路:

Tim*_*nen 30
这是我的拖曳扭曲建议(分享你的知识,Q&A风格).
实例是http://jsfiddle.net/xjHUk/278/,主要代码如下:(
仅输出窗口:http://jsfiddle.net/xjHUk/279/embedded/result/)
function transferPoint (xI, yI, source, destination)
{
var ADDING = 0.001; // to avoid dividing by zero
var xA = source[0].x;
var yA = source[0].y;
var xC = source[2].x;
var yC = source[2].y;
var xAu = destination[0].x;
var yAu = destination[0].y;
var xBu = destination[1].x;
var yBu = destination[1].y;
var xCu = destination[2].x;
var yCu = destination[2].y;
var xDu = destination[3].x;
var yDu = destination[3].y;
// Calcultations
// if points are the same, have to add a ADDING to avoid dividing by zero
if (xBu==xCu) xCu+=ADDING;
if (xAu==xDu) xDu+=ADDING;
if (xAu==xBu) xBu+=ADDING;
if (xDu==xCu) xCu+=ADDING;
var kBC = (yBu-yCu)/(xBu-xCu);
var kAD = (yAu-yDu)/(xAu-xDu);
var kAB = (yAu-yBu)/(xAu-xBu);
var kDC = (yDu-yCu)/(xDu-xCu);
if (kBC==kAD) kAD+=ADDING;
var xE = (kBC*xBu - kAD*xAu + yAu - yBu) / (kBC-kAD);
var yE = kBC*(xE - xBu) + yBu;
if (kAB==kDC) kDC+=ADDING;
var xF = (kAB*xBu - kDC*xCu + yCu - yBu) / (kAB-kDC);
var yF = kAB*(xF - xBu) + yBu;
if (xE==xF) xF+=ADDING;
var kEF = (yE-yF) / (xE-xF);
if (kEF==kAB) kAB+=ADDING;
var xG = (kEF*xDu - kAB*xAu + yAu - yDu) / (kEF-kAB);
var yG = kEF*(xG - xDu) + yDu;
if (kEF==kBC) kBC+=ADDING;
var xH = (kEF*xDu - kBC*xBu + yBu - yDu) / (kEF-kBC);
var yH = kEF*(xH - xDu) + yDu;
var rG = (yC-yI)/(yC-yA);
var rH = (xI-xA)/(xC-xA);
var xJ = (xG-xDu)*rG + xDu;
var yJ = (yG-yDu)*rG + yDu;
var xK = (xH-xDu)*rH + xDu;
var yK = (yH-yDu)*rH + yDu;
if (xF==xJ) xJ+=ADDING;
if (xE==xK) xK+=ADDING;
var kJF = (yF-yJ) / (xF-xJ); //23
var kKE = (yE-yK) / (xE-xK); //12
var xKE;
if (kJF==kKE) kKE+=ADDING;
var xIu = (kJF*xF - kKE*xE + yE - yF) / (kJF-kKE);
var yIu = kJF * (xIu - xJ) + yJ;
var b={x:xIu,y:yIu};
b.x=Math.round(b.x);
b.y=Math.round(b.y);
return b;
}
结果正确地扭曲到透视(两个消失点1).两点角度计算的原则是在这里.如果SVG路径数据满足以下要求,则该脚本可以处理:
弧可以标准化,但我还没有找到任何crossbrowser方式.V和H到L是很容易的任务,你必须得到最后使用的x或y坐标并在L之后添加缺失的坐标.
相同的脚本也可以处理路径中的曲线(曲线来自Times).以下是完全相同的代码,但路径属性("d")是不同的:
http://jsfiddle.net/xjHUk/277/ function dummy(a) {return a;}
(此代码没有检查无效位置,如上所述).
以上示例的路径来自Arial和Times的SVG版本.请注意,字体使用笛卡尔坐标系,其中y坐标在向上时会增加.否则SVG使用极坐标系,用于位图图像和css.这意味着在上面的代码中使用SVG字体的路径时,必须垂直翻转路径并缩放到所需的字体大小.TTF字体(及其SVG对应物)通常具有2048的大小,因此字形的边界框没有缩放2048像素,当SVG字形路径转换为SVG路径时,这通常太多.
但是如果你想扭曲其他SVG路径,那么翻转和缩放就不必要了.
这是相当长的代码(很多是因为拖动功能),但我认为同样的效果也可以实现一些css-3D-transform-way,但是在这样的实现中却没有运气......
为了比较一个非透视扭曲的例子(SVG的主要竞争对手SWF):http:
//www.rubenswieringa.com/code/as3/flex/DistortImage/
有关VALID透视计算的其他比较示例:http:
//zehfernando.com/f/TriangleTest.swf
oab*_*rca 12
所选答案已过时.
即使SVG不支持更改元素的视角,也可以通过使用CSS3 Transforms来实现.
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 Transform属性是:rotate(angle), scale(dimension). 我知道,他们看起来SOOOO类似SVG变换rotate(angle),scale(x y)但最好不要把他们作为平等的,因为有两个本质上的区别,与CSS3比SVG变换更为强大.此外,CSS3 Transforms有一个perspective你肯定需要看的属性.
没有比W3更好的地方找到有关CSS3变换的更多信息:http://www.w3.org/TR/css3-transforms/
这是一段代码:

div {
height: 150px;
width: 150px;
}
.container {
perspective: 500px;
border: 1px solid black;
background: gray;
}
.transformed {
transform: rotateY(50deg);
background: blue;
}Run Code Online (Sandbox Code Playgroud)
<!doctype html>
<html>
<body>
<div class="container">
<div class="transformed"> Hola! He sido transformado!</div>
</div>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
快乐转型!