CSS slide in from left animation - javascript

I'm working on a slideshow and it works, except for the animations. The animation for sliding out works fine but the animation for sliding in from the left does not. The left margin gets set to 0% but there is no animation, even though it is set to -100% at first.
Javascript:
var images = [
'http://i.imgur.com/ByyUANz.png',
'http://i.imgur.com/S5FfOOB.png',
'http://i.imgur.com/EuefPdv.png',
'http://i.imgur.com/Ucvm4pJ.png',
'http://i.imgur.com/pK5WBHN.png',
'http://i.imgur.com/nuOLVpy.png'
]
function slideShow(startAt){
var holder = document.getElementById("currentImage");
var img = document.createElement("img");
img.src = images[startAt];
holder.appendChild(img);
nextPicture(startAt, img);
}
function nextPicture(current, currentElement){
var holder = document.getElementById("currentImage");
setTimeout(function(){
currentElement.className = "translateLeft";
current += 1;
var img = document.createElement("img");
img.src = images[current];
img.style.marginLeft = "-100%";
holder.appendChild(img);
img.className = "translateIn";
if (current == 5){
current = -1;
nextPicture(current, img);
} else {
nextPicture(current, img);
}
}, 5000)
}
slideShow(0);
CSS:
.translateLeft {
transition: 3s;
margin-left: 100% !important;
}
.translateIn {
transition: 3s;
margin-left: 0% !important;
}

Here is a solution for you.
https://jsfiddle.net/smaefwrp/2/
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
html,
body,
img {
position: absolute;
top:0;
left: 0;
margin: 0;
padding: 0;
height: 100%;
overflow-x: hidden;
}
#currentImage {
height: 100%;
width: 1920px;
}
.translateOrigin {
transition: none;
transform: translate3d(-100%, 0, 0) !important;
}
.translateLeft {
transition: transform 3s;
transform: translate3d(100%, 0, 0) !important;
}
.translateIn {
transition: transform 3s;
transform: translate3d(0, 0, 0) !important;
}
</style>
</head>
<body>
<div id="currentImage">
</div>
<div id="buttons">
</div>
<script type="text/javascript">
var images = [
'http://i.imgur.com/ByyUANz.png',
'http://i.imgur.com/S5FfOOB.png',
'http://i.imgur.com/EuefPdv.png',
'http://i.imgur.com/Ucvm4pJ.png',
'http://i.imgur.com/pK5WBHN.png',
'http://i.imgur.com/nuOLVpy.png'
];
var imageEle = [];
var currImage = 0;
var holder = document.getElementById("currentImage");
function imagesPreload() {
for (var i = 0; i < images.length; i++) {
var img = new Image();
img.src = images[i];
img.className = "translateOrigin";
holder.appendChild(img);
imageEle.push(img);
}
}
imagesPreload();
document.onkeydown = function(event){
if(event.keyCode === 13) {
nextPicture();
}
};
function slideShow(startAt) {
var holder = document.getElementById("currentImage");
imageEle[currImage].className = "translateIn";
nextPicture();
}
function nextPicture() {
setTimeout(function () {
var img = imageEle[currImage];
img.addEventListener("transitionend", transitionEnd, false);
img.className = "translateLeft";
if (currImage == 5) {
currImage = 0;
} else {
currImage++;
}
imageEle[currImage].className = "translateIn";
/* Reset the image to original position */
function transitionEnd() {
img.className = "translateOrigin";
img.removeEventListener("transitionend", transitionEnd, false);
nextPicture();
}
}, 5000)
}
slideShow(currImage);
</script>
</body>
</html>

