在过去的两天里,我已经有效地想出了如何不旋转拉斐尔元素。
基本上我试图在元素上实现多个枢轴点以通过鼠标旋转它。
当用户进入旋转模式时,将创建5个枢轴。一个用于边界框的每个角落,另一个在框的中心。
当鼠标向下移动时,使用Raphael elements.rotate(degrees, x, y)并根据鼠标位置和atan2计算角度,可以很容易地围绕枢轴旋转。
在我旋转了元素,bbox和其他支点之后出现了问题。有x,y位置只在那里只有视口不同。
在支持SVG的浏览器中,我可以根据matrixTransformation and getCTM创建新的支点。然而,在创建第一组新枢轴之后,由于圆角误差,枢轴之后的每次旋转都远离变换的bbox。
以上在IE中甚至不是一个选项,因为它是基于VML的,不能解释转换。
是唯一有效的实施方式 元素旋转是通过使用旋转 绝对或围绕中心旋转 边界框?
是否可以创建multi 对象的枢轴点和更新 他们在mouseup之后留在了 转角的角落和中心 BBOX?
更新: 我试图使用jQuery偏移量来旋转后找到枢轴,并使用该偏移位置作为枢轴点。
演示网站...... http://weather.speedfetishperformance.com/dev/raphael/rotation.html
答案 0 :(得分:1)
我能想到的最好的跨浏览器方式就是自己实现轮换,而不是让SVG去做。旋转x,y坐标非常简单,每当我需要进行2D旋转时,我一直在使用这个(tcl)代码:Canvas Rotation。
这样做的好处是,您可以手动控制旋转。这解决了您在旋转后尝试猜测最终坐标时遇到的问题。此外,这应该是跨浏览器兼容的。
缺点是你必须使用路径。因此没有rects(虽然它应该很容易将它们转换为路径)或省略号(转换为路径但可行的更难)。此外,由于你是手动完成的,它应该比让SVG为你做的慢。
以下是javascript中该Tcl代码的部分实现:
首先我们需要一个regexp来标记SVG路径:
var svg_path_regexp = (function(){
var number = '-?[0-9.]+';
var comma = '\s*[, \t]\s*';
var space = '\s+';
var xy = number + comma + number;
var standard_paths = '[mlcsqt]';
var horiz_vert = '[hv]\s*' + number;
var arc = 'a\s*' + xy + space + number + space + xy + space + xy;
var OR = '\s*|';
return new RegExp(
standard_paths +OR+
xy +OR+
horiz_vert +OR+
arc,
'ig'
);
})();
现在我们可以实现旋转功能:
function rotate_SVG_path (path, Ox, Oy, angle) {
angle = angle * Math.atan(1) * 4 / 180.0; // degrees to radians
var tokens = path.match(svg_path_regexp);
for (var i=0; i<tokens.length; i++) {
var token = tokens[i].replace(/^\s+|\s+$/g,''); // trim string
if (token.match(/\d/)) { // assume it's a coordinate
var xy = token.split(/[, \t]+/);
var x = parseFloat(xy[0]);
var y = parseFloat(xy[1]);
x = x - Ox; // Shift to origin
y = y - Oy;
var xx = x * Math.cos(angle) - y * Math.sin(angle); // Rotate
var yy = x * Math.sin(angle) + y * Math.cos(angle);
x = xx + Ox; // Shift back
y = yy + Oy;
token = x + ',' + y;
}
else if (token.match(/^[hv]/)) {
// handle horizontal/vertical line here
}
else if (token.match(/^a/)) {
// handle arcs here
}
tokens[i] = token;
}
return tokens.join('');
}
上面的旋转功能实现了除水平/垂直线(你需要跟踪前一个xy值)和弧之外的所有内容。也不应该太难实现。