How to Dynamically Create '@-Keyframe' CSS Animations

How to dynamically create '@-Keyframe' CSS animations?

well i don't think it is easy to create dynamic @keyframes they are inflexible because they must be hard-coded.

Transitions are a little easier to work with, as they can gracefully respond to any CSS changes performed by JavaScript.

However, the complexity that CSS transitions can give you is pretty limited — an animation with multiple steps is difficult to achieve.

This is a problem that CSS @keyframe animations are meant to solve, but they don’t offer the level of dynamic responsiveness that transitions do.

but these links might help you

Link1 : a tool that generates a @-webkit-keyframe animation with many tiny steps. This opens the door to an unlimited selection of easing formula.

Link2 it will be a great help for you to take it as a base as it provides a UI to create animations and exports it to CSS code.

I guess this solution will definitely work for you. Its is used for dynamic keyframes

Dynamically create and apply CSS3 animations

Yes, we can dynamically create, apply and remove CSS3 animations to an element in the page.

To dynamically create an animation, we need to use the insertRule or addRule functions to add the @keyframes rules and append it to the stylesheet. Once the animation is appended, applying it to the element is very simple, we just need to set the required property value to the animation property via inline styles. Removing it agian is very simple, we just need to set the value back to null when it needs to be removed.

In the below snippet, I have first inserted an animation and applied it to the element on load. When the animation starts, the element fires the animationstart event. Within this event listener, I've obtained the outerHTML of the element that is being animated and printed it to show how inline style is present and then at the end of the animation (using the animationend event listener), I've removed the inline style and printed the outerHTML after it to show how it no longer has the animation.

There are no other simpler ways to dynamically create CSS3 animations. All possible solutions will involve creating and appending @keyframes to the stylesheets using basic insertRule, addRule or the keyframes specific appendRule function (which is used to append rules to an existing keyframe).

var elm = document.querySelector('.to-animate');var op = document.querySelector('.output');
var animName = "shake-up-down", animDuration = "3s", animTiming = "linear", animFillMode = "forwards", animIteration = "3";
var ruleText = "0% {transform: translateY(0px);}";ruleText += "25% {transform: translateY(10px);}";ruleText += "75% {transform: translateY(-10px);}";ruleText += "100% {transform: translateY(0px);}";

/* From David Walsh's blog */function addCSSAnimRule(sheet, name, rules, index) { if ("insertRule" in sheet) { sheet.insertRule("@keyframes " + name + "{" + rules + "}", index); } else if ("addRule" in sheet) { sheet.addRule("@keyframes " + name, rules, index); }}
/* Self written */function applyAnimation(elm, name, duration, timing, iteration, fillmode) { elm.style["animation"] = name + " " + duration + " " + timing + " " + iteration + " " + fillmode; /* or if you want to set them individually, comment the above line and uncomment this elm.style["animationName"] = name; elm.style["animationDuration"] = duration; elm.style["animationTimingFunction"] = timing; elm.style["animationIterationCount"] = iteration elm.style["animationFillMode"] = fillmode;*/}
addCSSAnimRule(document.styleSheets[0], animName, ruleText, 0);applyAnimation(elm, animName, animDuration, animTiming, animIteration, animFillMode);
/* to print output */
elm.addEventListener("animationstart", function(e) { op.textContent = "Animation " + e.animationName + " has started."; op.textContent += "\n\nElement's Outer HTML: \n"; op.textContent += elm.outerHTML; op.textContent += "\n\n------------------------------------------------------------------------------";});
elm.addEventListener("animationend", function(e) { elm.removeAttribute("style"); /* remove the animation */ op.textContent += "\nAnimation " + e.animationName + " has ended."; op.textContent += "\n\nElement's Outer HTML: \n"; op.textContent += elm.outerHTML; op.textContent += "\n\n------------------------------------------------------------------------------";});
.to-animate {  height: 100px;  width: 100px;  margin: 10px;  border: 1px solid red;}
<div class='to-animate'></div><pre class='output'></pre>

How to create dynamic Keyframe rules in Javascript?

OK, I think this code would be an aproach of what you need, I'm not sure but if you want more help you can share a picture of what you really want to do (final result).

Remove this rule -webkit-animation-name: 'testA';

