【问题标题】:SVG path calculation results in all zeroed coordinatesSVG 路径计算结果为全零坐标
【发布时间】:2014-09-20 22:38:12
【问题描述】:

我正在制作一个脚本,让我可以在两个或多个具有相同数量值的关键帧之间制作一个简单的 svg 路径补间(平滑变形动画)。我输入的形状应将椭圆形(关键帧 [0])变形为语音气泡形状(关键帧 [1])。

我遇到的问题是,当我尝试调试时,它告诉我 svg 元素的值全为 0。

<path d="M0, 0, Q0, 0, 0, 0, L0, 0, Q0, 0, 0, 0, L0, 0, Q0, 0, 0, 0, L0, 0, Q0, 0, 0, 0, L0, 0, L0, 0, L0, 0, Z" fill="#ffffff" stroke="#000000"></path>

当控制台向我显示它应该具有的值是

M-68.39999999999999, -18.787499999999998, Q-72.9, 0, -97.2, -4.5, L-97.2, -258.525, Q-121.5, -263.02500000000003, -116.99999999999999, -281.8125, L68.39999999999999, -281.8125, Q72.9, -300.59999999999997, 97.2, -296.1, L97.2, -42.075, Q121.5, -37.574999999999996, 116.99999999999999, -18.787499999999998, L48.6, -18.787499999999998, L24.3, 18.787499999999998, L0, -18.787499999999998, ZM-70.93333333333334, -19.483333333333334, Q-75.60000000000001, 0, -100.8, -4.666666666666666, L-100.8, -268.09999999999997, Q-126, -272.76666666666665, -121.33333333333333, -292.25, L70.93333333333334, -292.25, Q75.60000000000001, -311.73333333333335, 100.8, -307.06666666666666, L100.8, -43.63333333333333, Q126, -38.96666666666667, 121.33333333333333, -19.483333333333334, L50.4, -19.483333333333334, L25.2, 19.483333333333334, L0, -19.483333333333334, Z 

我的逻辑一定有错误,但我不知道为什么这不起作用。

JS:

