Firefox中的SVG路径动画访问数据不起作用 [英] SVG path animation access data in firefox not working

查看:71
本文介绍了Firefox中的SVG路径动画访问数据不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用SVG创建了一个Hourglass动画. 在chrome&&中工作正常歌剧,但在Firefox上存在一些问题.

可以将沙漏暂停,然后再恢复.现在,在chrome/opera中,我可以读取d的当前值,然后将其应用于简历上的动画元素,但是在Firefox中,该属性未更新,因此无法将当前属性值分配给恢复的元素.

我尝试过: 使用Element.animate()API,但它也不会更改元素的当前值. 使用getComputedStyle()方法,但无法获取d的值,因为firefox并未将其引用为css属性.

这是示例代码: svg.html <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <path d="M 0 0 L 0 200 L 200 200 L 0 0 Z" fill="black" id="myPath"/> </svg>

svg.js

var myPath = document.getElementById('myPath');

var anima = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
anima.setAttributeNS('', 'attributeType', 'XML');
anima.setAttributeNS('', 'attributeName', 'd');
anima.setAttributeNS('', 'values', 'M 0 0 L 0 200 L  200 200 L 0 0 Z; M 0 0 L 100 100 L  200 200 L 0 0 Z');
anima.setAttributeNS('', 'dur', '5s');
anima.setAttributeNS('', 'fill', 'freeze');
myPath.appendChild(anima);
myPath.lastChild.beginElement();

setTimeout(() => {
  console.log(myPath.getAttribute('d')); // in chrome gives the current value, in firefox gives the element original value
}, 1500)

问题是: 1.如何在Firefox中获取当前的d值? 2.没有额外的库,有可能吗?

我做了一个简单示例

如果有人想查看需要的地方,这就是沙漏 >

有人知道吗?

解决方案

因此,使用@RobertLongson技巧,我设法获得了当前的d属性. 它不如铬/歌剧那样舒适,但至少有一种方法:)

对于有相同问题的人,我编写了此函数以返回与chrome中相同的方式返回字符串:

var pointOrders = { // all data types and thier order
    A: ['pathSegTypeAsLetter', 'rx', 'ry', 'angle', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
    C: ['pathSegTypeAsLetter', 'x1', 'y1', 'x2', 'y2', 'x', 'y'],
    H: ['pathSegTypeAsLetter', 'x'],
    L: ['pathSegTypeAsLetter', 'x', 'y'],
    M: ['pathSegTypeAsLetter', 'x', 'y'],
    Q: ['pathSegTypeAsLetter', 'x1', 'y1', 'x', 'y'],
    S: ['pathSegTypeAsLetter', 'x2', 'y2', 'x', 'y'],
    T: ['pathSegTypeAsLetter', 'x', 'y'],
    V: ['pathSegTypeAsLetter', 'Y'],
    Z: ['pathSegTypeAsLetter']    
}

function pointStr(pointArr, pointType, orders){
    var str = "";
    for (var i = 0; i < orders[pointType].length; i++){
        var point = pointArr[orders[pointType][i]];
        if(typeof point === 'number'){
            if(point.toString().match(/\d+.\d{4,}/)){
                point = point.toFixed(3);
            }
            point += " ";
        }
        str += point;
    }
    return str;
}

function dString(dDetailArray){
    var dStr = "";
    for (var p = 0; p < dDetailArray.length; p++){
        var type = dDetailArray[p].pathSegTypeAsLetter;
        if(type.match(/[aA]/)){
            dStr += pointStr(dDetailArray[p], 'A');
        }
        else if(type.match(/[cC]/)){
            dStr += pointStr(dDetailArray[p], 'C');
        }
        else if(type.match(/[hH]/)){
            dStr += pointStr(dDetailArray[p], 'H');
        }
        else if(type.match(/[lL]/)){
            dStr += pointStr(dDetailArray[p], 'L');
        }
        else if(type.match(/[mM]/)){
            dStr += pointStr(dDetailArray[p], 'M');
        }
        else if(type.match(/[qQ]/)){
            dStr += pointStr(dDetailArray[p], 'Q');
        }
        else if(type.match(/[sS]/)){
            dStr += pointStr(dDetailArray[p], 'S');
        }
        else if(type.match(/[vV]/)){
            dStr += pointStr(dDetailArray[p], 'V');
        }
        else if(type.match(/[zZ]/)){
            dStr += pointStr(dDetailArray[p], 'Z');
        }
        else{
            throw `${type} is an invalid data type`
        }
    }
    return dStr;
}

currentPathData(yourPathElem.animatedPathSegList, pointOrders)

希望这对其他人也有帮助,如果您发现我的代码有任何问题,请发表评论,谢谢.

I have created a Hourglass animation with SVG. It works fine in chrome && opera, but has some issues on firefox.

The Hourglass could be paused and then later on resumed. Now in chrome/opera I can read the current value of d and then to apply it for the animation element on resume, but in firefox the attribute isn't being updated and therefor I can't assign the current attribute value to the resumed element.

I tried: Using the Element.animate() API but it is also not changing the current value of the element. Using getComputedStyle() method but it can't get the value of d since firefox isn't refering to it as a css property.

This is the example code: svg.html <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <path d="M 0 0 L 0 200 L 200 200 L 0 0 Z" fill="black" id="myPath"/> </svg>

svg.js

var myPath = document.getElementById('myPath');

var anima = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
anima.setAttributeNS('', 'attributeType', 'XML');
anima.setAttributeNS('', 'attributeName', 'd');
anima.setAttributeNS('', 'values', 'M 0 0 L 0 200 L  200 200 L 0 0 Z; M 0 0 L 100 100 L  200 200 L 0 0 Z');
anima.setAttributeNS('', 'dur', '5s');
anima.setAttributeNS('', 'fill', 'freeze');
myPath.appendChild(anima);
myPath.lastChild.beginElement();

setTimeout(() => {
  console.log(myPath.getAttribute('d')); // in chrome gives the current value, in firefox gives the element original value
}, 1500)

The questions are: 1. How to get the current d value in firefox? 2. Is it possible without extra libraries?

I made a simple example

And this is the hourglass if anyone wants to see where it is needed

Anyone knows something about it?

解决方案

So using @RobertLongson tip I managed to get the current d attribute. It is way less comfortable than it is in chrome/opera but at least there is a way :)

