As the current time, I have CSS3 Animations being triggered on button click, and all works well. Its an animation to represent the plant life cycle, working in 5 stages, each stage shows an image and corresponding text.
However, if i click stage 1, then stage 2, and want to click stage 1 again to view the supporting text again, whilst hiding the image from stage two, I cannot seem to be able to do it.
JSFiddle for your convinience:
http://jsfiddle.net/YUC3d/
Live View of current stage:
http://www.mattmeadows.info/MFTW2/howplantsgrow.html
Javascript:
$(function() {
$("#stage1").click(function() {
$("#Seed1,#infoBox1").toggleClass("animate")
});
$("#stage2").click(function() {
$("#Seed2,#infoBox2").toggleClass("animate")
});
$("#stage3").click(function() {
$("#Seed3,#infoBox3").toggleClass("animate")
});
$("#stage4").click(function() {
$("#Seed4,#infoBox4").toggleClass("animate")
});
$("#stage5").click(function() {
$("#Seed5,#infoBox5").toggleClass("animate")
});
});
HTML Segment being animated:
<div id="Seed1" class="target">
</div> <!-- end of Seed1 -->
<div id="infoBox1">
Text for stage 1 Text for stage 1 Text for stage 1 Text for stage 1 Text for stage 1
</div>
(There are 5 of these div combinations in total
CSS:
#-webkit-keyframes show
{
0% { opacity: 0; }
100% { opacity: 1; }
}
#Seed1
{
opacity:0;
}
#Seed1.animate
{
-webkit-animation-name: show;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: ease;
-webkit-animation-iteration-count: 1;
-webkit-animation-direction: normal;
-webkit-animation-delay: 0;
-webkit-animation-play-state: running;
-webkit-animation-fill-mode: forwards;
}
#infoBox1
{
width: 400px;
height: 100px;
background:white;
position: absolute;
bottom: 425px;
margin-left: 25px;
border-radius: 10px;
opacity:0;
}
#infoBox1.animate
{
-webkit-animation-name: show;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: ease;
-webkit-animation-iteration-count: 1;
-webkit-animation-direction: normal;
-webkit-animation-delay: 0;
-webkit-animation-play-state: running;
-webkit-animation-fill-mode: forwards;
}
Presuming that 'animate' is the 'on' class (it seems to be), try making a method that resets everything then animate the specific element:
function setStage(stage) {
var numberOfStages = 5;
for (i=1; i <= numberOfStages; i++) {
if (i == stage) {
$("#infoBox" + i).addClass("animate");
$("#Seed" + i).addClass("animate");
} else if (i < stage) {
$("#infoBox" + i).removeClass("animate");
$("#Seed" + i).addClass("animate");
} else {
$("#infoBox" + i).removeClass("animate");
$("#Seed" + i).removeClass("animate");
}
}
}
Example use:
$(document).ready(function() {
$("#stage1").click(function() {
setStage(1);
});
//stage 2,3,5 etc...
$("#stage4").click(function() {
setStage(4);
});
});
Presuming that 'animate' is the 'on' class (it seems to be), try making a method that resets everything then animate the specific element:
function resetState() {
//you can use classes here to make it neater
$("#Seed1,#infoBox1,#Seed2,#infoBox2,#Seed3,#infoBox3,#Seed4,#infoBox4,#Seed5,#infoBox5").removeClass("animate");
}
Example use:
$("#stage1").click(function() {
resetState();
$("#Seed1,#infoBox1").toggleClass("animate");
});
Related
I used "animation-iteration-count: infinite" but it needs to be used of every line separately. I need it to be applied on all lines combined. My code uses separate CSS class for every line which is quite annoying. I need one single class to be applied on whole text no matter how many line or paragraphs there are. Below is my code.
.css-typing p {
font-family: "Courier";
font-size: 14px;
width: 200em;
white-space: nowrap;
overflow: hidden;
-webkit-animation: type 2s steps(40, end);
animation: type 4s steps(40, end);
animation-iteration-count: infinite;
}
.css-typing p:nth-child(2) {
white-space: nowrap;
overflow: hidden;
opacity: 0;
-webkit-animation: type 2s steps(40, end);
animation: type2 4s steps(40, end);
-webkit-animation-delay: 2s;
animation-delay: 5s;
-webkit-animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
}
.css-typing p:nth-child(3) {
white-space: nowrap;
overflow: hidden;
opacity: 0;
-webkit-animation: type 5s steps(40, end);
animation: type3 4s steps(40, end);
-webkit-animation-delay: 3s;
animation-delay: 10s;
-webkit-animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
}
#keyframes type {
from {
width: 0;
}
}
#-webkit-keyframes type {
from {
width: 0;
}
}
span {
animation: blink 1s infinite;
}
#keyframes type2 {
0% {
width: 0;
}
from {
opacity: 0;
}
1% {
opacity: 1;
}
to {
opacity: 1;
}
100% {
opacity: 1;
}
}
#-webkit-keyframes type2 {
0% {
width: 0;
}
from {
opacity: 0;
}
1% {
opacity: 1;
}
to {
opacity: 1;
}
100% {
opacity: 1;
}
}
#keyframes type3 {
0% {
width: 0;
}
from {
opacity: 0;
}
1% {
opacity: 1;
}
to {
opacity: 1;
}
100% {
opacity: 1;
}
}
#-webkit-keyframes type3 {
0% {
width: 0;
}
from {
opacity: 0;
}
1% {
opacity: 1;
}
to {
opacity: 1;
}
100% {
opacity: 1;
}
}
<div class="css-typing">
<p>
Typed <br> text 1
</p>
<p>
Typed text 2
</p>
<p>
Typed text 3
</p>
</div>
I think CSS animation is not the way to go.
If possible, you can actually write the characters to the browser from JS.
From the top of my head you should have:
Text in JS array. each element represents a line.
setInterval that calls a function that pops each time a line
another setInterval or setTimeout that will put each letter there, using substr and keep an index where you are at any given time.
If you don't want to code, google for codepen typing effect, I'm sure you will find something you will like.
I am trying to change the animation-name in (loader--text: after) CSS with the help of js Or Jquery but I am only able to change (content) in CSS not able to change animation-name
I have tried:
code:
$('.loader--text').attr("data-content", "Connection Printer"); // It's Working
$('.loader--text').attr("data-animation", "connecting-text"); // But It's Not working
.loader--text:after {
content: attr(data-content);
font-weight: bold;
animation-name: attr(data-animation);
animation-duration: 3s;
animation-iteration-count: infinite;
}
#keyframes connecting-text {
0% {
content: "Connecting Printer";
}
25% {
content: "Connecting Printer.";
}
50% {
content: "Connecting Printer..";
}
75% {
content: "Connecting Printer...";
}
}
#keyframes fetching-text {
0% {
content: "Fetching Story";
}
25% {
content: "Fetching Story.";
}
50% {
content: "Fetching Story..";
}
75% {
content: "Fetching Story...";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='loader--text'></div>
after some research you can only change the content styling with attr method.
you can take a different approach to the task like turning the :after animation to only the dots and use innerHTML for the dom itself.
exmple:
const loader = document.querySelector(".loader--text");
loader.innerHTML = "Connecting Printer";
function changeText() {
loader.innerHTML = "Fetching Story";
}
.loader--text {
cursor: pointer;
}
.loader--text:after {
content: "";
font-weight: bold;
animation-name: dots;
animation-duration: 3s;
animation-iteration-count: infinite;
}
#keyframes dots {
0% {
content: "";
}
25% {
content: ".";
}
50% {
content: "..";
}
75% {
content: "...";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='loader--text' onclick="changeText()"></div>
you can use attr() in css to pass only string values. animation-name is not a string value
more info : https://css-tricks.com/css-attr-function-got-nothin-custom-properties/
you can change the animation by changing the style.animationName property of the element.
let state = 1;
const square = document.getElementById('square')
document.getElementById('test').addEventListener("click", ()=>{
if(state == 1){
square.style.animationName = "second"
state = 2
} else{
square.style.animationName = "first"
state = 1
}
})
#square{
background: red;
padding: 50px;
width:50px;
height:50px;
/* animation-name: attr(data-animate); */
animation-name: first;
position:absolute;
animation-duration: 2s;
animation-iteration-count: infinite;
}
#keyframes first {
0% {
left: 0
}
100% {
left: 600px;
}
}
#keyframes second {
0% {
top: 0
}
100% {
top: 600px;
}
}
<div id="square" data-animate="first">
</div>
<button id="test">TOGGLE</button>
You can only use attr() for the content attribute in this case.
I'd advise to get rid of jQuery (no hate, I used to love using it), but since you're already using it, you can switch animation name like this:
$('div').css('animation-name', 'anim2');
This of course doesn't apply for pseudo elements (such as :after).
Anyway I think it's much easier to create two separated classes (each one of them applies a different animation) and then just toggle the classes, I think it's much easier to use.
.loader--text.one:after{animation: ...}
.loader--text.two:after{animation: ...}
$('.loader--text').removeClass('one').addClass('two');
I need to chain two animations in my interface HTML/CSS on user event (here just a click on the document). The first animation start correctly, but when I want to restart the second animation nothing move ?
I know if i remove the .rotaiotn class and with a timeout put other animation class for the element, the second animation start from the first position of the element.
I want to know if exist a solution to start the second animation from the position of the blue ball after the first animation ?
document.addEventListener('click', startAnimation, false);
var isFisrtAnim = false;
function startAnimation(evt) {
var elt = document.querySelector('#blue_ball');
if (!isFisrtAnim) {
elt.setAttribute('class', 'rotation');
} else {
elt.setAttribute('class', 'rotation2');
}
elt.addEventListener("animationend", animationAtEnd, false);
}
function animationAtEnd(evt) {
evt.preventDefault();
isFisrtAnim = !isFisrtAnim;
var elt = evt.target;
// todo here get new position of elt to start another animation
// from the new position after first animation
var new_margin_top = window.getComputedStyle(elt).getPropertyValue('margin-top');
var new_margin_left = window.getComputedStyle(elt).getPropertyValue('margin-left');
console.log('At end new margin-top : ' + new_margin_top + ' - new margin-left : ' + new_margin_left);
// positions are the same of start element ? they are not modify ?
}
#circleNav {
background: rgba(215, 229, 231, 0.4) !important;
margin-top: 100px;
margin-left: 120px;
border-radius: 50%;
width: 335px;
height: 335px;
border: 2px solid #0e6694;
}
img {
max-width: 100%;
}
#blue_ball {
position: absolute;
margin-top: -350px;
margin-left: 165px;
width: 70px;
height: 70px;
border: none;
z-index: 5;
transform-origin: 120px 180px;
}
.rotation {
-webkit-animation: rotation 3s linear;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards !important;
}
#-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(240deg);
}
}
.rotation2 {
-webkit-animation: rotation 3s linear;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards !important;
}
#-webkit-keyframes rotation2 {
from {
-webkit-transform: rotate(240deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
<h2>
CLICK ON THE BODY TO START ANIMATION
</h2>
<h4>
When the Blue ball stop click an other time to start second animation, but don't work ?
</h4>
<div id="circleNav"></div>
<div id="blue_ball">
<a href="#">
<img id="btn_menu" src="http://mascaron.net/img/mini_rond_logo.png">
</a>
</div>
smaple code on jsfiddle
thanks in advance.
Just one question, in css:
.rotation2 {
-webkit-animation: rotation 3s linear;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards !important;
}
should not be:
.rotation2 {
-webkit-animation: rotation2 3s linear; /* <----- here, rotation2
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards !important;
}
In js part, why not use elem.classList https://developer.mozilla.org/fr/docs/Web/API/Element/classList to manipulate css class property.
I want to add button to toggle the animation for this fiddle. I have added the following code but I'm not able to toggle (start and stop) the animation.
body .a [class^="b"] {
width: 200px;
height: 142.8571428571px;
margin: 0 auto;
position: relative;
left: 71.4285714286px;
-webkit-transform-origin: bottom left;
transform-origin: bottom left;
border-radius: 100% 300%;
background: radial-gradient(bottom left, transparent 41.4285714286px, #ff0c0c 41.4285714286px, #3f0000 -15px, #ff0c0c 71.4285714286px);
/* -webkit-box-shadow: 71.4285714286px 71.4285714286px 142.8571428571px darkred;*/
box-shadow: 71.4285714286px 71.4285714286px 142.8571428571px rgb(164, 69, 14);
-webkit-animation-duration: 5s;
animation-duration: 0.5s;
-webkit-animation-delay: 1s;
animation-delay: 1s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
demo is here: https://jsfiddle.net/xianshenglu/bjwhm3bf/3/
first,i remove this code to html,and change it's value to stop
<input type="button" id="button" value="stop"></input>
second,i give the button css:
body #button {
z-index:1;
position:absolute;
left:0;
top:0;
}
third,i add this javascript :
document.getElementById('button').addEventListener('click', function() {
var animationPlayStateEle = document.querySelectorAll('.a [class^="b"]');
if (this.value === 'start') {
Array.from(animationPlayStateEle, function(ele) {
ele.style.animationPlayState = 'running';
});
this.value = 'stop';
} else if (this.value === 'stop') {
Array.from(animationPlayStateEle, function(ele) {
ele.style.animationPlayState = 'paused';
});
this.value = 'start';
}
}, false);
then ,job finished;
the core is that,when you click the button and the button's value==='stop',i change this
.a [class^="b"] {
animation-play-state: play;
}
to
.a [class^="b"] {
animation-play-state: paused;
}
in the javascript by change the element's style;
and when you click the button and the button's value==='start',i change this
.a [class^="b"] {
animation-play-state: paused;
}
to
.a [class^="b"] {
animation-play-state: running;
}
clear?
I'm trying to coding this text animation effect (please see video) but i'm quite far from solution!!
Can you please help me? maybe is better using js?
h1.fadeinone { animation: fadeinone 10s;}
h1.fadeintwo { animation: fadeintwo 10s;}
h1.fadeinthree { animation: fadeinthree 10s;}
#keyframes fadeinone {
0% {
opacity: 0;
}
33% { /* 3s for fade in */
opacity: 1;
}
}
#keyframes fadeintwo {
0% {
opacity: 0;
}
66% { /* 3s for fade in */
opacity: 1;
}
}
#keyframes fadeinthree{
0% {
opacity: 0;
}
100% { /* 3s for fade in */
opacity: 1;
}
}
#claim h1 {
font-size: 40px;
line-height:40px;
margin:0px;
padding:0px;
color:#FFF;
}
#claim {background-color:red;}
<div id="claim">
<h1 class="fadeinone">DESIGN</h1>
<h1 class="fadeintwo">loren ipsum</h1>
<h1 class="fadeinthree">DOLOR SIT</h1>
</div>
I think you are looking for the animation-delay property. It's a bit tedious, because you'll have to separate out each letter of each line into its own element (I used span in this case), and then you'll have to manually assign each span its own delay, but the effect matches what you provided.
Also, by using this method, you only need one set of keyframes, because you'll be using the delay to determine when the animation starts, rather than using a percentage over multiple animations.
div span
{
opacity: 0;
animation-name: fadein;
animation-duration: 3s;
animation-fill-mode:forwards;
}
div span:nth-child(1){animation-delay:0s}
div span:nth-child(2){animation-delay:0.2s}
div span:nth-child(3){animation-delay:0.4s}
div span:nth-child(4){animation-delay:0.6s}
div span:nth-child(5){animation-delay:0.8s}
div span:nth-child(6){animation-delay:1s}
#keyframes fadein
{
0%{opacity: 0}
100%{opacity:1}
}
<div>
<span>D</span><span>E</span><span>S</span><span>I</span><span>G</span><span>N</span>
</div>
Of course, you could do this with Javascript and the solution would likely be more elegant and easier to modify; however, then you have to deal with compatibility issues. You're going to be better off just sticking with strict CSS whenever possible.