.hundredPoints{
background-color: rgba(255,0,0,0.2);
position:absolute;
animation-duration: 6s;
animation-timing-function: ease-in-out;
animation-direction: alternate;
animation-iteration-count: infinite;
width:10px;
height:10px;
border-radius:100%;
}

Assign a specific class to each point point-(ith).

var hundredPointsArray = [];
for (var i = 0; i < 20; i++) {
hundredPointsArray += '<div class="hundredPoints point-' + i + '"></div>';
}

var containerHundredPoints = document.querySelector(".conHundredPoints");
containerHundredPoints.innerHTML = hundredPointsArray;

Create a new animation keyframe for each specific point,
then assign it to each specific class crated before.

for (var i = 0; i < hundredPointsArray.length; i++){
var sheet = document.createElement('style')
var circle = document.querySelectorAll(".hundredPoints");
sheet.textContent = ""+
".hundredPoints.point-" + i + " {" +
"-webkit-animation-name: 'animPoint-" + i + "';" +
"}" +

"@-webkit-keyframes animPoint-" + i + " {" +
"0% { transform:translate(495px, 495px)" +
"rotate(45deg) translate(" + (-i * 4) + "px," + (-i * 4) + "px);" +
"background-color:white;" +
"box-shadow: 0px 0px 5px #000;" +
"}" +

"100% { transform:translate(495px, 495px)" +
"rotate(405deg)" +
"translate(" + (-i * 4) + "px," + (-i * 4) + "px);" +
"background-color:black;" +
"box-shadow: 0px 0px 5px #980;" +
"}";
"}";

circle[i].appendChild(sheet);
}

Here is the complete code

Dynamically adding CSS keyframe from JS to add randomness to animation

The basic question is how to randomly create keyframes for CSS animations and have them loaded at runtime.

The @keyframes definitions cannot be added inline to an element. But you can change the animation name of an element by

el.style.animationName = 'animation'

and you can add style elements to your documents head at runtime. Taking the simple example given in the question here's a snippet to add random y values to an animation and give a piece of rubbish that animation:

const head = document.getElementsByTagName('head')[0];
const btnRubbish = document.querySelector('div.smallrubbish');

let keyframes =
`@keyframes rubbish {
0% {top:` + (Math.random() * 100) + `%; left: 100%;}
50% {top:` + (Math.random() * 100) + `%; left: 50%;}
100% {top:` + (Math.random() * 100) + `%; left: 0%;}`;

let style= document.createElement('STYLE');
style.innerHTML = keyframes;
head.appendChild(style);

btnRubbish.style.animationName = 'rubbish';
div.smallrubbish {
display: block;
height: 50px;
width: 50px;
background-color: rgba(255, 124, 0, 1);
border-radius: 100%;
position: absolute;
top: 50%;
left: 100%;
animation-name: rubbishflow;
animation-duration: 8s;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-delay: 0s;
animation-fill-mode: forwards;
}
<div class="game box"> 
<div class="smallrubbish"></div>
</div>

Continuous animation across dynamically loaded elements

This seems like a problem that might not be solvable with CSS alone. If I understand correctly you want the animation, of the child that is replaced by another child, to start at the point where it the previous animation ended.

You could look into the Web Animations API. As of this moment browser support is not great, but might get better in the future.

It does, however, have the capabilities that you are looking for. As referenced in this article on MDN, it is possible to get the point in time of your animation where it should start from by using the currentTime property of an animation.

// Just like with CSS we use keyframes to create an animation.
const keyframes = [
{
color: 'blue'
},
{
color: 'yellow'
}
];

// Set the timing properties of the animation just like you have in CSS.
const timing = {
duration: 15000,
direction: 'alternate',
iterations: Infinity,
};

// And add it all together.
const currentAnimation = document.querySelector('.child').animate(keyframes, timing);

The code here is the JavaScript equivalent of CSS animations. The color of the .child class will change for as long as the element exists, just like in CSS.

Before you replace a child with a new one you'll want to know where the animation is in terms of time. Get it by accessing the currentTime property as mentioned before.

// Returns the position in time of the animation in milliseconds.
const position = currentAnimation.currentTime;

