Javascript 如何动态创建'@-关键帧';CSS动画?

Javascript 如何动态创建'@-关键帧';CSS动画?,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我需要旋转div并在特定位置停止(该值将从服务器接收) 我试着让原生JS旋转并停止,但它占用了我大量的CPU时间 我可以使用CSS动画进行旋转,但我需要创建一个类来动态描述停止动画的位置。差不多 @-webkit-keyframes spinIt { 100% { -webkit-transform: rotate(A_DYNAMIC_VALUE); } } @-moz-keyframes spinIt { 100% { -webkit-t

我需要旋转div并在特定位置停止(该值将从服务器接收)

我试着让原生JS旋转并停止,但它占用了我大量的CPU时间

我可以使用CSS动画进行旋转,但我需要创建一个类来动态描述停止动画的位置。差不多

@-webkit-keyframes spinIt {
    100% {
        -webkit-transform: rotate(A_DYNAMIC_VALUE);
    }
}
@-moz-keyframes spinIt {
    100% {
        -webkit-transform: rotate(A_DYNAMIC_VALUE);
    }
}
这里有一个参考


提前感谢

我认为创建动态的
@关键帧并不容易
它们是不灵活的,因为它们必须硬编码。

转换更容易使用,因为它们可以优雅地响应JavaScript执行的任何CSS更改

但是,CSS转换的复杂性非常有限-一个包含多个步骤的动画很难实现。

这是CSS@keyframe动画想要解决的问题,但是它们没有提供像转换那样的动态响应能力。

但是这些链接可能会帮助你

:一种生成@-webkit关键帧动画的工具,其中包含许多小步骤。这打开了一扇无限选择宽松公式的大门

将其作为基础将对您有很大帮助,因为它提供了一个UI来创建动画并将其导出到CSS代码


我想这个解决方案肯定会对您有用。它用于动态关键帧

您可以动态插入样式表规则以覆盖头部中以前的样式。这有助于避免为单个任务添加另一个库

var style = document.createElement('style');
style.type = 'text/css';
var keyFrames = '\
@-webkit-keyframes spinIt {\
    100% {\
        -webkit-transform: rotate(A_DYNAMIC_VALUE);\
    }\
}\
@-moz-keyframes spinIt {\
    100% {\
        -webkit-transform: rotate(A_DYNAMIC_VALUE);\
    }\
}';
style.innerHTML = keyFrames.replace(/A_DYNAMIC_VALUE/g, "180deg");
document.getElementsByTagName('head')[0].appendChild(style);

Alex Grande的答案适用于一些关键帧。但是,如果你想一次又一次地动态添加关键帧,那么你的网页就会变得非常滞后,非常快。要解决这个问题,只需停止创建新的DOM元素。相反,创建一个新的DOM样式表,并将其与inertRule一起重用。如果您想要更多的关键帧(例如,如果您正在为每个animationframe生成一个新的关键帧),那么您需要设置一个系统,在旧关键帧不再使用后删除它们。这是如何实现这一目标的良好开端

var myReuseableStylesheet = document.createElement('style'),
    addKeyFrames = null;
document.head.appendChild( myReuseableStylesheet );
if (CSS && CSS.supports && CSS.supports('animation: name')){
    // we can safely assume that the browser supports unprefixed version.
    addKeyFrames = function(name, frames){
        var pos = myReuseableStylesheet.length;
        myReuseableStylesheet.insertRule(
            "@keyframes " + name + "{" + frames + "}", pos);
    }
} else {
    addKeyFrames = function(name, frames){
        // Ugly and terrible, but users with this terrible of a browser
        // *cough* IE *cough* don't deserve a fast site
        var str = name + "{" + frames + "}",
            pos = myReuseableStylesheet.length;
        myReuseableStylesheet.insertRule("@-webkit-keyframes " + str, pos);
        myReuseableStylesheet.insertRule("@keyframes " + str, pos+1);
    }
}
用法示例:

addKeyFrames(
    'fadeAnimation',
    '0%{opacity:0}' + 
    '100%{opacity:1}'
);

另外,Alex Grande,我非常确定自IE8以来不需要
document.getElementsByTagName('head')[0]
type='text/css'
,并且直到IE10才支持
@关键帧。只是说…

用户7892745不适合我,需要一些调整

1°“pos”不理解wot应为,但控制台日志显示“未定义” 所以我删除了“,pos”

2°“myReuseableStylesheet.insertRule”给我错误“不是函数” 所以我用“innerHTML”代替“insertRule”

3°我终于搬家了“ document.head.appendChild(myReuseableStylesheet);“在末尾

但在这之后,它工作得很好,这正是我想要的。 非常感谢用户7892745:D

也许我的问题来自于我使用它的方式

这是我使用的脚本

var getclass = document.getElementsByClassName("cls");
var countclass = getclass.length;
for (var i=0; i <countclass; i++ ){
    getclass[i].addEventListener('mouseover', function(){
        // get the data-name value to show element whose id are the same
        var x=  this.getAttribute("data-name"); 
        var y =document.getElementById(x);
            y.style.display="block";
            // because the element to show have fixed width, but different text length, they have different height
            // so I need to get the highness, then use the value of height to define the 100% value of animation
            // or the longer ones will be cutted an the shorten have a lot of empty space a the end
        var yHeig= Math.round(parseInt(getComputedStyle(y).getPropertyValue('height')));
            yHeig_ = yHeig - 10; // to shorten a bit the time from end and new passage
        console.log(yHeig+" - "+ yHeig_);
        addKeyFrames(
                'showMe',
                '0%{top:35px;}' + 
                '100%{top:-'+ yHeig_ +'px;}'
            );
        y.style.animation="showMe 7s linear infinite";

    },false);

    getclass[i].addEventListener('mouseout', function(){
        var x=  this.getAttribute("data-name");
        document.getElementById(x).style.display="none";
    },false);
}
var getclass=document.getElementsByClassName(“cls”);
var countclass=getclass.length;

对于(var i=0;i您可以在CSSKeyframeRule中更改样式,这对我来说在Chrome中很好,如下代码所示。 希望这会有所帮助:)


#正文{
显示:内联块;
}
正文
//动态创建关键帧动画
document.styleSheets[0]。insertRule('\
@关键帧动画{\
来自{transform:rotateZ(0deg);}\
到{变换:旋转(360度);}\
}'
);
var div=document.getElementById('text');
div.style.animation='anim 1s线性向前';
//此功能将更改动画
功能停止在某个度数(d){
var ss=document.styleSheets[0];
var anim;
用于(ss.cssRules中的变量i){
//按名称查找动画
if(ss.cssRules[i].name=='anim'){
anim=ss.cssRules[i];
打破
}
}
var stopFrame=anim.cssRules[1];//这表示上面“anim”的第二行。
//更改任何属性
stopFrame.style.transform='rotateZ('+d+'deg');
}
停止在180度;

