Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
旋转JavaScript中SVG组元素的位置,而不旋转整个图像_Javascript_Svg - Fatal编程技术网

旋转JavaScript中SVG组元素的位置,而不旋转整个图像

旋转JavaScript中SVG组元素的位置,而不旋转整个图像,javascript,svg,Javascript,Svg,我有一张用SVG绘制的地图,我使用矩阵变换根据某些鼠标事件进行旋转。单击地图的某些部分时,会绘制注释(在与旋转图像分离的组元素中) 现在,我可以在拖动地图时移动这些注释,只需将事件发送到一个JavaScript函数,作为一个单独的操作进行转换。我想在旋转和缩放基础贴图时做同样的事情,但不确定如何进行-显然,我不想旋转整个注释图像;我只想移动它以匹配更新的地图。似乎我需要弄清楚如何计算地图变换对单个点的X/Y坐标的影响,然后将该计算应用于注释位置。我似乎找不到任何可能有助于找出如何做到这一点的资源

我有一张用SVG绘制的地图,我使用矩阵变换根据某些鼠标事件进行旋转。单击地图的某些部分时,会绘制注释(在与旋转图像分离的组元素中)

现在,我可以在拖动地图时移动这些注释,只需将事件发送到一个JavaScript函数,作为一个单独的操作进行转换。我想在旋转和缩放基础贴图时做同样的事情,但不确定如何进行-显然,我不想旋转整个注释图像;我只想移动它以匹配更新的地图。似乎我需要弄清楚如何计算地图变换对单个点的X/Y坐标的影响,然后将该计算应用于注释位置。我似乎找不到任何可能有助于找出如何做到这一点的资源

下面是我写的一篇博客文章,讨论了我如何操作底层地图:


那篇文章中的活生生的例子现在不起作用(我移动了JavaScript文件的位置),但它应该为我的问题提供一些有用的上下文。

最后我只是手工计算。以下是我为后代使用的功能:

getRadiusAngle: function(referenceX, referenceY, centerX, centerY) {                
    var width = centerX - referenceX;
    var height = centerY - referenceY;
    var angle, radius;

    if(centerY > referenceY) {
        if(centerX > referenceX) {
            angle = Math.PI - Math.atan(Math.abs(height/width));
            radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
        } else if (centerX < referenceX) {
            angle = Math.atan(Math.abs(height/width));
            radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
        } else if (centerX == referenceX) {
            angle = Math.PI / 2;
            radius = height;
        }
    } else if(centerY < referenceY) {
        if(centerX > referenceX) {
            angle = Math.PI + Math.atan(Math.abs(height/width));
            radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
        } else if (centerX < referenceX) {
            angle = (2 * Math.PI) - Math.atan(Math.abs(height/width));
            radius = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
        } else if (centerX == referenceX) {
            angle = Math.PI * 1.5;
            radius = Math.abs(height);
        }
    } else if(centerY == referenceY) {
        if(centerX > referenceX) {
            angle = Math.PI;
            radius = width;
        } else if (centerX < referenceX) {
            angle = 0;
            radius = Math.abs(width);
        } else if(centerX == referenceX) {
            angle = 0;
            radius = 0;
        }
    }

    return({
        "radius": radius, 
        "angle": angle
    })
},

对于扩展,我使用了类似的策略。

如果您找到了自己的解决方案,您应该将其作为答案并接受它。
var calcwidth = annotations[i].getAttribute("calcwidth");
var matrix = annotations[i].getCTM();

var referenceX = (matrix.e + (calcwidth/2));
var referenceY = (matrix.f + 32);

var ra = this.getRadiusAngle(referenceX, referenceY, pointerX, pointerY);

var current_angle = ra.angle;
var radius = ra.radius

var newX, newY;
if(radius == 0) {
    newX = matrix.e;
    newY = matrix.f;
} else {      
    var new_angle = current_angle + -radians;  

    newX = (pointerX + (radius * Math.cos(new_angle))) - (calcwidth/2);
    newY = (pointerY + -(radius * Math.sin(new_angle))) - 32;
}

annotations[i].setAttribute("transform", "translate(" 
    + newX + " " + newY + ")");