gpt4 book ai didi

javascript - Raphael SVG VML 实现旋转的多枢轴点

转载 作者:行者123 更新时间:2023-11-30 06:05:58 25 4
gpt4 key购买 nike

在过去的两天里,我有效地弄清楚了如何不旋转 Raphael Elements。

基本上我正在尝试在元素上实现多个枢轴点以通过鼠标旋转它。

当用户进入旋转模式时,将创建 5 个枢轴。一个用于边界框的每个 Angular ,一个在框的中心。

当鼠标按下并移动时,使用 Raphael 围绕枢轴旋转非常简单 elements.rotate(degrees, x, y)并根据鼠标位置和 atan2 到轴心点计算度数。

问题出现在我旋转了元素、bbox 和其他枢轴之后。相同的 x,y 位置只有视口(viewport)不同。

在支持 SVG 的浏览器中,我可以基于 matrixTransformation and getCTM 创建新的轴心点.然而,在创建第一组新枢轴之后,由于舍入误差,枢轴之后的每次旋转都会远离转换后的 bbox。

rotate errors

以上甚至不是 IE 中的选项,因为它是基于 VML 的,无法解释转换。

Is the only effective way to implement element rotation is by using rotate absolute or rotating around the center of the bounding box?

Is it possible at all the create multi pivot points for an object and update them after mouseup to remain in the corners and center of the transformed bbox?

更新:我尝试使用 jQuery offset 在旋转后找到枢轴,并将该偏移位置用作枢轴点。

演示站点... http://weather.speedfetishperformance.com/dev/raphael/rotation.html

最佳答案

我能想到的最好的跨浏览器方式来做你想做的事情是自己实现旋转而不是让 SVG 来做。旋转 x,y 坐标非常简单,每当我需要进行 2D 旋转时,我都会使用这个 (tcl) 代码:Canvas Rotation .

这样做的好处是您可以最大程度地控制旋转,因为您是手动进行的。这解决了您在旋转后试图猜测最终坐标的问题。此外,这应该是跨浏览器兼容的。

缺点是您必须使用路径。所以没有矩形(尽管将它们转换为路径应该很容易)或省略号(转换为路径有点困难但可行)。此外,由于您是手动执行此操作,因此它应该比让 SVG 为您执行它慢一些。

这是在 javascript 中部分实现的 Tcl 代码:

首先我们需要一个正则表达式来标记 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 值)和弧线之外的所有内容。两者都不应该太难实现。

关于javascript - Raphael SVG VML 实现旋转的多枢轴点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4686651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com