I've been searching everywhere for answers but can't find the results. I have tried queryselect, queryselectall, getelementbytagname, etc. etc. but again nothing happens.
what I am trying to do is get the can element nested in the bootstrap 4 carousel. The idea is instead of pic of a can displaying in the browser and then move to the next slide on autoplay which will then show another pic of a can I want to show a 3d-effect of the can rotating in the screen. I have done the rotating of the can by javascript in a different file but now having troubles to fit it in bootstrap 4 carousel.
const clickFn = () => {
const $bottleSize = getElement('.carousel>.carousel-inner>.carousel-item>.can');
const $bottle1 = changeBottleSize();
const $bottle2 = changeBottleSize();
const $bottle3 = changeBottleSize();
here I have tried everything to change the getElement('') like ('.can') or ('.carousel .carousel-inner .carousel-item .can') and other stuff.
const getElement = (selector) => document.querySelector(selector);
here i change it to querySelectorAll or getElementById like const getElement = () => document.getElementById("#can");, etc. etc.
again no changes. And what I notice is when I have it querySelectorAll console displays a message saying
bootstrap-can.html:251 Uncaught TypeError: $can.append is not a function
at initApp (bootstrap-can.html:251)
at bootstrap-can.html:254
really don't know what I am doing wrong here
CSS
html,
body {
width: 100%;
height: 100%;
}
.container {
position: relative;
}
.bottle:hover {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(350px, 190px, 40px) scale(0.5);
}
.bottle {
transition: all 0.2s;
width: 10.125px;
-webkit-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(650px, 190px, 40px);
-moz-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(650px, 190px, 40px);
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(350px, 190px, 40px);
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
transform: scale(0.1);
position: absolute;
}
.bottle0 {
top: 100px;
left: 300px;
}
.bottle1 {
top: 100px;
left: 500px;
}
.bottle2 {
top: 100px;
left: 700px;
}
.bottle>img {
position: absolute;
top: -180px;
left: -182px;
width: 374px;
}
.label {
-webkit-animation: spin 50s infinite linear;
-moz-animation: spin 50s infinite linear;
animation: spin 50s infinite linear;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
}
.side {
position: absolute;
width: 10.55px;
height: 679px;
margin-bottom: 400px;
}
.bottle0 .side {
background: url("https://i.postimg.cc/BZ8rj2NM/sleve.png");
}
/* .bottle1 .side {
background: url("https://i.postimg.cc/Fs2RgnN6/passion.png");
}
.bottle2 .side {
background: url("https://i.postimg.cc/zGzJjm40/raspberry.png");
} */
#-webkit-keyframes spin {
from {
-webkit-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(-360deg);
transform: rotateY(-360deg);
}
}
#-moz-keyframes spin {
from {
-moz-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-moz-transform: rotateY(-360deg);
transform: rotateY(-360deg);
}
}
#keyframes spin {
from {
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(-360deg);
-moz-transform: rotateY(-360deg);
transform: rotateY(-360deg);
}
}
#mixin makeSide() {}
HTML
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<!-- <img class="d-block w-50" src="amor2.png" alt="First slide"> -->
<div class="container"></div>
</div>
<div class="carousel-item">
<!-- <img class="d-block w-50" src="amor2.png" alt="Second slide"> -->
<div class="container"></div>
</div>
<div class="carousel-item">
<!-- <img class="d-block w-50" src="amor2.png" alt="Third slide"> -->
<div class="container"></div>
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
JS
const getElement = (selector) => document.querySelector(selector);
const createElement = (tag) => document.createElement(tag);
// const addBackground1 = document.style['background'] = 'url ("https://i.postimg.cc/BZ8rj2NM/sleve.png")';
const addSideStyle = ($side, i) => {
let deg = 3.75 * i;
let bgPosition = 972 - (i * 10.125);
$side.style['background-position'] = bgPosition + 'px 0';
$side.style['-webkit-transform'] = 'rotateY(' + deg + 'deg) translateZ(154px)';
$side.style['-moz-transform'] = 'rotateY(' + deg + 'deg) translateZ(154px)';
$side.style['transform'] = 'rotateY(' + deg + 'deg) translateZ(154px)';
};
const createBottle = () => {
const $bottle = createElement('div');
$bottle.classList.add('bottle');
const $bottleLabel = createBottleLabel();
for (let i = 0; i < 96; i = i + 1){
let $bottleSide = createBottleSide(i);
$bottleLabel.append($bottleSide);
}
$bottle.append($bottleLabel);
return $bottle;
};
const createBottleLabel = () => {
const $bottleLabel = createElement('div');
$bottleLabel.classList.add('label');
return $bottleLabel;
}
const createBottleSide = (i) => {
const $bottleSide = createElement('div');
$bottleSide.classList.add('side');
addSideStyle($bottleSide, i);
return $bottleSide;
};
const changeBottleSize = (clickFn) => {
const _bottle = createElement('div');
_bottle.classList.add('bottle');
_bottle.style['transform'] = 'scale(0.9)';
return _bottle;
}
const clickFn = () => {
const $bottleSize = getElement('.carousel>.carousel-inner>.carousel-item>.can');
const $bottle1 = changeBottleSize();
const $bottle2 = changeBottleSize();
const $bottle3 = changeBottleSize();
$bottleSize.style['transform'] = 'scale(0.9)';
return $bottleSize;
}
const initApp = () => {
const $can = getElement('.carousel>.carousel-inner>.carousel-item>.can');
const $bottle1 = createBottle();
const $bottle2 = createBottle();
const $bottle3 = createBottle();
[$bottle1, $bottle2, $bottle3].forEach(($bottle, i) => {
$bottle.classList.add('bottle' + i);
});
$can.append($bottle1, $bottle2, $bottle3);
};
initApp();
Related
There are sliders on my site. Which keeps sliding using functions and setTimeout. I am currently trying to make my slider freeze on mouse hover. But adding an event listener to the slides doesn't seem to work. What can be the best possible solution?
//quote slider
let qslideIndex = 0;
let qslides = document.getElementsByClassName("quotemySlides");
let qdots = document.getElementsByClassName("quotedot");
//hiding each image through loop
const qhidenLoop = ()=>{
let j;
for (j = 0; j < qslides.length; j++) {
qslides[j].style.display = "none";
}
}
//running the slide
const qautoslideRun = ()=>{
qslideIndex++;
if (qslideIndex > qslides.length) {
qslideIndex = 1;
}
qhidenLoop();
qslides[qslideIndex-1].style.display = "block";
}
qshowSlides();
//all slide functions running here
function qshowSlides() {
qautoslideRun();
setTimeout(qshowSlides, 10000); // Change image every 10 seconds
}
.quoteslideshow-container {
max-width: 40%;
position: relative;
margin: 5% auto 5% auto;
}
.quotemySlides {
display: none;
}
/* Fading + slide in animation */
.slideinfromleft {
animation: slideinfromleft 1.5s ease-in 0s 1 normal forwards;
}
.image {
transition: border, border-radius 1s linear;
}
.image:hover {
border-radius: 20%;
border: 2px solid black
}
#keyframes slideinfromleft {
0% {
-webkit-transform: translateX(-100%);
-moz-transform: translateX(-100%);
-o-transform: translateX(-100%);
-ms-transform: translateX(-100%);
opacity: 0.1;
}
50% {
opacity: .5
}
100% {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-o-transform: translateX(0);
-ms-transform: translateX(0);
opacity: 1
}
}
<body>
<div class="container">
<div class="quote">
<div class="quoteslideshow-container">
<!-- Full-width images with number and caption text -->
<div class="quotemySlides slideinfromleft">
<img class="image" src="img/quote1.png" style="width:100%">
</div>
<div class="quotemySlides slideinfromleft">
<img class="image" src="img/quote2.png" style="width:100%">
</div>
<div class="quotemySlides slideinfromleft">
<img class="image" src="img/quote3.png" style="width:100%">
</div>
<div class="quotemySlides slideinfromleft">
<img class="image" src="img/quote4.png" style="width:100%">
</div>
</div>
<br>
</div>
</div>
<script src="tribute.js" type="text/javascript"></script>
<script src="quotetribute.js" type="text/javascript"></script>
</body>
Use a variable to hold setTimeout into it, on mouseover slide clear it, on mouseleave call function slider() again, I change timeout to 3 seconds for test hover.
on mouseleave I call function qshowSlides() after 1 second by setTimeout, you can call it without setTimeout or increase time for setTimeout
//quote slider
let qslideIndex = 0;
let qslides = document.getElementsByClassName("quotemySlides");
let qdots = document.getElementsByClassName("quotedot");
let timeoutHolder = null;
//hiding each image through loop
const qhidenLoop = ()=>{
let j;
for (j = 0; j < qslides.length; j++) {
qslides[j].style.display = "none";
}
}
//running the slide
const qautoslideRun = ()=>{
qslideIndex++;
if (qslideIndex > qslides.length) {
qslideIndex = 1;
}
qhidenLoop();
qslides[qslideIndex-1].style.display = "block";
}
qshowSlides();
//all slide functions running here
function qshowSlides() {
qautoslideRun();
timeoutHolder = setTimeout(qshowSlides, 3000); // Change image every 3 seconds for test hover
}
const disableAutoSlideOnHover = () => {
const container = document.querySelector( ".quoteslideshow-container" );
container.addEventListener( "mouseover", function() {
clearTimeout( timeoutHolder );
timeoutHolder = null;
} );
container.addEventListener( "mouseleave", function() {
setTimeout( () => qshowSlides(), 1000 )
} );
}
disableAutoSlideOnHover();
.quoteslideshow-container {
max-width: 40%;
position: relative;
margin: 5% auto 5% auto;
}
.quotemySlides {
display: none;
}
/* Fading + slide in animation */
.slideinfromleft {
animation: slideinfromleft 1.5s ease-in 0s 1 normal forwards;
}
.image {
transition: border, border-radius 1s linear;
}
.image:hover {
border-radius: 20%;
border: 2px solid black
}
#keyframes slideinfromleft {
0% {
-webkit-transform: translateX(-100%);
-moz-transform: translateX(-100%);
-o-transform: translateX(-100%);
-ms-transform: translateX(-100%);
opacity: 0.1;
}
50% {
opacity: .5
}
100% {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-o-transform: translateX(0);
-ms-transform: translateX(0);
opacity: 1
}
}
<body>
<div class="container">
<div class="quote">
<div class="quoteslideshow-container">
<!-- Full-width images with number and caption text -->
<div class="quotemySlides slideinfromleft">
<img class="image" src="https://images.unsplash.com/photo-1497215728101-856f4ea42174?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" style="width:100%">
</div>
<div class="quotemySlides slideinfromleft">
<img class="image" src="https://images.unsplash.com/photo-1586227740560-8cf2732c1531?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1261&q=80" style="width:100%">
</div>
<div class="quotemySlides slideinfromleft">
<img class="image" src="https://images.unsplash.com/photo-1659944975073-453265ccf3a6?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" style="width:100%">
</div>
<div class="quotemySlides slideinfromleft">
<img class="image" src="https://images.unsplash.com/photo-1659830686710-9c6df95f8cf3?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1176&q=80" style="width:100%">
</div>
</div>
<br>
</div>
</div>
<script src="tribute.js" type="text/javascript"></script>
<script src="quotetribute.js" type="text/javascript"></script>
</body>
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!
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
I searched for how to chain Animista CSS animations with JavaScript to slide out a tab and slide in a new one. I couldn't find anything but I did find this post on chaining animations using Promises.
I modified the code to slide in and out a container for use in tabs.
// We can declare a generic helper method for one-time animationend listening
let hideElement = (el, animation) => {
return new Promise(resolve => {
const onAnimationEndCb = () => {
el.classList.remove('active', animation);
el.removeEventListener('animationend', onAnimationEndCb);
resolve();
}
el.classList.add(animation);
el.addEventListener('animationend', onAnimationEndCb)
});
}
let showElement = (el, animation) => {
return new Promise(resolve => {
const onAnimationEndCb = () => {
el.classList.remove(animation);
el.removeEventListener('animationend', onAnimationEndCb);
resolve();
}
el.classList.add('active', animation);
el.addEventListener('animationend', onAnimationEndCb)
});
}
let hide_box_one = async () => {
const el = document.getElementById('div_one');
await hideElement(el, 'slide-out-top');
}
let show_box_two = async () => {
const el = document.getElementById('div_two');
await showElement(el, 'slide-in-top');
}
let hide_box_two = async () => {
const el = document.getElementById('div_two');
await hideElement(el, 'slide-out-top');
}
let show_box_one = async () => {
const el = document.getElementById('div_one');
await showElement(el, 'slide-in-top');
}
let change_tabs = async () => {
await hide_box_one();
await show_box_two();
await hide_box_two();
await show_box_one();
await hide_box_one();
await show_box_two();
await hide_box_two();
await show_box_one();
await hide_box_one();
await show_box_two();
await hide_box_two();
await show_box_one();
}
const btn = document.getElementById('btn');
btn.onclick = function() {
change_tabs().then(() => console.log('tabs changed'));
};
#div_one {
width: 50px;
height: 50px;
border: 10px solid red;
display: none;
}
#div_one.active{
display:block;
}
#div_two {
width: 50px;
height: 50px;
border: 10px solid blue;
display: none;
}
#div_two.active{
display:block;
}
#btn{
margin-top:10px;
border: 2px solid black;
background: #fff;
padding: 15px;
}
.slide-in-top {
-webkit-animation: slide-in-top 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-top 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
.slide-out-top {
-webkit-animation: slide-out-top 0.6s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
animation: slide-out-top 0.6s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
}
/* ----------------------------------------------
* Generated by Animista on 2020-8-22 19:10:58
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: #cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-in-top
* ----------------------------------------
*/
#-webkit-keyframes slide-in-top {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#keyframes slide-in-top {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#-webkit-keyframes slide-out-top {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
100% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
}
#keyframes slide-out-top {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
100% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
}
<div id="div_one" class="active"></div>
<div id="div_two"></div>
<button id="btn" type="button">Next Tab</button>
enter code here
I've got code:
<div class="wrap2" id="wrap" data-num="0">
<span>0</span><span>1</span>...
CSS:
.wrap2[data-num="0"] {
transfom:translate(0, 0);
}
.wrap2[data-num="1"] {
transform:translate(0, -30px);
}
https://jsfiddle.net/9t4zsuov/2/
But i want to act like a odometer - numbers have to roll only to top, not bottom. Any ideas, how to do that ?
As #codyThompsonDev said, a rollover area is the best way to implement this. Something I think he missed though, is what happens when you go from a rollover number to a non-rollover number.
For example, let's say that the odometer randomly tries to roll to 4, then 3, then 1. The first time, it can roll to 4 no problem. The second time, it has to roll to "13", in the rollover zone. But then, it tries to roll to "11" which is also in the rollover zone, causing it to roll backwards.
To achieve this effect under those circumstances, you must snap the dial back out of the rollover zone, then roll forward again. I would implement this using window.requestAnimationFrame().
I've made a fiddle to demonstrate this: https://jsfiddle.net/tprobinson/8k125fmz/67/
Add the debugBackground class to dupa2 to see the rollover effect visually.
I would recommend generating the CSS classes with a preprocessor like Sass, as writing them by hand can be error prone as well.
document.getElementById("rand").addEventListener("click", randomize);
const debug = document.getElementById("debug");
const dupa = document.getElementById("cipa");
let animationInProgress = null
function setDebug(num) {
debug.textContent = 'Number is really: ' + num
}
function animateOdometer(newNum) {
// Add the smooth class and set the number to let it roll.
dupa.classList.add('smooth')
setDebug(newNum)
dupa.dataset.num = newNum
// In 1000 ms, remove the smooth class
animationInProgress = window.setTimeout(() => {
dupa.classList.remove('smooth')
animationInProgress = null
}, 1000)
}
function randomize() {
let oldNum = Number.parseInt(dupa.dataset.num)
if (oldNum === undefined || oldNum === null) {
oldNum = 0
}
let newNum = Math.floor(Math.random() * 9) + 0;
// If an animation is already in progress, cancel it
if (animationInProgress) {
window.clearTimeout(animationInProgress)
dupa.classList.remove('smooth')
animationInProgress = null
}
// If the new number is before our old number
// we have to force a roll forwards
if (newNum < oldNum) {
newNum += 10
}
if (oldNum > 9) {
// The dial was already rolled over. We need to
// snap the dial back before rolling again.
// Wait for a frame so we can snap the dial back
dupa.dataset.num = oldNum - 10
setDebug(oldNum - 10)
dupa.classList.remove('smooth')
window.requestAnimationFrame(() => {
// Wait for one frame to let the snapback happen
window.requestAnimationFrame(() => {
// Then roll forward
animateOdometer(newNum)
})
})
return
}
// Roll the dial
animateOdometer(newNum)
}
#rand,
#debug {
margin-top: 50px;
}
.dupa1 {
height: 30px;
width: 30px;
border: 1px solid #000;
overflow: hidden;
}
.dupa2.smooth {
transition: all 1s ease;
}
.dupa2 span {
height: 30px;
width: 30px;
display: block;
text-align: center;
line-height: 30px;
}
.dupa2.debugBackground {
background: linear-gradient(to bottom, #ffffff 0%, #ffffff 50%, #207cca 51%, #207cca 100%);
}
.dupa2[data-num="0"] {
transform: translate(0, 0);
}
.dupa2[data-num="1"] {
transform: translate(0, -30px);
}
.dupa2[data-num="2"] {
transform: translate(0, -60px);
}
.dupa2[data-num="3"] {
transform: translate(0, -90px);
}
.dupa2[data-num="4"] {
transform: translate(0, -120px);
}
.dupa2[data-num="5"] {
transform: translate(0, -150px);
}
.dupa2[data-num="6"] {
transform: translate(0, -180px);
}
.dupa2[data-num="7"] {
transform: translate(0, -210px);
}
.dupa2[data-num="8"] {
transform: translate(0, -240px);
}
.dupa2[data-num="9"] {
transform: translate(0, -270px);
}
.dupa2[data-num="10"] {
transform: translate(0, -300px);
}
.dupa2[data-num="11"] {
transform: translate(0, -330px);
}
.dupa2[data-num="12"] {
transform: translate(0, -360px);
}
.dupa2[data-num="13"] {
transform: translate(0, -390px);
}
.dupa2[data-num="14"] {
transform: translate(0, -420px);
}
.dupa2[data-num="15"] {
transform: translate(0, -450px);
}
.dupa2[data-num="16"] {
transform: translate(0, -480px);
}
.dupa2[data-num="17"] {
transform: translate(0, -510px);
}
.dupa2[data-num="18"] {
transform: translate(0, -540px);
}
.dupa2[data-num="19"] {
transform: translate(0, -570px);
}
<div class="dupa1">
<div class="dupa2" id="cipa" data-num="0">
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
</div>
</div>
<div id="debug">
Number is really: 0
</div>
<button id="rand">rand</button>
You can use two sets of numbers and a little bit of extra javascript to achieve this effect.
If the new number is less than the current number, use a second set of numbers (digits 0-9) that are farther down. As the css animation transitions from the first set of numbers to the second, it will appear as if the odometer is "rolling over".
When the animation completes, switch back to the first set of numbers without animating (no transition class).
I've made a working example based off of your original jsfiddle.
NOTE: This makes use of the .classList property of DOM elements, and the tranistionend event. You may have to add vendor prefixes (i.e. webkitTransitionEnd) and implement your own version of .classList, depending on what browsers you need to support.
document.getElementById("rand").addEventListener("click", randomize);
document.getElementById("cipa").addEventListener("transitionend", transitionEnd);
function randomize() {
setNumber(Math.floor(Math.random() * 9));
}
function setNumber(newNumber) {
let dupa = document.getElementById("cipa");
// assumes dupa.dataset.num always be a valid int
let selected = parseInt(dupa.dataset.num);
if (newNumber === selected) return; // if same as existing, don't do anything
// if the new number is less than the old number
// use the second set of numbers to avoid moving "backwards"
if (newNumber < selected) dupa.classList.add("rolledover");
// animate to the new position
dupa.classList.add("transitioning");
dupa.dataset.num = "" + newNumber;
}
function transitionEnd() {
let dupa = document.getElementById("cipa");
// don't animate
dupa.classList.remove("transitioning");
dupa.classList.remove("rolledover");
}
#rand {
margin-top: 50px;
}
.dupa1 {
height: 30px;
width: 30px;
border: 1px solid #000;
overflow: hidden;
}
.dupa2.transitioning {
transition: all 1s ease;
}
.dupa2 span {
height: 30px;
width: 30px;
display: block;
text-align: center;
line-height: 30px;
}
.dupa2[data-num="0"] {
transform: translate(0, 0);
}
.dupa2[data-num="1"] {
transform: translate(0, -30px);
}
.dupa2[data-num="2"] {
transform: translate(0, -60px);
}
.dupa2[data-num="3"] {
transform: translate(0, -90px);
}
.dupa2[data-num="4"] {
transform: translate(0, -120px);
}
.dupa2[data-num="5"] {
transform: translate(0, -150px);
}
.dupa2[data-num="6"] {
transform: translate(0, -180px);
}
.dupa2[data-num="7"] {
transform: translate(0, -210px);
}
.dupa2[data-num="8"] {
transform: translate(0, -240px);
}
.dupa2[data-num="9"] {
transform: translate(0, -270px);
}
.rolledover.dupa2[data-num="0"] {
transform: translate(0, -300px);
}
.rolledover.dupa2[data-num="1"] {
transform: translate(0, -330px);
}
.rolledover.dupa2[data-num="2"] {
transform: translate(0, -360px);
}
.rolledover.dupa2[data-num="3"] {
transform: translate(0, -390px);
}
.rolledover.dupa2[data-num="4"] {
transform: translate(0, -420px);
}
.rolledover.dupa2[data-num="5"] {
transform: translate(0, -450px);
}
.rolledover.dupa2[data-num="6"] {
transform: translate(0, -480px);
}
.rolledover.dupa2[data-num="7"] {
transform: translate(0, -510px);
}
.rolledover.dupa2[data-num="8"] {
transform: translate(0, -540px);
}
.rolledover.dupa2[data-num="9"] {
transform: translate(0, -570px);
}
<div class="dupa1">
<div class="dupa2" id="cipa" data-num="0">
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
</div>
</div>
<button id="rand">rand</button>
Thank you a lot.
But I stuck in another problem similar, but with array.
I've made a fiddle for better view to the problem: https://jsfiddle.net/zr2dLbge/
<div class="wrap" id="wrap"></div>
.wrap{
border:1px solid #000;
display: inline-block;
height:30px;
border-right: none;
}
.numbers{
width:30px;
height:30px;
display:inline-block;
overflow: hidden;
border-right: 1px solid #000;
}
.numbers span{
display: block;
width:30px;
height:30px;
line-height: 30px;
text-align: center;
}
.numbers[data-num="0"] div{
transform: translate(0, 0);
transition: all 1s ease;
}
.numbers[data-num="1"] div{
transform: translate(0, -30px);
transition: all 1s ease;
}
.numbers[data-num="2"] div{
transform: translate(0, -60px);
transition: all 1s ease;
}
.numbers[data-num="3"] div{
transform: translate(0, -90px);
transition: all 1s ease;
}
.numbers[data-num="4"] div{
transform: translate(0, -120px);
transition: all 1s ease;
}
.numbers[data-num="5"] div{
transform: translate(0, -150px);
transition: all 1s ease;
}
.numbers[data-num="6"] div{
transform: translate(0, -180px);
transition: all 1s ease;
}
.numbers[data-num="7"] div{
transform: translate(0, -210px);
transition: all 1s ease;
}
.numbers[data-num="8"] div{
transform: translate(0, -240px);
transition: all 1s ease;
}
.numbers[data-num="9"] div{
transform: translate(0, -270px);
transition: all 1s ease;
}
let arr = [];
var numbers = 1234561234;
const wrap = document.getElementById("wrap");
function toArray (val) {
return (val).toString().split('');
}
arr = toArray(numbers);
for (let i = 0; i < arr.length; i++) {
div = document.createElement('div'),
div.className = "numbers";
div.dataset.num = arr[i];
div.dataset.x = i;
div.innerHTML = "<div><span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span></div>"
wrap.appendChild(div);
}
setInterval(function(){
arr.forEach( (k) => {
arr[k] = Math.floor(Math.random() * 9) + 0;
})
for (let i = 0; i < arr.length; i++) {
document.querySelector('.numbers[data-x="'+i+'"]').dataset.num = arr[i];
}
}, 1000);
unfortunately window.requestAnimationFrame() doesn't work for me in this case