For people with the same problem I wrote this function to return a string the same way you would get in chrome:

var pointOrders = { // all data types and thier order
    A: ['pathSegTypeAsLetter', 'rx', 'ry', 'angle', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
    C: ['pathSegTypeAsLetter', 'x1', 'y1', 'x2', 'y2', 'x', 'y'],
    H: ['pathSegTypeAsLetter', 'x'],
    L: ['pathSegTypeAsLetter', 'x', 'y'],
    M: ['pathSegTypeAsLetter', 'x', 'y'],
    Q: ['pathSegTypeAsLetter', 'x1', 'y1', 'x', 'y'],
    S: ['pathSegTypeAsLetter', 'x2', 'y2', 'x', 'y'],
    T: ['pathSegTypeAsLetter', 'x', 'y'],
    V: ['pathSegTypeAsLetter', 'Y'],
    Z: ['pathSegTypeAsLetter']    
}

function pointStr(pointArr, pointType, orders){
    var str = "";
    for (var i = 0; i < orders[pointType].length; i++){
        var point = pointArr[orders[pointType][i]];
        if(typeof point === 'number'){
            if(point.toString().match(/\d+.\d{4,}/)){
                point = point.toFixed(3);
            }
            point += " ";
        }
        str += point;
    }
    return str;
}

function dString(dDetailArray){
    var dStr = "";
    for (var p = 0; p < dDetailArray.length; p++){
        var type = dDetailArray[p].pathSegTypeAsLetter;
        if(type.match(/[aA]/)){
            dStr += pointStr(dDetailArray[p], 'A');
        }
        else if(type.match(/[cC]/)){
            dStr += pointStr(dDetailArray[p], 'C');
        }
        else if(type.match(/[hH]/)){
            dStr += pointStr(dDetailArray[p], 'H');
        }
        else if(type.match(/[lL]/)){
            dStr += pointStr(dDetailArray[p], 'L');
        }
        else if(type.match(/[mM]/)){
            dStr += pointStr(dDetailArray[p], 'M');
        }
        else if(type.match(/[qQ]/)){
            dStr += pointStr(dDetailArray[p], 'Q');
        }
        else if(type.match(/[sS]/)){
            dStr += pointStr(dDetailArray[p], 'S');
        }
        else if(type.match(/[vV]/)){
            dStr += pointStr(dDetailArray[p], 'V');
        }
        else if(type.match(/[zZ]/)){
            dStr += pointStr(dDetailArray[p], 'Z');
        }
        else{
            throw `${type} is an invalid data type`
        }
    }
    return dStr;
}

currentPathData(yourPathElem.animatedPathSegList, pointOrders)

Hopefully it would be helpful for others too, if you find any problem with my code please leave a comment, thanks.

这篇关于Firefox中的SVG路径动画访问数据不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