在JavaScript中,是否可以使用document.styleSheets访问样式表。每个工作表都有一个规则和/或cssRule列表(取决于浏览器)和一个方法

此方法允许您将新的关键帧原始添加为字符串:

JavaScript

function insertStyleSheetRule(ruleText)
{
    let sheets = document.styleSheets;

    if(sheets.length == 0)
    {
        let style = document.createElement('style');
        style.appendChild(document.createTextNode(""));
        document.head.appendChild(style);
    }

    let sheet = sheets[sheets.length - 1];
    sheet.insertRule(ruleText, sheet.rules ? sheet.rules.length : sheet.cssRules.length);
}

document.addEventListener("DOMContentLoaded", event =>
{
    insertStyleSheetRule("@keyframes spinIt { 0% { transform: rotate(-20deg); } 100% { transform: rotate(20deg); } }");

    insertStyleSheetRule("#box { " + 
        "animation: spinIt 1s infinite alternate cubic-bezier(0.5,0,0.5,1); " + 
        "width: 64px; height: 64px; background-color: red; border: 4px solid black; " + 
    "}");
});
html

<div id="box"></div>

演示:

您可以创建一个
元素,将其内容设置为所需的CSS,在本例中是动画声明,并将其添加到页面的

另外,正如其他人所建议的,如果您需要创建许多不同的动画,那么最好重用单个
标记,而不是创建多个并使用添加新样式

最后,如果您可以使用ES6,您的代码将看起来更干净:

让dynamicStyles=null;
函数addAnimation(身体){
如果(!dynamicStyles){
dynamicStyles=document.createElement('style');
dynamicStyles.type='text/css';
document.head.appendChild(dynamicStyles);
}
dynamicStyles.sheet.insertRule(主体,dynamicStyles.length);
}
添加动画(`
@关键帧myAnimation{
0%{变换:旋转(0);}
20%{transform:rotate(${360*Math.random()}度);}
60%{transform:rotate(${-360*Math.random()}度);}
90%{transform:rotate(${360*Math.random()}度);}
100%{变换:旋转(${0}度);}
}
`);
document.getElementById(“圆圈”).style.animation='myAnimation'
html,
身体{
高度:100vh;
}
身体{
显示器:flex;
证明内容:中心;
对齐项目:居中;
保证金:0;
}
#圈{
宽度:100px;
高度:100px;
框阴影:
0 0 48px-4倍rgba(0
function addAnimation(keyframe){
     var ss=document.createElement('style');
     ss.innerText=keyframe;
     document.head.appendChild(ss);
}
--lightScaleStart: 0.8;

.light {
    animation: grow 2s alternate infinite ease-in-out;
}

.light.yellow {
    --lightScaleEnd: 1.1;
}

.light.red {
    --lightScaleEnd: 1.2;
}

@keyframes grow {
  from {
    transform: scale(var(--lightScaleStart));
  }
  to {
    transform: scale(var(--lightScaleEnd));
  }
}