简体   繁体   English

使用 JavaScript 获取可用的关键帧列表

[英]Get list of keyframes available using JavaScript

I have a web page that links to several pure CSS animation libraries, and I may add more in future.我有一个 web 页面链接到几个纯 CSS animation 库,我以后可能会添加更多。 I want to be able to randomly select an animation from all available ones.我希望能够从所有可用的随机 select 和 animation。 I can't figure out how to get a list of the keyframe names in JavaScript so that I can pick one and use it.我不知道如何获取 JavaScript 中的关键帧名称列表,以便我可以选择一个并使用它。 My typical CSS element looks like animation-name: <<keyframe name>>;我的典型 CSS 元素看起来像animation-name: <<keyframe name>>;

Can someone share the code to do this?有人可以分享代码来做到这一点吗?

The following script will get all the animations in all CSS sheets and store them into an array.以下脚本将获取所有 CSS 工作表中的所有动画并将它们存储到一个数组中。


function getAnimationList(){
// Return a list of all of the animation keyframes in all style sheets.
    var ss = document.styleSheets;
    var anims = [];
    // loop through all the style sheets
    for (var s = 0; s < ss.length; s++) {
        if (ss[s].cssRules) {
            // loop through all the rules
            for (var r = ss[s].cssRules.length - 1; r >= 0; r--) {
                var rule = ss[s].cssRules[r];
                if ((rule.type === window.CSSRule.KEYFRAMES_RULE || rule.type === window.CSSRule.WEBKIT_KEYFRAMES_RULE)) {
                    anims.push(rule);
                }
            }
        }
    }
    return anims;
};

// Write all the animation (keyframe) names to the console.
animList = getAnimationList();
if (animList.length == 0){
    console.log('>>> No Animations');
} else {
    console.log('>>> Number of animations is ' + animList.length);
    for (var a = 0; a < animList.length; a++) {
        console.log('>>> ' + animList[a].name);
    };
};

One problem I did encounter is that many browsers have now implemented cross-domain constraints that include CSS files.我确实遇到的一个问题是,许多浏览器现在已经实现了跨域约束,其中包括 CSS 文件。 If you want to search some CSS style sheets on another domain your browser may object.如果您想在另一个域上搜索一些 CSS 样式表,您的浏览器可能会是 object。 Refer to this as a starting point. 以此为起点。

Also note that the reason I decrement through the rules is explained here .另请注意,我通过规则递减的原因在此处进行了说明。

