以编程方式更改动画规则中的webkit转换值

问题描述 投票:23回答:7

我有这个样式表:

        @-webkit-keyframes run {
            0% {
                -webkit-transform: translate3d(0px, 0px, 0px);
            }            
            100% {
                -webkit-transform: translate3d(0px, 1620px, 0px);
            }
        }

现在,我想根据一些参数修改1620px的值。像这样:

        @-webkit-keyframes run {
            0% {
                -webkit-transform: translate3d(0px, 0px, 0px);
            }            
            100% {
                -webkit-transform: translate3d(0px, height*i, 0px);
            }
        }

我宁愿能够使用JavaScript和jQuery,虽然纯CSS解决方案可以。

这适用于在其移动Apple Safari浏览器中运行的iPhone游戏。

javascript css safari webkit mobile-safari
7个回答
41
投票

Use the CSSOM

var style = document.documentElement.appendChild(document.createElement("style")),
rule = " run {\
    0%   {\
        -webkit-transform: translate3d(0, 0, 0); }\
        transform: translate3d(0, 0, 0); }\
    }\
    100% {\
        -webkit-transform: translate3d(0, " + your_value_here + "px, 0);\
        transform: translate3d(0, " + your_value_here + "px, 0);\
    }\
}";
if (CSSRule.KEYFRAMES_RULE) { // W3C
    style.sheet.insertRule("@keyframes" + rule, 0);
} else if (CSSRule.WEBKIT_KEYFRAMES_RULE) { // WebKit
    style.sheet.insertRule("@-webkit-keyframes" + rule, 0);
}

如果要修改已包含的样式表中的关键帧规则,请执行以下操作:

var
      stylesheet = document.styleSheets[0] // replace 0 with the number of the stylesheet that you want to modify
    , rules = stylesheet.rules
    , i = rules.length
    , keyframes
    , keyframe
;

while (i--) {
    keyframes = rules.item(i);
    if (
        (
               keyframes.type === keyframes.KEYFRAMES_RULE
            || keyframes.type === keyframes.WEBKIT_KEYFRAMES_RULE
        )
        && keyframes.name === "run"
    ) {
        rules = keyframes.cssRules;
        i = rules.length;
        while (i--) {
            keyframe = rules.item(i);
            if (
                (
                       keyframe.type === keyframe.KEYFRAME_RULE
                    || keyframe.type === keyframe.WEBKIT_KEYFRAME_RULE
                )
                && keyframe.keyText === "100%"
            ) {
                keyframe.style.webkitTransform =
                keyframe.style.transform =
                    "translate3d(0, " + your_value_here + "px, 0)";
                break;
            }
        }
        break;
    }
}

如果您不知道订单但知道CSS文件的URL,请将document.styleSheets[0]替换为document.querySelector("link[href='your-css-url.css']").sheet


7
投票

您是否尝试在html文档头部的<style>元素中声明css的关键帧部分。然后,您可以为此元素提供id或其他任何内容,并随时随地使用javaScript更改其内容。像这样的东西:

<style id="keyframes">
        @-webkit-keyframes run {
            0%    { -webkit-transform: translate3d(0px,0px,0px); }            
            100%  { -webkit-transform: translate3d(0px, 1620px, 0px); }
        }
</style>

然后你的jquery可以正常改变它:

$('#keyframes').text('whatever new values you want in here');

3
投票

从你的例子来看,在我看来CSS动画可能有点矫枉过正。改为使用转换:

-webkit-transition: -webkit-transform .4s linear; /* you could also use 'all' instead of '-webkit-transform' */

然后通过js将新变换应用于元素:

$("<yournode>")[0].style.webkitTransform = "translate3d(0px,"+ (height*i) +"px,0px)";

它应该有动力。


2
投票

当你想修改这些值(即使用变量)时我没有得到,但是这里有3到4个解决方案和1个不可能的解决方案(现在)。

  • 服务器端计算:为了不时地提供不同的CSS,您可以告诉PHP或任何服务器端语言解析.css文件以及.php.html,然后在PHP标记之间使用PHP变量。注意文件缓存:为了避免它,你可以加载样式表,如style.css?1234567890random-or-time它会产生一个明显不同的文件,因此不会被缓存
  • SASS也是一个需要Ruby的服务器端解决方案,它将为您提供现有的语法,可能比手工制作的解决方案更清晰,因为其他人已经解决了问题和解决方案
  • LESS是一个客户端解决方案,它将加载你的.less文件和一个less.js文件,该文件将解析前者,并为你提供CSS中的变量,无论你的服务器是什么。它也可以在服务器端与node.js一起工作
  • 在页面显示时动态修改CSS? 对于2D,有Ben Barnett的jquery-animate-enhanced2d-transformCSS3 rotate反过来(他们尽可能使用CSS3,没有这样的功能,他们回退到现有的jQuery .animate()和IE矩阵过滤器)但就是这样。 您可以使用一些参数来管理您想要通过3D转换实现的create a plugin for jQuery,并避免在DOM中修改长而复杂的CSS规则的麻烦
  • 仅限CSS:您可以使用-moz-calc [1] [2]仅适用于Firefox 4.0,其中-webkit-transform仅适用于... OK nevermind :-)

1
投票

尝试这样的事情:

var height = {whatever height setting you want to detect};
element.style.webkitTransform = "translate3d(0px," + height*i + ",0px)";

1
投票

一个'矮胖'的解决方案?

在您选择的粒度范围内创建高度转换,例如0-99,100-199,200-299等。每个都具有唯一的动画名称标识符,如:

@-webkit-keyframes run100 {
        0%    { -webkit-transform: translate3d(0px,0px,0px); }            
        100%  { -webkit-transform: translate3d(0px,100px,0px); }
}

@-webkit-keyframes run200 {
        0%    { -webkit-transform: translate3d(0px,0px,0px); }            
        100%  { -webkit-transform: translate3d(0px,200px,0px); }
}

然后创建匹配的CSS类:

.height-100 div { 
    -webkit-animation-name: run100;  
}

.height-200 div { 
    -webkit-animation-name: run200;  
}

然后用javascript决定你所在的块,并为周围的元素分配适当的类。

$('#frame').attr('class', '').addClass('height-100');

如果粒度不太好,可能还可以!


0
投票

我使用warmanp的解决方案并且它有效,但有一些非常重要的调整。

$('#ticket-marquee-css').text(
    "@-webkit-keyframes marqueeR{ 0%{text-indent: -" + distanceToMove + "px;} 100%{text-indent: 0;} }" + 
    "@-webkit-keyframes marqueeL{ 0%{text-indent: 0;} 100%{text-indent: -" + distanceToMove + "px;} }"
);

为了使CSS转换更新,而不是使用先前定义的值,我不得不停止动画,然后重新启动。为此,我在元素上放置了一个“active”类,并使CSS仅将转换应用于具有该类的元素

#marquee1.active {-webkit-animation-name: marqueeL;}
#marquee2.active {-webkit-animation-name: marqueeR;}

然后我只需要关闭“活动”类,等待它应用于DOM(因此是setTimeout),然后重新应用它。

$('.ticket-marquee').removeClass('active');
setTimeout(function() { $('.ticket-marquee').addClass('active'); },1);

而且效果很好!现在我可以动态改变文本移动的距离!

© www.soinside.com 2019 - 2024. All rights reserved.