To create a nice slideshow I suggest to use css transform property rather than the margin. The idea is to create the placeholder element currentImage with relative position, and then create all images inside it with position set to absolute. Then by default all images are translated out of the placeholder element, and adding/removing classes show and hide you can place them inside the view and then outside of it, like this:
var images = [
'http://i.imgur.com/ByyUANz.png',
'http://i.imgur.com/S5FfOOB.png',
'http://i.imgur.com/EuefPdv.png',
'http://i.imgur.com/Ucvm4pJ.png',
'http://i.imgur.com/pK5WBHN.png',
'http://i.imgur.com/nuOLVpy.png'
];
// Get the holder
var holder = document.getElementById("currentImage");
// Create the images
images.forEach(function(url) {
var img = document.createElement("img");
img.src = url;
holder.appendChild(img);
});
// Image counter
var counter = 0;
// Slide show interval
var slideshow = setInterval(function() {
// When we reach the end of images we shut down the slide show
// or you can reset the counter to start over
if(counter === images.length) {
clearInterval(slideshow);
return;
}
// Get all images
var nodes = holder.getElementsByTagName("img");
// Hide previous image
if(nodes[counter - 1]) {
nodes[counter - 1].className = "hide";
}
// Show next image
nodes[counter].className = "show";
counter++;
}, 2500);
#currentImage {
background: gray;
width: 300px;
height: 300px;
margin: 0 auto;
position: relative;
overflow: hidden;
}
#currentImage img {
width: 100%;
position: absolute;
transform: translateX(-110%);
-webkit-transition: -webkit-transform 1.0s ease 0s;
-moz-transition: -moz-transform 1.0s ease 0s;
-o-transition: -o-transform 1.0s ease 0s;
transition: transform 1.0s ease 0s;
}
#currentImage img.show {
transform: translateX(0%);
}
#currentImage img.hide {
transform: translateX(110%);
}
<div id="currentImage">
</div>

You can try something like:
// HTML
<div id="currentImage">
<div class="window">
<div class="image-list">
<div>
<img src="http://i.imgur.com/ByyUANz.png" />
</div>
<div>
<img src="http://i.imgur.com/S5FfOOB.png" />
</div>
<div>
<img src="http://i.imgur.com/EuefPdv.png" />
</div>
<div>
<img src="http://i.imgur.com/Ucvm4pJ.png" />
</div>
<div>
<img src="http://i.imgur.com/pK5WBHN.png" />
</div>
<div>
<img src="http://i.imgur.com/nuOLVpy.png" />
</div>
</div>
</div>
</div>
And CSS
// CSS
img {
height: 50px;
width: 50px
}
.window {
position: absolute;
height: 50px;
width: 50px;
border: 2px solid red;
overflow: hidden
}
div {
display: inline-block
}
.image-list {
list-style-type: none;
display: inline-block;
padding-left: 0px;
margin: 0px;
width: 350px;
animation: slidingli 30s ;
}
#keyframes slidingli {
0% {
transform: translateX(0px)
}
16% {
transform: translateX(-50px)
}
32% {
transform: translateX(-100px)
}
48% {
transform: translateX(-150px)
}
64% {
transform: translateX(-200px)
}
80% {
transform: translateX(-250px)
}
100% {
transform: translateX(-300px)
}
}
Checkout this fiddle. Also there are many libraries out there which provide what need For example: http://fotorama.io/customize/autoplay/

Related

Touchscreen Auto Image Slider is showing white space