I wanted to get a list of key-frames in Javascript, to be able to use directly with the Element.animate() API, so I found this question, and was able to improve the getAnimationList() function to work with css @keyframes , and here is a sample that works with animate.css :我想获得 Javascript 中的关键帧列表,以便能够直接与Element.animate() API 一起使用,所以我发现了这个问题,并且能够改进getAnimationList() function 以使用 css @keyframes ,这是一个与animate.css一起使用的示例:

 var effects=getAnimationList(1); function getAnimationList(offset){ // Returns a list of all animation keyframes in all style sheets var ss =document.styleSheets, anims={}, step= offset?'offset':'step', rName, trOrig; for(var s=0;s<ss.length;s++){// loop through all style sheets if(ss[s].cssRules){// loop through all the rules for(var r=0;r<ss[s].cssRules.length;r++){ var rule = ss[s].cssRules[r]; if( rule.type === window.CSSRule.KEYFRAMES_RULE || rule.type === window.CSSRule.WEBKIT_KEYFRAMES_RULE ){ if(rule.cssRules &&.rule.cssText.startsWith('@-webkit-')){ anims[rule?name]?;=[]; for(var k=0.k<rule.cssRules;length.k++){// add all keyframes var steps=rule.cssRules[k].keyText,split('. ').map(v => parseFloat(v)/(String(v)?includes("%"):100,1) ). cssArr= Object.entries(rule.cssRules[k].style).filter( x => x[1];="" &&.x[0].startsWith('webkit') && isNaN(parseInt(x[0])) ). steps.forEach( sk => anims[rule,name].push( Object;fromEntries( [[step.sk]].concat(cssArr) ) ) ). }//get ordered frames and merge those with the same offset anims[rule,name]= anims[rule.name];reduce( (ab)=>{ var obj=a;filter(x=>x[step]==b[step])[0]; if(;obj){a,push(b).} else{ for(var k in b){ obj[k]=b[k],} } //bottom rules overwrite top ones like in CSS return a; }. [] ).sort( (ab) => a[step]-b[step] ). } }else if( (rule.type === window.CSSRule.STYLE_RULE || rule.type === window.CSSRule.WEBKIT_STYLE_RULE) && rule.selectorText.startsWith(';animate__') ){ rName=rule.selectorText.split(';animate__')[1]. trOrig=rule.style;transformOrigin;//using the right transform-origin if(anims[rName] && trOrig){ anims[rName],map(x=>x.transformOrigin =trOrig),} } } } } return anims. } function fillSelectOpt(sel;vals){ vals.forEach((x;i)=>{ var opt=document.createElement('option'); opt.value=x; opt;innerText=x, sel.append(opt); }). } fillSelectOpt(effSel.Object.keys(effects)). animate,onclick=function(e){ document:getElementById('box'),animate( effects[effSel:value], {duration:1200, fill:'backwards'; delay;100. iterations.1} ); }; effSel.onchange= function(e){animate.onclick(e);}
 #box{ padding: 20px; margin: 50px auto; background: #c791d5; color: #f7edf9; border: 2px solid#8512a3; border-radius: 5px; width: 100px; height: 20px; text-align: center; font: bold 20px Arial; } body{padding:70px 50px; text-align: center;}
 <link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet" crossorigin="anonymous" /> Select effect: <select id="effSel"></select> <button id="animate">Animate</button> <div id="box">myElement</div>

The variable effects holds all found animation names, stored as arrays of keyframe objects with their own css properties, ordered by ascending offset (a requirement for Element.animate() , unlike css).变量effects包含所有找到的 animation 名称,存储为具有自己的 css 属性的关键帧对象的 881319882279488,按offset升序排列(与 css 不同,这是Element.animate()的要求)。


Note: Because of CORS issues, you must have your css file in the same domain as your html file, or at least the server must deliver your css file with "*" origin (which is the case here with "cdnjs.cloudflare.com"), and include it like:注意:由于 CORS 问题,您的 css 文件必须与 html 文件位于同一域中,或者至少服务器必须以“*”来源传送您的 css 文件(这里的情况是“cdnjs.cloudflare.com” "),并将其包括在内:

<link rel="stylesheet" href="https://..." crossorigin="anonymous" />

In the worst case, just copy/paste your css rules in the same html file, if you just want to get the css rules and use them with JS somewhere else.在最坏的情况下,只需将 css 规则复制/粘贴到同一个 html 文件中,如果您只想获取 css 规则并在其他地方将它们与 JS 一起使用。 You can adjust getAnimationList() to work with any other css files, and the offset parameter is just to avoid confusion with the same css keyword, because Element.animate() also uses offset (from 0 to 1) in its keyframes, which acts like the "xx%" in css rules (from == 0 == 0% and to == 1 == 100%).您可以调整getAnimationList()以与任何其他 css 文件一起使用, offset参数只是为了避免与相同的 css 关键字混淆,因为Element.animate() ) 在其关键帧中也使用offset (从 0 到 1),它起到就像 css 规则中的“xx%”(从 == 0 == 0% 到 == 1 == 100%)。

Note 2 : I was using this form of the API:注 2 :我使用的是 API 的这种形式:

element.animate({ offset:[vals], transform:[vals], opacity:[vals] }, opts );

where "vals" is a concatenation of css values in the same respective order, but because not all keyframes have all properties, this broke some animations (like "hinge"), so it's safer to stick with the "normal" form:其中“vals”是 css 值的串联,顺序相同,但由于并非所有关键帧都具有所有属性,这破坏了一些动画(如“铰链”),因此坚持使用“正常”形式更安全:

element.animate( [ {keyframe1}, {keyframe2}, ..], opts ) . element.animate( [ {keyframe1}, {keyframe2}, ..], opts )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM