I am working on a simple css animation for webkit. A number of elements will slide in and then unfold.
My idea is to keep to have a single css animation and trigger it by adding the slideIn class with jquery.
.slideIn {
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: 1;
-webkit-animation-fill-mode: forwards;
-webkit-animation-name: slideIn;
clip: rect(0,125px,315px,0);
}
#-webkit-keyframes slideIn {
0% { -webkit-transform: translateX(0); }
50% { -webkit-transform: translateX(-700px); clip: rect(0,125px,315px,0); }
100% { -webkit-transform: translateX(-700px); clip: rect(0,550px,315px,0); }
}
As I mentioned, there are more than one item on the page and I want them to slide in one by one. So I need to add the slideIn class one by one, with somtehing like:
var pref = "animated";
var animClass = "slideIn";
var eNumber = 5;
var interval = 10000;
animateMultiple(pref, eNumber, interval, animClass);
function animateMultiple(pref, eNumber, interval, animClass) {
var i = 0;
function addAnimClass() {
i++;
$('#' + pref + i).addClass(animClass);
if(i < eNumber){
setTimeout(addAnimClass(), interval);
}
}
addAnimClass ();
}
Yet, this ends in all the element sliding in alltogether.
Why does not the interval have any effect?
setTimeout(addAnimClass(), interval);
You are (immediately) calling addAnimClass and passing its return value (undefined) to setTimeout.
Remove the ().
Related
I have a JavaScript function that types out, letter by letter, a message. However, where the current character to be typed is located, I have a blinking css animation. What I need is to stop this animation and make it disappear.
I am using a css with #id::after to put the animation after the text in question. The animation works fine, I need a way to set content: '█'; to content: ''; via JavaScript.
(function type_p(){
let msg = 'This is a message to type out! Spooky!';
let element = document.getElementById('typehere');
typeOut(msg, '', 0, element);
}());
function typeOut(text, letter, index, element){
letter = text.slice(0, ++index);
element.textContent = letter;
if (letter.length == text.length){
stop();
}
setTimeout(typeOut, 100, text, letter, index, element);
}
#typehere {
position: relative;
}
#typehere::after {
content: '█';
position: absolute;
animation: blink 1.5s infinite;
/* animation-iteration-count: 2; */
}
#keyframes blink {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
51% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<p id="typehere">Here</P>
I am aware of CSS animation-iteration-count: however this will stop the animation but it will still be visible (motionless). How do I remove this?
I would just add a class to your element and change the content based on class.
(function type_p(){
let msg = 'This is a message to type out! Spooky!';
let element = document.getElementById('typehere');
typeOut(msg, '', 0, element);
}());
function typeOut(text, letter, index, element){
letter = text.slice(0, ++index);
element.textContent = letter;
if (letter.length == text.length){
element.classList.add('stop');
stop();
}
setTimeout(typeOut, 100, text, letter, index, element);
}
#typehere {
position: relative;
}
#typehere::after {
content: '█';
position: absolute;
animation: blink 1.5s infinite;
/* animation-iteration-count: 2; */
}
#typehere.stop::after {
content: '';
}
#keyframes blink {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
51% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<p id="typehere">Here</P>
This is similar to the other answer, but I find it easier/cleaner than adding multiple classes to something that will no longer be visible.. You can add the animation styling as a class, and then remove that class when you no longer want it to animate.
Change to class in css:
.typehereclass::after {
content: '█';
position: absolute;
animation: blink 1.5s infinite;
}
Add the class to your element in html:
<p id="typehere" class="typehereclass">Here</P>
And then when you want to stop the blinking in JS:
element.classList.remove('typehereclass')
So I want to change the width of a span element inside a h1 element that have the textContent changed every 4s with setInterval().I want to do that to add a transition to the width property to fill the space between the h1 and the next word that span will have smoothly.
I tried to get the width of the span with getBoundingClientRect() but that didn't work and when I set the width it remains the width of the first element and it's not changed dynamically as I would want.
Here is the code:
const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
setInterval(function() {
count++;
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
if(count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.style.width = `${elementWidth}px`;
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span {
display: inline-block;
color: #c82929;
transition: width .2s ease;
}
.animation-span {
animation: moveDown .8s ease;
}
#keyframes moveDown {
0% {opacity: 0;
transform: translateY(-50%);
}
100% {
transform: translateY(0);
}
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>
consider an animation using max-width:
const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
setInterval(function() {
count++;
if (count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span {
display: inline-block;
color: #c82929;
}
.animation-span {
animation: moveDown .8s ease;
}
#keyframes moveDown {
0% {
opacity: 0;
transform: translateY(-50%);
max-width:0;
}
100% {
transform: translateY(0);
max-width:200px; /* a big value here */
}
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>
Your code is very good.
But you need to remove 2 rows like below, then you code works well as you want
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
changingSpan.style.width = ${elementWidth}px;
So the answer was posted by Sean above(Thank you). I will put here the code snippet for this in case somebody will search for something similar and will want to do the same thing:
const changingSpan = document.querySelector('.changing-span');
const changingSpanWrapper = document.querySelector('.changing-span-wrapper');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
changingSpanWrapper.style.width = `${changingSpan.getBoundingClientRect().width.toString()}px`;
setInterval(function() {
count++;
if(count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.addEventListener('animationstart', function() {
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
let elementHeight = changingSpan.getBoundingClientRect().height.toString();
changingSpanWrapper.style.width = `${elementWidth}px`;
changingSpanWrapper.style.height = `${elementHeight}px`;
})
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span-wrapper {
display: inline-block;
transition: width .2s ease, height .2s ease;
}
.changing-span {
display: inline-block;
color: #c82929;
}
.animation-span {
animation: moveDown 1s ease;
}
#keyframes moveDown {
0% {opacity: 0;
transform: translateY(-50%);
}
100% {
transform: translateY(0);
}
}
<h1 class="first-heading">The <span class="changing-span-wrapper"><span class="changing-span">best</span></span> burgers in town.</h1>
I'm trying to optimize my code so that I can cycle through images on a splash page quickly and effectively. I've got it looking really smooth on chrome and safari but when I view the splash page on mobile and firefox it bugs out big time
A demo can be found at http://theotherchrisrock.com
I would love to hear your input on how to fix this. Here is the relevant code:
var i = 0
var j = 0
var l = $('.se-pre-con > div').length - 2;
var $pre_con = $('.se-pre-con');
var $di_sum = $('.splash-image:last-child');
var $img_array = [];
for (t = 0; t < l; t++) {
$img_array[t] = $('.splash-image-' + t);
}
function flashanimation() {
if (i < l) {
$img_array[i].addClass('flash');
i++;
flashloop();
} else if (j != 1) {
$di_sum.addClass('di-some');
j = 1
flashloop();
} else {
$pre_con.addClass('nun');
}
}
function flashloop() {
setTimeout(function() {
flashanimation();
}, 300)
}
$(".blinker").removeClass("blinker");
flashloop();
Basically, the goal is to make the image appear for 150ms and then disappear for 150ms and then next image appears and so on finally ending with just a black div. Right now I'm adding a class to each div which triggers this keyframe animation ~
.splash-image.flash {
-webkit-animation:flash 0.15s linear;
animation:flash 0.15s linear;
-webkit-animation-delay:0.15s;
animation-delay:0.15s;
display:block;
opacity:0;
}
#-webkit-keyframes flash {
0% {
opacity:0;
}
1% {
opacity: 1;
}
100% {
opacity:1;
}
}
#keyframes flash {
0% {
opacity:0;
}
1% {
opacity: 1;
}
100% {
opacity:1;
}
}
I would love to hear your input. Thank u for reviewing my question
Assume I have the following array:
var myarray = [1, 2, 3, 4, 5]
What is the cleanest way using Javascript/CSS3 to make it such that onpage load, each element in the array is shown in a box/div with a red background color on the page? Usually I would just do:
for(var i = 0; i < myarray.length; i++) {
bodyelement.append("<div class="box">"+myarray[i]+"</div>");
}
The issue is, it is super fast and they all just show up instantaneously without any real "effect".
Though how do I make them "sequentially" animate in as it is appended? Say, for example, the box would animate say from a overly big box and shrink down to the size of the actual div, or fade in gradually. Can this be done with CSS3 only or is there javascript required? How can I create this effect?
Here is an example of what I described in the comments. JSFIDDLE.
Basically you use css transitions, and add a class to each element after a certain period of time.
(function() {
var elements = document.querySelectorAll("#test div");
for (var i = 0; i < elements.length; i++) {
load(elements[i], i);
}
function load(elem, i) {
setTimeout(function() {
elem.classList.add("load");
},50 * i);
}
}());
CSS
#test div {
-webkit-transition: opacity 2s ease-in;
-moz-transition: opacity 2s ease-in;
-ms-transition: opacity 2s ease-in;
-o-transition: opacity 2s ease-in;
transition: opacity 2s ease-in;
}
#test div.load {
opacity: 1;
}
This FIDDLE may get you started.
JS
var fadeintime = 500;
animatediv();
function animatediv()
{
var number = 0;
var interval = setInterval(function() {
var divid = $("#div" + number);
divid.animate({opacity: "1"}, fadeintime);
number++;
if(number > 4) clearInterval(interval);
}, 1000);
}
Based on THIS.
I have a group of divs that share the same class (optionsclass). The display is set to block. When a user clicks them the following javascript function is executed the display is changed to none.
function hideBlockElementsByClass(className)
{
var elements = document.getElementsByClassName(className);
for(i in elements)
{
elements[i].style.display = "none";
}
}
The transition between display block and none is quite rough and I would like to make a smoother transition. What's the best strategy to accomplish this?
Use CSS3 :
.className {
opacity: 0;
visibility: hidden;
-webkit-transition: visibility 0.2s linear,
opacity 0.2s linear;
-moz-transition: visibility 0.2s linear,
opacity 0.2s linear;
-o-transition: visibility 0.2s linear,
opacity 0.2s linear;
}
.className:hover {
visibility: visible;
opacity: 1;
}
While Sridhar gives a nice CSS3 solution and other mention Jquery.
Here you can find a pure javascript/CSS solution:
https://codereview.stackexchange.com/questions/7315/fade-in-and-fade-out-in-pure-javascript
Try this method
HTML
<div class = "image" onclick = "eff()"></div>
CSS
.transition {
-moz-transition: 2s width;
width: 150px;
height: 100px;
}
Script
function eff() {
var k = document.getElementsByClassName("image");
k[0].className = "transition";
}
try this in plain javascript:(Will work on IE10, chrome, firefox, safari, android, ios)
<script>
function hideBlockElementsByClass(className) {
var elements = document.getElementsByClassName(className);
console.log(elements.length)
for (var i = 0; i < elements.length; i++) {
(function (a) {
elements[a].addEventListener('webkitTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('mozTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('oTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('transitionend', function () {
elements[a].style.display = "none";
}, false);
})(i);
elements[i].style.webkitTransitionDuration = "1s";
elements[i].style.mozTransitionDuration = "1s";
elements[i].style.oTransitionDuration = "1s";
elements[i].style.transitionDuration = "1s";
elements[i].style.opacity = "0";
}
}
</script>