【问题标题】:Scale SVG (Raphaël) paths from center on mouse hover在鼠标悬停时从中心缩放 SVG (Raphaël) 路径
【发布时间】:2012-12-16 11:51:46
【问题描述】:

我试图在鼠标悬停时缩放 SVG 路径,但因为我必须在将路径添加到纸上时对其进行转换,结果弄得一团糟。

请看: http://jsfiddle.net/chrisloughnane/Kc4q2/

使用此变换属性添加路径:

transform: 'S2.5,2.5,0,0'

mouse in 上,我使用以下动画: this.animate({transform: 's2.9,2.9,0,0'}, 200);

mouse out 我恢复: this.animate({transform: 's2.5,2.5,0,0' }, 400, "bounce");

在这里查看后,我发现有人提到了element.getBBox(),我尝试了这个,但我搞砸了。

var center = this.getBBox();
var adjustx = center.width / 2 ;//+ center.x;
var adjusty = center.height / 2 ;//+ center.y;
adjustx = (1 - 3)*adjustx;
adjusty = (1 - 3)*adjusty;

谁能指出我错过了什么?

或者推荐一个很好的工具来将 SVG 路径调整为新的默认值。我试过inkscape和http://svg-edit.googlecode.com/svn/branches/2.5.1/editor/svg-editor.html

tia

【问题讨论】:

    标签: jquery svg raphael scale


    【解决方案1】:

    处理转换是拉斐尔最不喜欢的部分。我可能在这里遗漏了一个明显的解决方案,但这是我修复它的方法:

    • 在原始转换之前获取边界框,此时形状完全按照路径指定的方式绘制。

    • 计算鼠标悬停前后形状中心的 dx 和 dy 差异。如果 bbox 是原始的预缩放边界框,那么对于 dx,这将是 2.5 * (bbox.x + bbox.width / 2) - 2.9 (bbox.x + bbox.width / 2)。这显然可以减少。

    • 将放大后的形状向后平移这些量。

    在代码中:

        var obj = paper.path(paths[county].path);
        obj.bbox = obj.getBBox();
        obj.attr({ transform: 'S2.5,2.5,0,0' });
    
        obj.mouseover(function (e) {
            var dx = -0.4 * (this.bbox.x + this.bbox.width / 2);
            var dy = -0.4 * (this.bbox.y + this.bbox.height / 2);
            this.animate({ transform: 'S2.9,2.9,0,0T' + dx + ',' + dy}, 200);
        }).mouseout(function (e) {
            this.animate({ transform: 's2.5,2.5,0,0' }, 400, "bounce");
        });
    

    这是updated fiddle for you。作为参考,我让它绘制了代表鼠标悬停前后边界框的红色和蓝色矩形——每当转换让我消化不良时,我都会使用这种策略。您自然会想要删除它们。

    要记住的另一件事:不规则形状的实际中心是它的center of mass,而不是其边界框的中点。 (只有当它是一个完全对称的形状时,这两个点才相同,而地理边界很少会产生这种形状。)对于像阿拉斯加州这样的形状,在拐角处有很多岛屿,这会使基于中心的缩放看起来很尴尬.

    如果您想变得更花哨,可以尝试计算每个形状的质心。但我怀疑你想去那里,而且这些县似乎在中心周围的质量分布大致均匀。

    【讨论】:

    • 非常感谢您的详细回答,我从您的工作中学到了很多东西。我立即尝试在我的主项目页面中复制您的解决方案并得到了一个奇怪的结果。路径上的第一次悬停效果很好,但所有后续悬停都会导致路径从其原始位置移动到越来越远的距离。经过大量试验和错误后,我发现如果我删除了与您的参考框有关的所有内容,则会导致问题。 jsfiddle.net/Kc4q2/15 但如果你取消注释 //var box = this.getBBox();有用。你以前见过这个吗?再次感谢。
    • 这对我来说太草率了。由于“this.bbox”是对对象边界框的引用,它随每个比例而变化,因此adjustx 和adjusty 值每次都在变化。但是我认为没有理由不止一次地计算它们。请参阅更新的小提琴:dx 和 dy 现在是对象在创建时计算一次的属性。 jsfiddle.net/Kc4q2/16
    • 在下面的链接中演示之前,我遇到了类似的东西。我发现如果你在函数内部进行绑定,然后在一个事件上调用该函数,你最终会得到 2^x, x=iterations。当我看到路径以越来越远的距离移动时,它让我想起了下面的例子。你真的为我节省了很多工作。谢谢,当大学允许我完成它时,我会在这里发布期末考试。 jsfiddle.net/chrisloughnane/acNwn
    猜你喜欢
    • 1970-01-01
    • 2018-08-20
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2015-06-01
    • 2021-09-30
    • 2018-12-18
    相关资源
    最近更新 更多