programmatically changing webkit-transformation values in animation rules
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);
}
If you want to modify a keyframe rule in a stylesheet that's already included, do the following:
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;
}
}
If you don't know the order but do know the URL of the CSS file, replace document.styleSheets[0]
with document.querySelector("link[href='
your-css-url.css
']").sheet
.
Javascript to change keyframe values in external css sheet (No Inline Style Changes!)
It is possible to change keyframes on loaded stylesheets. Here you have a stack overflow answer from 2011. And here's a link to a recent blog post about it.
Can I pass a value to a CSS function?
My answer: No you can not.
But you can create the whole CSS using PHP. The best bet is to use PHP to generate the entire CSS esp the one you need to modify according to the user settting.
Set the webkit-keyframes from/to parameter with JavaScript
A solution of sorts:
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('@-webkit-keyframes slider {'+
'from { left:100px; }'+
'80% { left:150px; }'+
'90% { left:160px; }'+
'to { left:150px; }'+
'}');
cssAnimation.appendChild(rules);
document.getElementsByTagName("head")[0].appendChild(cssAnimation);
Just adds a style definition to the header. Would be much cleaner/better to define it though the DOM if possible.
Edit: Error in Chrome with old method
Cannot dynamically set initial element translation before transition in same call stack
Because of the computation costs associated with each reflow, most browsers optimize the reflow process by queuing changes and performing them in batches. In this case, you are overwriting the inline style information of the elements, which the browser recognizes. The browser queues the first change and then the second before finally deciding that a reflow should occur, which it does all-at-once. (It doesn't matter that you have separated the changes into two function calls.) This would similarly happen when trying to update any other style property.
You can always force the browser to reflow by using any of the following:
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop, scrollLeft, scrollWidth, scrollHeight
- clientTop, clientLeft, clientWidth, clientHeight
- getComputedStyle() (currentStyle in IE)
So just change your first function to this:
var computedStyles = [];
function setAnimation() {
div1.style.webkitTransform = 'matrix(1,0,0,1,1200,0)';
div2.style.webkitTransform = 'matrix(1,0,0,1,0,0)';
// force div's 1 and 2 to reflow
computedStyles[div1] = div1.clientHeight;
computedStyles[div2] = div2.clientHeight;
}
And now the browser will perform the initial transformations. You don't need two functions to accomplish this, just force the reflow in-between.
Due to some headaches that can occur when trying to solve reflow/repaint issues like this, I always suggest using CSS animations, even if you have to dynamically create and remove style rules from a stylesheet using the CSSOM. Read more here: programmatically changing webkit-transformation values in animation rules
Set Webkit Keyframes Values Using Javascript Variable
Okay, not what your actual code looks like, but you can't throw JavaScript variables into CSS, it won't recognize them.
Instead, you need to create the CSS rules through JavaScript and insert them into the CSSOM (CSS Object Model). This can be done a few ways -- you can either just create a keyframe animation and add it in, or you can overwrite an existing animation. For this sake of this question, I'm going to assume you want to continually overwrite an existing keyframe animation with different rotation values.
I've put together (and documented) a JSFiddle for you to take a look at: http://jsfiddle.net/russelluresti/RHhBz/2/
It starts off running a -10 -> 10 degree rotation animation, but then you can click the button to have it execute a rotation between random values (between -360 and 360 degrees).
This example was hacked together primarily from earlier experimentation done by Simon Hausmann. You can see the source here: http://www.gitorious.org/~simon/qtwebkit/simons-clone/blobs/ceaa977f87947290fa2d063861f90c820417827f/LayoutTests/animations/change-keyframes.html (for as long as that link works, gitorious is pretty bad at maintaining urls).
I've also taken the randomFromTo JavaScript function code from here: http://www.admixweb.com/2010/08/24/javascript-tip-get-a-random-number-between-two-integers/
I've added documentation to the parts of the Simon Hausmann script that I've taken from him (though I've slightly modified them). I've also used jQuery just to attach the click event to my button--all other script is written in native JavaScript.
I've tested this for Chrome 18 and Safari 5.1, and it seems to work fine in both browsers.
Hope this helps.
Change the keyframes value of css with jQuery
You could use a CSS variable and change that:
setTimeout(() => {
console.log("changing");
document.getElementById("fizz").style.setProperty("--foo", "green");
}, 2000);
:root {
--foo: blue;
}
@keyframes hello {
from {
background-color: yellow;
}
to {
background-color: var(--foo);
}
}
#fizz {
height: 1em;
animation: 1s infinite alternate hello;
}
<div id="fizz">
<div>
Clean way to programmatically use CSS transitions from JS?
There isn't a clean way at this moment (without using CSS Animations -- see the nearby answer by James Dinsdale for an example using CSS Animations). There is a spec bug 14617, which unfortunately wasn't acted upon since it was filed in 2011.
setTimeout
does not work reliably in Firefox (this is by design).
I'm not sure about requestAnimationFrame
-- an edit to the original question says it doesn't work reliably either, but I did not investigate. (Update: it looks like requestAnimationFrame
is considered at least by one Firefox core developer to be the place where you can make more changes, not necessarily see the effect of the previous changes.)
Forcing reflow (e.g. by accessing offsetHeight
) is a possible solution, but for transitions to work it should be enough to force restyle (i.e. getComputedStyle
): https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/
window.getComputedStyle(elem).opacity;
Note that just running getComputedStyle(elem)
is not enough, since it's computed lazily. I believe it doesn't matter which property you ask from the getComputedStyle, the restyle will still happen. Note that asking for geometry-related properties might cause a more expensive reflow.
More information on reflow/restyle/repaint: http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
Related Topics
How to Build & Deploy a Samsung Smarttv App Without the Ide (E.G: on Linux)
How to Bind to List of Checkbox Values with Angularjs
If a Dom Element Is Removed, Are Its Listeners Also Removed from Memory
Is It Spread "Syntax" or the Spread "Operator"
Web Worker Settings for Chrome
.Trim() in JavaScript Not Working in Ie
Make Iframe Height Dynamic Based on Content Inside- Jquery/Javascript
Set Keyboard Caret Position in HTML Textbox
Npm Not Installing Returns Error Consistently
Check Whether User Has a Chrome Extension Installed
Read :Hover Pseudo Class with JavaScript
Is "Monkey Patching" Really That Bad
Change Type of Input Field with Jquery
Convert a String to a Template String
Why Can't I Access a Property of an Integer with a Single Dot
Ruby's ||= (Or Equals) in JavaScript
Jquery Selector for Inputs with Square Brackets in the Name Attribute