I am trying to make a touchscreen auto image slider for a landing page and it's somewhat working as it should. However, the image slider sometimes shows white space after a certain amount of scrolls.
Here's the code:
const slides = document.getElementById("slides");
const allSlides = document.querySelectorAll(".slide");
const slidesLength = allSlides.length;
const slideWidth = allSlides[0].offsetWidth;
let index = 0;
let posX1;
let posX2;
let initialPosition;
let finalPosition;
var myTimer;
let canISlide = true;
const prev = document.getElementById("prev");
const next = document.getElementById("next");
const firstSlide = allSlides[0];
const lastSlide = allSlides[allSlides.length - 1];
const cloneFirstSlide = firstSlide.cloneNode(true);
const cloneLastSlide = lastSlide.cloneNode(true);
slides.appendChild(cloneFirstSlide);
slides.insertBefore(cloneLastSlide, firstSlide);
next.addEventListener("click", () => switchSlide("next"));
prev.addEventListener("click", () => switchSlide("prev"));
slides.addEventListener("transitionend", checkIndex);
slides.addEventListener("mouseown", dragStart);
slides.addEventListener("touchstart", dragStart);
slides.addEventListener("touchmove", dragMove);
slides.addEventListener("touchend", dragEnd);
function dragStart(e) {
e.preventDefault();
initialPosition = slides.offsetLeft;
if (e.type == "touchstart") {
posX1 = e.touches[0].clientX;
} else {
posX1 = e.clientX;
document.onmouseup = dragEnd;
document.onmousemove = dragMove;
}
}
function dragMove(e) {
if (e.type == "touchmove") {
posX2 = posX1 - e.touches[0].clientX;
posX1 = e.touches[0].clientX;
} else {
posX2 = posX1 - e.clientX;
posX1 = e.clientX;
}
slides.style.left = `${slides.offsetLeft - posX2}px`;
}
function dragEnd() {
/*
three possibilities:
1. next slide
2. prev slide
3. stay still
*/
finalPosition = slides.offsetLeft;
if (finalPosition - initialPosition < -496) {
switchSlide("next", "dragging");
} else if (finalPosition - initialPosition > 496) {
switchSlide("prev", "dragging");
} else {
slides.style.left = `${initialPosition}px`;
}
document.onmouseup = null;
document.onmousemove = null;
}
function switchSlide(arg, arg2) {
slides.classList.add("transition");
if (canISlide) {
if (!arg2) {
initialPosition = slides.offsetLeft;
}
if (arg == "next") {
slides.style.left = `${initialPosition - slideWidth}px`;
index++;
} else {
slides.style.left = `${initialPosition + slideWidth}px`;
index--;
}
}
canISlide = false;
}
function checkIndex() {
slides.classList.remove("transition");
if (index == -1) {
slides.style.left = `-${slidesLength * slideWidth}px`;
index = slidesLength - 1;
}
if (index == slidesLength) {
slides.style.left = `-${1 * slideWidth}px`;
index = 0;
}
canISlide = true;
}
* {
box-sizing: border-box;
}
.container body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
max-height: 100vh;
}
img {
width: 100%;
height: 100%;
}
.slider {
overflow: hidden;
position: relative;
width: 1080px;
height: 500px;
margin: auto;
}
.slides {
width: 10000px;
display: flex;
position: absolute;
top: 0;
left: -1080px;
cursor: pointer;
}
.slides.transition {
transition: all 0.3s ease-in-out;
}
.slide {
width: 1080px;
height: 500px;
animation: slide 16s infinite;
}
.prev,
.next {
position: absolute;
top: 50%;
transform: translateY(-50%);
color: #f3f3f3;
font-size: 4rem;
}
.next {
right: 2rem;
}
.prev {
left: 2rem;
}
.next:hover, .prev:hover {
transition: 0.2s ease-in-out;
}
.active {
background-color: #ffffff;
-webkit-transition: all 0.4s ease-in-out;
-moz-transition: all 0.4s ease-in-out;
-ms-transition: all 0.4s ease-in-out;
-o-transition: all 0.4s ease-in-out;
transition: all 0.4s ease-in-out;
}
#keyframes slide{
0%{
transform: translateX(0);
}
25%{
transform: translateX(0);
}
30%{
transform: translateX(-100%);
}
50%{
transform: translateX(-100%);
}
55%{
transform: translateX(-200%);
}
75%{
transform: translateX(-200%);
}
80%{
transform: translateX(-300%);
}
100%{
transform: translateX(-300%);
}
}
<div class="container">
<div class="slider">
<div class="slides" id="slides">
<span class="slide">
<a href="#">
<img loading="lazy" src="img.png" alt="" width="100%"></a>
</span>
<span class="slide">
<a href="#">
<img loading="lazy" src="img2.png"></a>
</span>
<span class="slide">
<a href="#">
<img loading="lazy" src="img3-png" width="100%"></a>
</span>
</div>
<a href="#" id="prev" class="prev">❮
<i class="fas fa-caret-left"></i>
</a>
<a href="#" id="next" class="next">❯
<i class="fas fa-caret-right"></i>
</a>
</div>
Of course, I can also just leave out the automatic scrolling, but that isn't quite the goal. The goal is to have the image slider move automatically with a touch function, while working smoothly.
Thank you!