$(function() {

    var sponsorBubble = function(el, html, cornerRad) {
        this.html = html,
        this.width = el.parent().width(),
        this.height = el.parent().height(),
        this.arrowWidth = el.parent().width()/4,
        this.arrowHeight = el.parent().height()/8,
        this.cornerRad = cornerRad;


        //ENSURE SAME NUMBER OF PATH SEGMENTS IN ALL KEYFRAMES (START TO END)
        this.keypaths = [];

        this.keypaths[0] = [
            "M",
            (this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "Q",
            (this.width/2) - (this.arrowWidth/2), this.height - this.arrowHeight,
            (this.width/2), this.height - this.arrowHeight,
            "L",
            (this.width/2), this.height - this.arrowHeight,
            "Q",
            (this.width/2) + (this.arrowWidth/2), this.height - this.arrowHeight,
            (this.width/2) + (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "L",
            (this.width/2) + (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "Q",
            (this.width/2) + (this.arrowWidth/2), this.height,
            (this.width/2), this.height,
            "L",
            (this.width/2), this.height,
            "Q",
            (this.width/2) - (this.arrowWidth/2), this.height,
            (this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "L",
            (this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "L",
            (this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "L",
            (this.width/2) - (this.arrowWidth/2), this.height - (this.arrowHeight/2),
            "Z"
        ];

        this.keypaths[1] = [
            "M", //STARTS AT BOTTOM LEFT, GOING CLOCKWISE
            this.cornerRad, this.height-this.arrowHeight,
            "Q",
            0, this.height-this.arrowHeight,
            0, this.height-this.arrowHeight-this.cornerRad,
            "L",
            0, this.cornerRad,
            "Q",
            0,0,
            this.cornerRad, 0,
            "L",
            this.cornerRad+(this.width - (this.cornerRad*2)), 0,
            "Q",
            this.width, 0,
            this.width, this.cornerRad,
            "L",
            this.width, this.cornerRad+(this.height-this.arrowHeight-(this.cornerRad*2)),
            "Q",
            this.width, this.height-this.arrowHeight,
            this.width-this.cornerRad, this.height-this.arrowHeight,
            "L",
            (this.width/2)+(this.arrowWidth/2), this.height-this.arrowHeight,
            "L",
            this.width/2, this.height,
            "L",
            (this.width/2)-(this.arrowWidth/2), this.height-this.arrowHeight, 
            "Z"
        ];


    };

    sponsorBubble.prototype.getFrame = function(frame, total_steps, current_step) {

    if (this.keypaths[frame + 1]) { //IF THERES FRAMES AFTER
        for (var i = 0; i <= this.keypaths[frame].length; i++) {
            //IF IS A LETTER
            if (isNaN(this.keypaths[frame][i])) {
                if (this.newpath && i < this.keypaths[frame].length - 1) {
                    this.newpath = this.newpath + this.keypaths[frame][i];
                }
                else if (!this.newpath) {
                    this.newpath = this.keypaths[frame][i];
                }
                else if (this.newpath && i == this.keypaths[frame].length - 1) {
                    this.newpath = this.newpath + this.keypaths[frame][i];
                }
            }

            //IF IS A NUMBER
            else {
                if (this.newpath && i < this.keypaths[frame].length - 1) {
                    this.newpath = this.newpath + (((this.keypaths[frame + 1][i] - this.keypaths[frame][i]) / total_steps) * current_step) + ", ";
                }
                else {
                    this.newpath = this.newpath + this.keypaths[frame][i];
                }
            }
        }
    }

    else { //NO FRAMES AFTER
        for (var i = 0; i <= this.keypaths[frame].length; i++) {
            //IF IS A LETTER
            if (isNaN(this.keypaths[frame][i])) {
                if (this.newpath && i < this.keypaths[frame].length - 1) {
                    this.newpath = this.newpath + this.keypaths[frame][i];
                }
                else if (!this.newpath) {
                    this.newpath = this.keypaths[frame][i];
                }
                else if (this.newpath && i === this.keypaths[frame].length - 1) {
                    this.newpath = this.newpath + this.keypaths[frame][i];
                }
            }

            //IF IS A NUMBER
            else {
                if (this.newpath && i < this.keypaths[frame].length - 1) {
                    this.newpath = this.newpath + this.keypaths[frame][i] + ", ";
                }
                else {
                    this.newpath = this.newpath + this.keypaths[frame][i];
                }
            }
        }
    }

        current_step++;

        if (current_step < total_steps) {
                console.log(this.newpath);
            requestAnimationFrame(function() {
                bub.getFrame(frame, total_steps, current_step);
            });
        }
}

snapper = Snap('#svg');
var bub = new sponsorBubble($('#svg'), 'test', 5, 20);
bub.getFrame(0, 30, 0);

var test = snapper.path(bub.newpath);
    test.attr({
        fill: 'white',
        stroke: 'black'
    });
});

HTML:

<!DOCTYPE html>
<html>
    <head>
        <link type="text/css" rel="stylesheet" href="bubble.css" />
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script type="text/javascript" src="snap.svg-min.js"></script>
        <script type="text/javascript" src="bubble.js"></script>
    </head>

    <body>
        <div id="inset">
            <div id="inset2">
                <svg id="svg" width="100%" height="100%"></svg>
            </div>
        </div>
    </body>

</html>

CSS:

body, html {
    width: 100%;
    height: 100%;
    border: 0;
    padding: 0;
    margin: 0;
}

#inset {
 width: 20%;
 height: 50%;
 position: absolute;
 bottom: 0;
 left: 50%;
}

#inset2 {
 width: 80%;
 height: 100%;
}

JSfiddle: http://jsfiddle.net/bmjkz1rf/

【问题讨论】:

    标签: jquery svg snap.svg


    【解决方案1】:

    你的插值算法是错误的。

    要在x0x1 两个值之间进行插值,公式为:

    x0 + ((x1 - x0) * current_step / total_steps)
    

    代码目前缺少第一个 x0 术语。

    我认为还有更多需要解决的问题。就目前而言,this.newpath 是一个字符串,它随着递归的进行而不断增长,在“Z”之后和下一个“M”之前没有任何描述。我不确切知道需要什么,但我认为这不可能是正确的。即使您修复了“...ZM...”的描述,您仍然会得到一个怪物字符串,而我猜您想要一组(一个数组?)单个帧。

    即使我错了并且你确实想要一个怪物字符串,最好放弃.getFrame() 的递归并迭代地调用它,在每次迭代时返回一帧的数据,从而构建你的最终调用函数中的数据结构。

    【讨论】:

    • 哇,你说得对。甚至没有注意到这一点。这个想法是迭代地调用每一帧,我只是没有意识到它是在添加而不是替换路径数据。无论哪种方式,非常感谢男人
    • 我假设您的案例需要其他东西,但我想我会提到 Snap 已经在相同点数的路径之间变形,stackoverflow.com/questions/22987836/…
    • @Ian,不错!您可能会说,我对 SVG 了解不多。我只是根据 javaScript 和简单数学的一般知识调试了这个。
    猜你喜欢
    • 2012-07-16
    • 2010-11-11
    • 2023-02-09
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    相关资源
    最近更新 更多