I have a question, it is possible to set dynamic variable or change variable from JS in post-css?
I have react component and inside css3 animation, I want set dynamic delay for each animation individually for each component.
I found similar solution, that I can pass property and read it from css for example JS code:
<div className={style.component} delay={5}>
and I can read it in CSS but only like if statement:
&[delay="5"] {
animation: show 0.1s linear forwards 5s;
}
and it works!
but I want something like:
animation: show 0.1s linear forwards [delay]s; //dynamic delay value here
it is possible?
Cheers
Just pass the dynamic value '5' as a prop like this:
const App = (props) => {
return (
<div className={style.component} style={{animation: "show 0.1s linear forwards " + (props.delayStyle + 's')}}>
// Div Content Here
</div>
)
};
ReactDOM.render(<App delayStyle='5' />, document.getElementById('someDiv'));
CodePen: https://codepen.io/andrewl64/pen/dKzzaJ
Related
Using Angular and Ionic, I have created an app that uses Firebase subscribe methods to retrieve data. I have created an animation that loops through divs repeated in a *ngFor to create a animation delay and use keyframes to change each divs opacity from 0 to .5 to 1.
#neededfoodnames {
animation: fadeIn 0.5s linear;
animation-fill-mode: both;
}
// Set delay per List Item
#for $i from 1 through 100 {
#neededfoodnames:nth-child(#{$i}) {
animation-delay: .25s * $i;
}
}
// Keyframe animation
#-webkit-keyframes fadeIn {
0% {
opacity: 0;
}
75% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
However, because I am using Firebase's subscribe methods to listen for changes, each time an item is updated, the animation is triggered again for that item.
I'd like this animation to only happen on load and not when a change is made to items.
I have tried using an ngClass based on a boolean. On load I have set the boolean to true to fire the animation but I have also created a setTimeout() method to change the boolean to false after a designated time.
HTML:
<div id="neededfoodnames" *ngFor="let list of lists; let i = index" [ngClass]="{'neededfoodnames':animate == true}">
...
</div>
TypeScript:
export class HomePage {
lists: FirebaseListObservable<any[]>;
animate: boolean;
constructor() {
this.animate = true;
setTimeout(() => {
this.animate = false
}, 4000);
}
}
The CSS was also updated to use neededfoodnames as a class instead of a id.
Using this method, I currently have the setTimeout()'s milliseconds hardcoded. If I continue with this method, I will need to find a way to dynamically set the milliseconds.
I have created an example on Stackblitz of what I'm wanting to achieve, however it is only working because it is not retrieving the data from Firebase.
Is there a better way to trigger this animation only on load and not when data changes? Or is finding and setting the setTimeout()'s milliseconds my best option?
I am appending new HTML on a load more button, like this:
function addStuff() {
$.get('page-partials/more-stuff.html', function(stuff) {
$('#load-button').append(stuff);
});
};
The trouble is that this new content is being put into a container (with a dynamic height), which I want to animate down when more things are added. For this reason, I need to add a dynamic class to divs inside 'more-stuff.html', each time that template is added again.
Eg:
<div class='stuff added1'></div>
And then the next time it's added:
<div class='stuff added2'></div>
Etc. Is this possible? Otherwise, does anyone know of a solution to animate height changes from an undetermined non-zero number to another undetermined non-zero number?
What about
var count = 0;
$.get('page-partials/more-stuff.html', function(stuff) {
count++;
$('#load-button').append(stuff).addClass('stuff added'+count);
});
Actually vivek mentioned a better approach but that has to be something like this:
var stuff = '<div style="height:200px;">Dynamically appended div</div>'; // ajax response
var h = $(stuff).height();// find out the height of it.
$('.stuff').append(stuff).css('height', h); // after append just update the height.
.stuff {
height:60px;
width:100px;
border:2px solid #f00;
-webkit-transition: height 0.8s ease-in-out;
-moz-transition: height 0.8s ease-in-out;
-o-transition: height 0.8s ease-in-out;
transition: height 0.8s ease-in-out; /* <------css3 transition to animate the height */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='stuff'></div>
Try chaining added function to each call to addStuff
function addStuff() {
// `return` jQuery promise object from `addStuff`
return $.get('page-partials/more-stuff.html', function(stuff) {
$('#load-button').append(stuff);
});
};
var added = function() {
$(".stuff").each(function(index) {
$(this).addClass("added" + index + 1)
})
}
addStuff().then(added);
I have a block which content is being dynamically changed by script and I want that content not to change instantly, but fade out and then fade in with new content.
I want that done without jQuery — pure JS and CSS.
I am trying to do this in such a way:
I've defined transparent and opacle classes in CSS with transition set to 2s, and wanna toggle that classes for block with content when the content changes. As I expect it should smoothly fade out old content and fade in new content. But in fact content just changes instantly.
CSS:
.non-opacle {
opacity:0;
transition: opacity 2s linear;
}
.opacle {
opacity:1;
transition: opacity 2s linear;
}
HTML
<div class="alert alert-info" id="wrapper">
<p id="text-box">…</p>
</div>
JS
var textBox = document.getElementById('text-box');
window.onload = function () {
var failCounter = 0;
var current = notes[Math.floor(Math.random() * 12)];
textBox.className = 'opacle';
textBox.innerHTML = '…';
function keyClicked(event) {
if (event.target.className.split(' ')[1] === current) {
textBox.className = 'non-opacle';
textBox.innerHTML = '*some altered content*';
textBox.className = 'opacle';
…
In JS I initially set content wrapper block to 'opacle' class with initial content, and then on certain conditions, I set it to 'non-opacle', change block's innerHTML to place relevant content, and set the class back to 'opacle'.
But no animation occurs( What am I doing wrong?
Your problem is that you're adding and removing the opacity at the same time, before the initial transition has had time to complete.
What you need to do is delay the changing of the innerHTML and resetting of the opacity until the transition has completed.
Here's a very simple looping example to illustrate the principle, the important part to note is the setTimeout.
var p=document.getElementById("change"),text=["One","Two","Three","Four","Five"],x=0,interval=setInterval(function(){
x++;if(x===text.length)x=0;
p.classList.add("hide");
setTimeout(function(){
p.innerHTML=text[x];
p.classList.remove("hide");
},500);
},2000);
#change{
color:#000;
font-family:arial;
padding:5px;
transition:opacity .5s linear;
}
.hide{
opacity:0;
}
<p id="change">One</p>
The browser is not going to wait for transitions to complete before setting the class back to opacle.
This simple working fiddle moves the transition out to a separate selector, and uses a transitionend event listener, to wait for the element to be completely faded out before changing the content and fading it back in.
http://jsfiddle.net/0m3Lpwxo/1/
CSS:
.opacle {
opacity:1;
}
.non-opacle {
opacity:0;
}
#test {
transition: opacity 1s linear;
}
html:
<div id="test" class="non-opacle">this is content</div>
<button onclick="toggle()">toggle</button>
js:
function transitionEnded() {
var el = document.getElementById('test');
el.innerHTML = "hello.";
el.classList.remove('non-opacle');
}
function toggle() {
var el = document.getElementById('test');
el.addEventListener("transitionend", transitionEnded, true);
el.classList.add('non-opacle');
}
You probably just need to define browser specific styles along side your current definition (for example: -webkit-transition: opacity 2s linear;)
Also, I would say that instead of adding the transition redundantly to both classes, target something about your element that's not going to change, like its ID and define the transition style rules there. That way you will keep your CSS more DRY.
Here's the best reference material for dealing with CSS transitions: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Try this:
<div id="myElement">Text</div>
function fadeOut(id,val){
if(isNaN(val)){ val = 9;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val--;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{return;}
}
function fadeIn(id,val){
if(isNaN(val)){ val = 0;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{return;}
}
Referred from this.
I have used following JS:
function change(){
var d = document.getElementById("div");
d.className = d.className + " non-opacle";
setTimeout(function(){
d.className = "opacle";
d.innerHTML = "TEST";
},1000);
}
See following DEMO, with CSS:
.opacle {
opacity:1;
transition: opacity 1s linear;
}
.non-opacle {
opacity:0;/* No need to add transaction here */
}
How are you?
This is from a previous post and a solution was posted.
JS :
$(document).ready(function() {
var allBoxes = $("div.boxes").children("div");
transitionBox(null, allBoxes.first());
});
function transitionBox(from, to) {
function next() {
var nextTo;
if (to.is(":last-child")) {
nextTo = to.closest(".boxes").children("div").first();
} else {
nextTo = to.next();
}
to.fadeIn(500, function() {
setTimeout(function() {
transitionBox(to, nextTo);
}, 5000);
});
}
if (from) {
from.fadeOut(500, next);
} else {
next();
}
}
JSFIDDLE HERE
However I was trying to extend this a bit, where when box 1 fades out, you can see box 2 fading in slightly at the same time - simultaneously, and as box2 fades out ...box 3 is fading in at the same time with the opacity going from 0 to 1
I'm fine and you? :') .
I have a solution that maybe can help.
Have you tried making 1 class named display and setting display: block; and then put it on the function as toggleClass(). Finally you make a new class named as .transition(I do this with all my project to make them easier) and put it on the div or add it with some code like: $("div").addClass("transition");.
the code for .transition should be like this:
.transition {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
You can also try insted of CSS and jQuery using only CSS.
an example could be using CSS Animations. Define the class of every box and then make a animation and add a delay on every animation so it will show every certain time, make them infinite so the will loop.
Hope you understand :)
Editing line 14 of your jsFiddle to add a delay created a smoother effect so you don't see two at once. Which I surmise is the answer to the question.
Line 14 edits: to.delay(100).fadeIn(500, function () {
I'm animating a div. It has the following definition:
<div ng-show="showTranslations" ng-swipe-right="showTranslationsBlock=false">...</div>
I have the following css defined:
div.ng-hide {
transition: 0.5s linear opacity;
opacity: 0;
}
div.ng-hide-add,
div.ng-hide-remove {
/* this needs to be here to make it visible during the animation
since the .ng-hide class is already on the element rendering
it as hidden. */
display:block!important;
}
This is taken from this tutorial. The animation works. But:
Why do I need these classes .ng-hide-add and .ng-hide-remove?
Why I don't see them added to div's classes?
Why there are also classes ng-hide-add-active and ng-hide-remove-active?
Why there is no transition when the div becomes visible although I've added the following css rule:
div.ng-hide-remove {
opacity: 1;
}
UPDATE
As I can see from the table provided by google's tutorial these classes are added to trigger animation frame (this performs a reflow). Is my understanding correct? Why is animation frame is mentioned there?
I tried to increase the transition period but it didn't add the classes. I didn't see the classes ng-hide-add-active and ng-hide-remove-active added either.
As I understand from the table these are the classes that trigger transition?
UPDATE1
I've explored the Angular's source code and found the following for the ng-hide directive:
var ngHideDirective = ['$animate', function($animate) {
return function(scope, element, attr) {
scope.$watch(attr.ngHide, function ngHideWatchAction(value){
$animate[toBoolean(value) ? 'addClass' : 'removeClass'](element, 'ng-hide');
});
};
}];
As I understand the ng-hide class is added through animation service. But what happens if I don't use animations and $animate service is not available? How Angular is going to handle this situation given the code above and how it is going to add ng-hide class? Or is this $animate.addClass() simply adds a callback to addClass event?
Put your CSS transition on ng-hide-remove, ng-hide-remove-active:
div.ng-hide-remove {
transition: 0.5s linear opacity;
opacity: 0;
}
div.ng-hide-remove-active {
opacity: 1;
}
Similarly, for ng-hide-add and ng-hide-add-active:
div.ng-hide-add {
transition: 0.5s linear opacity;
opacity: 1;
}
div.ng-hide-add-active {
opacity: 0;
}