Inline-block remove bottom space to add text

I have the below code to begin an animation for an acronym that makes the code transform to a vertical form. I'd like to have it where it will type the rest of the acronym out next to the letters on the button click. However doing so adds far to much space between all the type I want them to basically line up how they do before the button is pressed you can see what it currently does here:
var a = 0;
var b = 0;
var c = 0;
var d = 0;
var e = 0;
var f = 0;
var balance = 'alance';
var execution = 'xecution';
var teamwork = 'eamwork';
var training = 'raining';
var experience = 'xperience';
var results = 'esults';
var speed = 50;
function typeWriter() {
while (a < balance.length) {
document.getElementById("balance").innerHTML += balance.charAt(a);
a++;
setTimeout(typeWriter, speed);
}
while (b < execution.length) {
document.getElementById("execution").innerHTML += execution.charAt(b);
b++;
setTimeout(typeWriter, speed);
}
while (c < teamwork.length) {
document.getElementById("teamwork").innerHTML += teamwork.charAt(c);
c++;
setTimeout(typeWriter, speed);
}
while (d < training.length) {
document.getElementById("training").innerHTML += training.charAt(d);
d++;
setTimeout(typeWriter, speed);
}
while (e < experience.length) {
document.getElementById("experience").innerHTML += experience.charAt(e);
e++;
setTimeout(typeWriter, speed);
}
while (f < results.length) {
document.getElementById("results").innerHTML += results.charAt(f);
f++;
setTimeout(typeWriter, speed);
}
}
function scroller() {
var move = document.querySelectorAll(".move");
var fade = document.querySelectorAll(".fade");
for (var i = 0; i < move.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = move[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
move[i].classList.add("active");
} else {
move[i].classList.remove("active");
}
}
for (var i = 0; i < fade.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = fade[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
fade[i].classList.add("active");
} else {
fade[i].classList.remove("active");
}
}
}
window.addEventListener("scroll", scroller);
.move {
font-size: 105px;
position: relative;
}
.move.active {
font-size: 105px;
position: relative;
animation: mover 5s ease 0s normal forwards;
}
.fade {
font-size: 105px;
position: relative;
}
.fade.active {
font-size: 105px;
position: relative;
animation: fader 2s ease 0s normal forwards;
}
.move.active span {
margin: 0px;
position: relative;
display: inline-block;
animation: rotate 5s ease 0s normal forwards;
}
#keyframes mover {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(-20%, 300px) skew(0deg) rotate(90deg);
}
}
#keyframes rotate {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(0px, 0px) skew(0deg) rotate(-90deg);
}
}
#keyframes fader {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
opacity: 0;
}
}
#keyframes typing {
0% {
width: 0%
}
100% {
width: 100%
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<CENTER>
<h2 class="fade">IT'S </h2>
<h2 class="move">
<span id="balance">B</span>
<span id="execution">E</span>
<span id="teamwork">T</span>
<span id="training">T</span>
<span id="experience">E</span>
<span id="results">R</span>
</h2>
<h2 class="fade">TOGETHER </h2>
</CENTER>
<button onclick="typeWriter()">Click me</button>
https://noahark.w3spaces.com/saved-from-Tryit-2022-04-29.html
Any and all help will be extremely appreciated.
In your particular example, the spacing is coming from the lengths of the words. When I undo the rotation caused by the animation, we can see this:
So, if you force the length of the word to be one character (regardless of how many characters are actually there), then you no longer have the spacing problem caused by the words' length.
.move span {
display: inline-block;
width: 1.5ch;
}
Although forcing the span's width works, it can feel a little naughty. We're now relying on nice overflow behaviour, and hopefully we don't need the true width of the element for anything else.
I found that I didn't have to force width if we start at the end rather than the beginning. By default (no transform applied), it is already arranged as a column of words exactly like what you want at the end of the animation.
Then, you apply the 90 degree rotation to get the horizontal "BETTER" text. The animation undoes the rotation, meaning you always get what you expect at the end.
const betterAcronym = document.querySelector('#better-acronym')
const revealButton = document.querySelector('#reveal-button')
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const typeElement = async (element) => {
const word = element.dataset['word']
const start = element.textContent.length
for (let c = start; c < word.length; ++c) {
element.textContent += word[c]
await wait(100)
}
}
revealButton.addEventListener('click', async () => {
betterAcronym.classList.add('revealed')
await wait(2750) // length of the animation plus some
Array.from(betterAcronym.children).forEach(typeElement)
})
.acronym {
font-size: 1.25rem;
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
transform: rotate(-90deg);
transform-origin: 0.5em 0.5em;
transition: transform 2.5s ease-in-out;
}
.acronym > li {
display: inline-block;
transform: rotate(90deg);
transform-origin: 0.5em 0.5em;
transition: transform 2.5s ease-in-out;
}
.acronym.revealed {
transform: rotate(0deg);
}
.acronym.revealed > li {
transform: rotate(0deg);
}
body {
overflow: hidden;
}
button {
font-size: 1.25rem;
}
<ol id="better-acronym" class="acronym">
<li data-word="balance">B</li>
<li data-word="execution">E</li>
<li data-word="teamwork">T</li>
<li data-word="training">T</li>
<li data-word="experience">E</li>
<li data-word="results">R</li>
</ol>
<button id="reveal-button">Reveal</button>
You just have to provide width: 73px to .move.active span. And after the animation ends adjust the parent height.
In the demo look for code comments. I've also fixed the typing effect code. View in full page mode.
const move = document.querySelector(".move");
const fade = document.querySelectorAll(".fade");
const words = ['balance', 'execution', 'teamwork', 'training', 'experience', 'results'];
let col = 1;
let row = 0;
const speed = 100;
function typeWriter() {
const e = document.getElementById(words[row]);
e.textContent += words[row][col];
col++;
if(col >= words[row].length){
col = 1;
row++;
}
if(row < words.length)
setTimeout(typeWriter, speed);
else
typeWriter = () => console.log('can not rerun the animation');
}
function scroller() {
var windowHeight = window.innerHeight;
var elementTop = move.getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
move.classList.add("active");
} else {
move.classList.remove("active");
}
for (var i = 0; i < fade.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = fade[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
fade[i].classList.add("active");
} else {
fade[i].classList.remove("active");
}
}
}
// adjust parent height after the animation ends
// change the calculation as per your requirements
move.onanimationend = (event)=>{
if(move === event.target) {
move.parentElement.style.height = move.parentElement.offsetHeight - move.offsetHeight + move.offsetWidth + - move.nextElementSibling.scrollHeight + 'px';
}
};
window.addEventListener("scroll", scroller);
center{ border: 1px dashed gray;}
.move {
font-size: 105px;
position: relative;
}
.move.active {
font-size: 105px;
position: relative;
animation: mover 5s ease 0s normal forwards;
/* we need exact width to adjust the parent's height */
width: fit-content;
}
.fade {
font-size: 105px;
position: relative;
}
.fade.active {
font-size: 105px;
position: relative;
animation: fader 2s ease 0s normal forwards;
}
.move.active span {
margin: 0px;
position: relative;
display: inline-block;
animation: rotate 5s ease 0s normal forwards;
/* specify width equal to one character in the font */
width: 73px;
}
#keyframes mover {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(-20%, 300px) skew(0deg) rotate(90deg);
}
}
#keyframes rotate {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(0px, 0px) skew(0deg) rotate(-90deg);
}
}
#keyframes fader {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
opacity: 0;
}
}
#keyframes typing {
0% {
width: 0%
}
100% {
width: 100%
}
}
button {
position: fixed;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<CENTER>
<h2 class="fade">IT'S </h2>
<h2 class="move">
<span id="balance">B</span>
<span id="execution">E</span>
<span id="teamwork">T</span>
<span id="training">T</span>
<span id="experience">E</span>
<span id="results">R</span>
</h2>
<h2 class="fade">TOGETHER </h2>
</CENTER>
<button onclick="typeWriter()">Click me</button>
Adjust the calculations as per your requirements.

Confetti falling animation problem transparencies

Good evening all,
i added the confetti falling animation to my website.
The confetti are superimposed on my buttons and i can't click them, how can i make the confetti visible but transparent so that i can click what's underneath?
This is the code that i used:
<canvas id="my-canvas"></canvas>
<script src="assets/index.min.js"></script>
<script> var confettiSettings = { target: 'my-canvas' };
var confetti = new ConfettiGenerator(confettiSettings);
confetti.render();
</script>
<style>
#my-canvas
{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 100000;
}
</style>
You can use the pointer-events CSS property to control some aspects of how the pointer interacts with an element. Setting pointer-events: none; will let pointer events (like hover and click) pass right through an element as though it wasn't there. Here's some documentation: pointer-events
here I hope this helps:
index.html
<div class="js-container container"></div>
index.css
#keyframes confetti-slow {
0% { transform: translate3d(0, 0, 0) rotateX(0) rotateY(0); }
100% { transform: translate3d(25px, 105vh, 0) rotateX(360deg) rotateY(180deg); }
}
#keyframes confetti-medium {
0% { transform: translate3d(0, 0, 0) rotateX(0) rotateY(0); }
100% { transform: translate3d(100px, 105vh, 0) rotateX(100deg) rotateY(360deg); }
}
#keyframes confetti-fast {
0% { transform: translate3d(0, 0, 0) rotateX(0) rotateY(0); }
100% { transform: translate3d(-50px, 105vh, 0) rotateX(10deg) rotateY(250deg); }
}
.container {
width: 100vw;
height: 100vh;
background: #f0f0f0;
}
.confetti-container {
perspective: 700px;
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.confetti {
position: absolute;
z-index: 1;
top: -10px;
border-radius: 0%;
&--animation-slow {
animation: confetti-slow 2.25s linear 1 forwards;
}
&--animation-medium {
animation: confetti-medium 1.75s linear 1 forwards;
}
&--animation-fast {
animation: confetti-fast 1.25s linear 1 forwards;
}
}
script file
const Confettiful = function(el) {
this.el = el;
this.containerEl = null;
this.confettiFrequency = 3;
this.confettiColors = ['#fce18a', '#ff726d', '#b48def', '#f4306d'];
this.confettiAnimations = ['slow', 'medium', 'fast'];
this._setupElements();
this._renderConfetti();
};
Confettiful.prototype._setupElements = function() {
const containerEl = document.createElement('div');
const elPosition = this.el.style.position;
if (elPosition !== 'relative' || elPosition !== 'absolute') {
this.el.style.position = 'relative';
}
containerEl.classList.add('confetti-container');
this.el.appendChild(containerEl);
this.containerEl = containerEl;
};
Confettiful.prototype._renderConfetti = function() {
this.confettiInterval = setInterval(() => {
const confettiEl = document.createElement('div');
const confettiSize = (Math.floor(Math.random() * 3) + 7) + 'px';
const confettiBackground = this.confettiColors[Math.floor(Math.random() * this.confettiColors.length)];
const confettiLeft = (Math.floor(Math.random() * this.el.offsetWidth)) + 'px';
const confettiAnimation = this.confettiAnimations[Math.floor(Math.random() * this.confettiAnimations.length)];
confettiEl.classList.add('confetti', 'confetti--animation-' + confettiAnimation);
confettiEl.style.left = confettiLeft;
confettiEl.style.width = confettiSize;
confettiEl.style.height = confettiSize;
confettiEl.style.backgroundColor = confettiBackground;
confettiEl.removeTimeout = setTimeout(function() {
confettiEl.parentNode.removeChild(confettiEl);
}, 3000);
this.containerEl.appendChild(confettiEl);
}, 25);
};
window.confettiful = new Confettiful(document.querySelector('.js-container'));
Here is a link of a Codepen.io: https://codepen.io/jacobgunnarsson/pen/pbPwga

CSS Animation Won't Play Per Click

I built a carousel for some images. I need my 'next' and 'previous' buttons to use the CSS animation that I assigned them in my javascript function for their event listeners.The animation will only play for one click, and when the buttons are clicked again to navigate the carousel the animation doesn't play. I need the buttons to grow and shrink for every click.
Here's the CSS:
.carousel-actions {
position: absolute;
display: flex;
justify-content: space-between;
width: 105%;
top: 30%;
}
.carousel-actions button {
padding: 30px 50px;
background-color: rgba(255, 255, 255, 0.329);
font-weight: 900;
cursor: pointer;
border-radius: 100px;
border: 0;
font-size: 60px;
color: black;
outline: none;
}
#keyframes grow {
0% {
transform: scale(1);
}
50% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
Here's the HTML:
<div class="carousel-actions">
<button id="prev" aria-label="Previous Slide"><</button>
<button id="next" aria-label="Next Slide">></button>
</div>
Here's the JS:
const slides = document.querySelectorAll(".carousel-item");
const totalSlides = slides.length;
let slidePosition = 0;
console.log(totalSlides);
const next = document.getElementById("next");
const prev = document.getElementById("prev");
function hideAllSlides() {
for (const slide of slides) {
slide.classList.remove("carousel-item-visible") &&
slide.classList.add("carousel-item-hidden");
}
}
function nextSlide() {
hideAllSlides();
if (slidePosition === totalSlides - 1) {
slidePosition = 0;
} else {
slidePosition++;
}
slides[slidePosition].classList.add("carousel-item-visible");
next.style.animation = "grow 1s";
}
function prevSlide() {
hideAllSlides();
if (slidePosition === 0) {
slidePosition = totalSlides - 1;
} else {
slidePosition--;
}
slides[slidePosition].classList.add("carousel-item-visible");
prev.style.animation = "grow 1s";
}
next.addEventListener("click", nextSlide);
prev.addEventListener("click", prevSlide);
The problem is seen because once the system has played the animation it thinks 'well, I've played it'. Setting it to the same again does not make it play again.
To get round this you can unset the animation when it has finished.
In your code add an event listener for the animationend event.
Here's a simplified example:
const div = document.querySelector('div');
div.addEventListener('click', function() { div.style.animationName='grow';});
div.addEventListener('animationend', function() { div.style.animationName='';});
div {
width: 100px;
height: 100px;
background-color: blue;
animation-duration: 1s;
animation-iteration-count: 1;
}
#keyframes grow {
0% {
transform: scale(1);
}
50% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
<div></div>

How to make an html div to swiftly move to right (for less than 1 second) and disappear?

I would like to make an html div to swiftly move to right (e.g. for less than 1 second) and disappear. Then appear again directly at the position the div was at the very beginning of this process after 1 second. This process will be triggered by a button click and repeat by 10 times.
I tried to use transition-property in CSS to achieve this, but the result is not what I wanted. The div will directly disappear instead of disappearing after moving to right.
Could it be that what I want to do is impossible to achieve with CSS? If it is the case, what should I use?
The css code:
#box1 {
width: 100px;
height: 100px;
background: red;
-webkit-transition-property: left, right; /* Safari */
-webkit-transition-duration: 2s; /* Safari */
transition-property: left, right;
transition-duration: 2s;
position:absolute;
left: 0;
}
#box1:hover {
transition-delay:1s;
left: 100px;
transition-delay:1s;
opacity:0;
}
Javascript code:
var elem = document.getElementById("box1");
$('#b').click(function(){
var i = 0;
while (i < 10){
setTimeout(function(){
elem.setAttribute("style","left: 1000px;");
}, 500);
setTimeout(function(){
elem.setAttribute("style"," opacity: 0;");
}, 500);
i ++;
}
})
You can achieve this in so many ways :
1-using transition and css jQuery method:
//changing the style of the box using css method of jQuery
var animationDuration = 800;
var animationRepetition = 10;
//this array will be used to clear timeouts if user click while animation still going
var timeoutIds = [];
$("#css_method").click(function() {
for (var i = 0; i < timeoutIds.length; i++) {
clearTimeout(timeoutIds[i]);
}
timeoutIds = [];
for (var i = 0; i < animationRepetition; i++) {
var index = i;
var id1 = setTimeout(function() {
$("#box1").addClass("left-opacity-transition").css({
left: 500,
opacity: 0
});
}, 2 * index * animationDuration)
var id2 = setTimeout(function() {
$("#box1").removeClass("left-opacity-transition").css({
left: 0,
opacity: 1
});
}, ((2 * index) + 1) * animationDuration);
timeoutIds.push(id1, id2);
}
});
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: relative;
left: 0;
}
button {
margin-top: 30px;
}
.left-opacity-transition {
-webkit-transition-property: left, opacity;
/* Safari */
-webkit-transition-duration: .8s;
/* Safari */
transition-property: left, opacity;
transition-duration: .8s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="box1"></div>
<button id="css_method" type='button'>use css method</button>
2-using animate jQuery method :
//using the animate method of jQuery you can remove the transition from style
var animationDuration = 800;
var animationRepetition = 10;
$("#animate_method").click(function() {
var $box1 = $("#box1");
$box1.finish();
for (var i = 0; i < animationRepetition; i++) {
$box1.animate({
left: 500,
opacity: 0
}, 800, function() {
$box1.css({
left: 0,
opacity: 1
});
});
}
});
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: relative;
}
button {
margin-top: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="box1" class="fade-in-left"></div>
<button id="animate_method" type='button'>use animate method</button>
3-using translate in a css class :
//using the translateX you also can change the element position in X axis
var animationDuration = 800;
var animationRepetition = 10;
//this array will be used to clear timeouts if user click while animation still going
var timeoutIds = [];
$("#translate_button").click(function() {
for (var i = 0; i < timeoutIds.length; i++) {
clearTimeout(timeoutIds[i]);
}
timeoutIds = [];
for (var i = 0; i < animationRepetition; i++) {
var index = i;
var id1 = setTimeout(function() {
$("#box1").addClass("transform-opacity-transition translate-fade-left");
}, 2 * index * animationDuration);
var id2 = setTimeout(function() {
$("#box1").removeClass("transform-opacity-transition translate-fade-left");
}, ((2 * index) + 1) * animationDuration);
timeoutIds.push(id1, id2);
}
});
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
button {
position: absolute;
top: 150px;
}
.translate-fade-left {
transform: translateX(500px);
-webkit-transform: translateX(500px);
opacity: 0;
}
.transform-opacity-transition {
-webkit-transition-property: transform, opacity;
/* Safari */
-webkit-transition-duration: .8s;
/* Safari */
transition-property: transform, opacity;
transition-duration: .8s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="box1"></div>
<button id="translate_button" type='button'>use translate</button>

Categories

Resources