программно изменяющие значения webkit-преобразования в правилах анимации - PullRequest
23 голосов
/ 24 февраля 2011

У меня есть эта таблица стилей:

        @-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-решение подойдет.

Это игра для iPhone, которая запускается в мобильном браузере Apple Safari.

Ответы [ 7 ]

41 голосов
/ 20 марта 2011

Используйте 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;
    }
}

Если вы не знаетезакажите, но знаете URL-адрес файла CSS, замените document.styleSheets[0] на document.querySelector("link[href='your-css-url.css']").sheet.

7 голосов
/ 17 марта 2011

Вы пытались объявить часть ключевого кадра вашего css в элементе <style> в заголовке вашего HTML-документа. Затем вы можете присвоить этому элементу идентификатор или что-то еще и изменить его содержимое в любое время с помощью 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 голосов
/ 18 марта 2011

Что ж, из вашего примера мне кажется, что 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 голосов
/ 16 марта 2011

Я не получил, когда вы хотели изменить эти значения (т.е. использовать переменные), но тем не менее здесь есть 3-4 решения и 1 невозможное решение (на данный момент).

  • вычисление на стороне сервера : чтобы время от времени обслуживать другой CSS, вы можете указать PHP или любому языку на стороне сервера, чтобы он анализировал файлы .css, а также .php или .html, а затемиспользовать переменные PHP между тегами PHP.Остерегайтесь кеширования файлов: чтобы избежать этого, вы можете загрузить таблицу стилей, например style.css? 1234567890, случайное время или файл, который создаст явно другой файл и, следовательно, не будет кэширован

  • SASS - это также решение на стороне сервера, для которого требуется Ruby, и он предоставит вам существующий синтаксис, возможно, более чистый, чем решение, созданное вручную, поскольку другие уже знакомы с проблемами и решениями

  • LESS - это решение на стороне клиента, которое загрузит ваш файл .less и файл less.js, который проанализирует первый файл и предоставит вам переменныев CSS, каким бы ни был ваш сервер.Он также может работать на стороне сервера с node.js

  • CSS, являющийся , динамически изменяемый во время отображения вашей страницы?
    Для 2D есть jquery от Ben-Barnett, 2d-transform или CSS3 rotate - наоборот (они используют CSS3, где это возможно, и там, где таких функций нет, ониоткат к существующим jQuery .animate () и матричному фильтру IE), но это все.
    Вы можете создать плагин для jQuery , который бы управлял несколькими параметрами, чего вы хотите добиться с помощью 3D-трансформации, и избегалхлопоты по модификации длинных и сложных правил CSS в DOM

  • только CSS : вы можете использовать -moz-calc [ 1 ] [ 2 ], который работает только в Firefox 4.0 с -webkit-transform, который работает только в ... OK, неважно: -)

1 голос
/ 16 марта 2011

Решение «Коренастый»?

Создание преобразований для высот в пределах выбранной гранулярности, скажем, 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');

Может быть хорошо, если зернистость не слишком хорошо!

1 голос
/ 25 февраля 2011

Попробуйте что-то вроде этого:

var height = {whatever height setting you want to detect};
element.style.webkitTransform = "translate3d(0px," + height*i + ",0px)";
0 голосов
/ 11 февраля 2012

Я использовал решение 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);

И это прекрасно работает! Теперь я могу динамически изменять расстояние, на которое перемещается текст!

...