So now you have the position of the animation. You can use it to set the starting point of the animation on the new element. Just like this:

// Create a new animation
const newAnimation = docum... // You know the drill.

// Update the currentTime with the position of the previous animation.
newAnimation.currentTime = position;

The new animation will start on the position that we stored.

You still need to wrap these examples into functions to use them in your code, but I hope you can figure that out. If the Web Animations API is not something you could use then look for a framework with better support, like GreenSock or AnimeJS. This article also has a list of good alternatives.

Hope this helps and have a nice day!

Dynamically Changing Keyframe CSS Firefox

Turns out it was a refresh issue

// search the CSSOM for a specific -webkit-keyframe rule
function findKeyframesRule(rule) {
// gather all stylesheets into an array
var ss = document.styleSheets;

// loop through the stylesheets
for (var i = 0; i < ss.length; ++i) {

// loop through all the rules
for (var j = 0; j < ss[i].cssRules.length; ++j) {
// find the -webkit-keyframe rule whose name matches our passed over parameter and return that rule
if ((ss[i].cssRules[j].type == window.CSSRule.KEYFRAMES_RULE) && ss[i].cssRules[j].name == rule) return [ss[i], ss[i].cssRules[j]];
}
}

// rule not found
return null;
}

// remove old keyframes and add new ones
function change(anim) {
// find our -webkit-keyframe rule
var results = findKeyframesRule(anim);
var style_sheet = results[0];
var rule = results[1];
console.log(rule)
// remove the existing 0% and 100% rules
rule.deleteRule("0%");
rule.deleteRule("100%");
rule.appendRule("0% { transform: rotate(0deg);}")
rule.appendRule("100% { transform: rotate(" + randomFromTo(-360, 360) + "deg); }")

// create new 0% and 100% rules with random numbers
var box = document.getElementById('box');
// assign the animation to our element (which will cause the animation to run)
box.style.animationName = 'none';
box.offsetWidth = box.offsetWidth;
box.style.animationName = anim;
}

// begin the new animation process
function startChange() {
change("rotate");
}

// get a random number integer between two low/high extremes
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}

$(function () {
$('#update-box').bind('click', click_handler);
});

function click_handler(e) {
e.preventDefault();
startChange();
}

Is the updated working code.

http://jsfiddle.net/RHhBz/675/

The following being the important change

box.style.animationName = 'none';
box.offsetWidth = box.offsetWidth; //This line here is needed to force refresh
box.style.animationName = anim;

Dynamically creating CSS keyframe animation via JavaScript

First, get rid of these moz prefixes everywhere, Firefox supports unprefixed animation since years, so do every browsers. (besides, it's style.MozXXX)

Then, style.animationName should be the animation's name (yes), and your animation is called "pop", not "pop 2s".

2s would be a valid value for style.animationDuration:

var cue = document.createElement('div');cue.setAttribute('id', 'cue');cue.setAttribute(    'style',    'opacity:' + '0;');cue.textContent = "hello";
var cueAnimation = document.createElement('style');cueAnimation.type = 'text/css';var rules = document.createTextNode('@keyframes pop {'+ '0% { opacity:0; }'+ '50% { opacity:1; }'+ '100% { opacity:0; }'+ '}');cueAnimation.appendChild(rules);cue.appendChild(cueAnimation);
appContainer.appendChild(cue);
cue.style.animationName = 'pop';cue.style.animationDuration = '2s';
<div id="appContainer"></div>

generate @-webkit-keyframes CSS dynamically with JavaScript?

Yes, i use Jquery library and then apply like so:

Say in this situation i want the left value to be dynamic from a div with attribute class value = "push"

<!--HTML-->
<div class="push">Wall</div>

//--JS--
var KeyFrame =
{
init: function(){
if(!KeyFrame.check)
{
//get the left position
var pushLeft = $('.push').position().left;
//set the style and append to head
var css = $('<style>@keyframes mymove{from {left:0px;}to {left:'+pushLeft+'px;}}</style>').appendTo('head'); //make sure you don't carriage return the css inline statement, or else it'll be error as ILLEGAL
//so u don't keep appending style to head
KeyFrame.check = true;
}
}
}
KeyFrame.init();


Related Topics



Leave a reply



Submit