I have 3 moving objects with my keyframe:
#keyframes rotation {
0% {
transform: rotateY(0deg)
}
10% {
transform: rotateY(55deg)
}
30% {
transform: rotateY(55deg)
}
60% {
transform: rotateY(230deg)
}
80% {
transform: rotateY(230deg)
}
100% {
transform: rotateY(360deg)
}
}
this moves my object ->
css:
.object{
position: relative;
margin: auto;
height: 300px;
width: 300px;
-webkit-transition: -webkit-transform 2s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform 2s linear;
-moz-transform-style: preserve-3d;
transition: transform 2s linear;
transform-style: preserve-3d;
transform: rotateY(230deg);
}
.cb2 {
animation: rotation 20s infinite linear;
}
Now I want the first object to spin once then when it's done the second one should spin, when the second one is done the third one should spin.
I tried something like this:
setTimeout(function() {
$("#first").addClass('cb2');
}, 10000);
setTimeout(function() {
$("#first").removeClass('cb2');
}, 16500);
setTimeout(function() {
$("#second").addClass('cb2');
}, 16600);
setTimeout(function() {
$("#second").removeClass('cb2');
}, 29900);
setTimeout(function() {
$("#third").addClass('cb2');
}, 30100);
First of all, that doesn't really work, because it's not really smooth but the main problem is, that this will do the job once, but I want to loop this.
Is that possible ?
HTML:
<div id="container">
<div id="thrdcb" class="position-absolute displayres" style="top:100px;left: 10%;bottom:0;pointer-events: none;">
<div class="container">
<div class="row mt-5">
<div class="col">
<div data-index="7" data-chapter="1" data-names="opacity,margin-left" data-start-values="0,-10px" data-end-values="1,0" data-delay="1000" style="opacity: 0;" class="wontainer">
<div class="navbar"></div>
<div class="news-grid">
<div class="news-card">
<div id="firstcube" class="object">
<div class="face one">
<p id="firstnewssub" style="position: relative; background-color: #a3ba1e; padding: 10px;">
</p>
</div>
<div class="face two">
<p id="firstnewssub2" style="position: relative; background-color: #a3ba1e; padding: 10px;">
</p>
</div>
<div class="face three">
<img src="data/img/testasdd.png" alt="" />
<p id="aaaae" style="position: relative; background-color: #a3ba1e; padding: 10px;">
</p>
</div>
<div class="face four">
<img src="data/img/asddfff.png" alt="" />
<p id="firstnews2" style="position: relative; background-color: #a3ba1e; padding: 10px;">
</p>
</div>
</div>
<a id="rrzuii" href="https://example.com" target="_blank" rel="noopener noreferrer" data-index="7" data-chapter="1"
data-names="opacity, pointer-events" data-start-values="0, none" data-end-values="1, all" data-delay="1000" style="opacity: 0; margin-left: 0px;text-align: center; cursor: pointer;display: none;" class="asdz7">
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="scndcb" class="position-absolute displayres" style="top:100px;right: 10%;bottom:0;pointer-events: none;">
<div class="container">
<div class="row mt-5">
<div class="col">
<div data-index="7" data-chapter="1" data-names="opacity,margin-left" data-start-values="0,-10px" data-end-values="1,0" data-delay="1000" style="opacity: 0;" class="wontainer">
<div class="news-grid">
<div class="news-card">
<div id="thirdcube" class="object">
<div class="face one">
<p id="lppzz" style="position: relative; background-color: #62798b; padding: 10px;">
</p>
</div>
<div class="face two">
<p id="iottt" style="position: relative; background-color: #62798b; padding: 10px;">
</p>
</div>
<div class="face three">
<img src="data/img/asdaqqqqq.png" alt="" />
<p id="thirdnews1" style="position: relative; background-color: #62798b; padding: 10px;">
</p>
</div>
<div class="face four">
<img src="data/img/uthhase.png" alt="" />
<p id="thirdnews2" style="position: relative; background-color: #62798b; padding: 10px;">
</p>
</div>
</div>
<a id="aaklptt" href="https://example.com" target="_blank" rel="noopener noreferrer" data-index="7" data-chapter="1" data-names="opacity, pointer-events"
data-start-values="0, none" data-end-values="1, all" data-delay="1000" style="opacity: 0; margin-left: 0px;text-align: center; cursor: pointer;display: none;" class="-blue">
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="cubepointer" class="position-absolute displayres" style="top: 100px; left: 20%; right: 20%; bottom: 0px;pointer-events: none;">
<div class="container">
<div class="row mt-5">
<div class="col">
<div data-index="7" data-chapter="1" data-names="opacity,margin-left" data-start-values="0,-10px" data-end-values="1,0" data-delay="1000" style="opacity: 0;" class="wontainer">
<div class="news-grid">
<div class="news-card">
<div id="secondcube" class="object">
<div class="face one">
<p id="dghh" style="position: relative; background-color: #e07a0c; padding: 10px;">
</p>
</div>
<div class="face two">
<p id="aas" style="position: relative; background-color: #e07a0c; padding: 10px;">
</p>
</div>
<div class="face three">
<img src="data/img/adasd.png" alt="" />
<p id="ffss" style="position: relative; background-color: #e07a0c; padding: 10px;">
</p>
</div>
<div class="face four">
<img src="data/img/testm.png" alt="" />
<p id="zz" style="position: relative; background-color: #e07a0c; padding: 10px;">
</p>
</div>
</div>
<a id="rdda" href="https://example.com" target="_blank" rel="noopener noreferrer" data-index="99" data-chapter="1" data-names="opacity, pointer-events" data-start-values="0, none" data-end-values="1, all"
data-delay="9999" style="opacity: 0; margin-left: 0px;text-align: center; cursor: pointer;display: none;" class="font-weight font">
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You can make use of the animation event. In your case the animation is defined as animation: rotation 20s infinite linear;, so to stop the animation and start the next you need to look for the animationiteration event.
I wrapped the elements in a <div> for the event listener. At the same time this wrapper can be used for finding the next element to animate.
const container = document.getElementById('container');
//container.addEventListener('animationend', e => {
container.addEventListener('animationiteration', e => {
$(e.target).removeClass('cb2');
let next = e.target.parentElement.querySelector(`div#${e.target.id}~div.object`);
if(next){
$(next).addClass('cb2');
}else{
$(e.target.parentElement.querySelector(`div.object`)).addClass('cb2');
}
});
// initiate animation
$(container.querySelector(`div.object`)).addClass('cb2');
#keyframes rotation {
0% {
transform: rotateY(0deg)
}
10% {
transform: rotateY(55deg)
}
30% {
transform: rotateY(55deg)
}
60% {
transform: rotateY(230deg)
}
80% {
transform: rotateY(230deg)
}
100% {
transform: rotateY(360deg)
}
}
.object {
position: relative;
margin: auto;
height: 100px;
width: 100px;
-webkit-transition: -webkit-transform 2s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform 2s linear;
-moz-transform-style: preserve-3d;
transition: transform 2s linear;
transform-style: preserve-3d;
transform: rotateY(230deg);
}
.cb2 {
animation: rotation 20s infinite linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="first" class="object">A</div>
<div id="second" class="object">B</div>
<div id="third" class="object">C</div>
</div>
Update
The first example assumes that all the div.object elements are siblings. The following example is showing how div.object elements can be in a nested structure. In this case there is a need for a variable objects that hold all the div.objects. The selection of the next element happens based on the index of the current element in the array.
const container = document.getElementById('container');
const objects = container.querySelectorAll('.object');
container.addEventListener('animationiteration', e => {
$(e.target).removeClass('cb2');
let currentIndex = [...objects].indexOf(e.target);
let next = objects[currentIndex+1];
if(next){
$(next).addClass('cb2');
}else{
$(objects[0]).addClass('cb2');
}
});
// initiate animation
$(objects[0]).addClass('cb2');
#keyframes rotation {
0% {
transform: rotateY(0deg)
}
10% {
transform: rotateY(55deg)
}
30% {
transform: rotateY(55deg)
}
60% {
transform: rotateY(230deg)
}
80% {
transform: rotateY(230deg)
}
100% {
transform: rotateY(360deg)
}
}
.object {
position: relative;
margin: auto;
height: 100px;
width: 100px;
-webkit-transition: -webkit-transform 2s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform 2s linear;
-moz-transform-style: preserve-3d;
transition: transform 2s linear;
transform-style: preserve-3d;
transform: rotateY(230deg);
}
.cb2 {
animation: rotation 20s infinite linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div>
<div id="first" class="object">A</div>
</div>
<div>
<div id="second" class="object">B</div>
</div>
<div>
<div id="third" class="object">C</div>
</div>
</div>
While it is theoretically possible to do this in CSS, using one set of keyframes and the animation-delay CSS property, there is a possibility that timings could get out of step, as pointed out in a comment (depending for example how busy the system is with other things).
This snippet therefore sets the animation going for one cycle on the first object, listens for when that animation ends, removes the animation and puts it onto the next object and so on. That way it is guaranteed to keep in step sequentially, even if things get a little delayed sometime.
const objects = document.querySelectorAll('.objects > *');
const num = objects.length;
let n = 0;
objects.forEach(object => {
object.addEventListener('animationend', function() {
object.classList.remove('cb2');
n = (n + 1) % num;
objects[n].classList.add('cb2');
});
});
objects[n].classList.add('cb2');
#keyframes rotation {
0% {
transform: rotateY(0deg)
}
10% {
transform: rotateY(55deg)
}
30% {
transform: rotateY(55deg)
}
60% {
transform: rotateY(230deg)
}
80% {
transform: rotateY(230deg)
}
100% {
transform: rotateY(360deg)
}
}
.objects>* {
position: relative;
margin: auto;
height: 300px;
width: 300px;
-webkit-transition: -webkit-transform 2s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform 2s linear;
-moz-transform-style: preserve-3d;
transition: transform 2s linear;
transform-style: preserve-3d;
transform: rotateY(230deg);
}
.objects>*:nth-child(1) {
background: cyan;
}
.objects>*:nth-child(2) {
background: magenta;
}
.objects>*:nth-child(3) {
background: yellow;
}
.cb2 {
animation: rotation 20s 1 linear;
}
<div class="objects">
<div></div>
<div></div>
<div></div>
</div>
Related
How can I create a Swiper.js slider with full-width images in the background, but with three sliders per view? Here is an example of what I want it to look like: https://stinna-it.nl/alle-projecten.
I have tried to update the images from an array through Swiper.js, called "images", but it is not updating.
var images = [
{
id: "1",
img: "https://i.im.ge/2022/12/15/dfE2sy.aura-blobb.png",
},
{
id: "2",
img: "https://i.im.ge/2022/12/15/df3XIx.almond-key.jpg",
},
{
id: "3",
img: "https://i.im.ge/2022/12/15/dfE2sy.aura-blobb.png",
},
{
id: "4",
img: "https://i.im.ge/2022/12/15/dfE2sy.aura-blobb.png",
},
{
id: "5",
img: "https://i.im.ge/2022/12/15/dfE2sy.aura-blobb.png",
},
];
const img = document.querySelector(".prjctbg");
// for (i = 0; i < images.length; i++) {
// console.log(images[i].img);
// img.src = images[i].img;
// }
var swiper = new Swiper(".swiper-container", {
pagination: {
el: ".swiper-pagination",
clickable: true,
},
spaceBetween: 1,
slidesPerView: 2.5,
centeredSlides: true,
roundLengths: true,
loop: true,
loopAdditionalSlides: 30,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
on: {
slideChangeTransitionStart: function () {
var imgElement = document.querySelector(".prjctbg");
// Get the current slide index
var slideIndex = this.realIndex;
imgElement.src = images[slideIndex].img;
},
},
});
.projectSlider {
width: 100vw;
height: 100vh;
position: relative;
.prjctbg {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
filter: blur(8px);
-webkit-filter: blur(8px);
z-index:-1;
}
}
.swiper-container {
position: relative;
width: 100%;
height: 100%;
}
.swiper-slide {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
transition: all 200ms cubic-bezier(0.165, 0.84, 0.44, 1);
transform: scale(0.8);
text-align: center;
// transition: cubic-bezier(0.165, 0.84, 0.44, 1);
p {
overflow: hidden;
color: #fff;
span {
transform: translateY(100px);
transition: transform 1000ms cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s,
transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s;
display: block;
}
}
h1 {
color: #fff;
font-size: 3em;
line-height: 100%;
transition: transform 1000ms cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s,
transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s;
margin: 0px;
transform: scale(0.5);
}
&.swiper-slide-active {
p {
opacity: 1;
transition-delay: 0.5s;
span {
transition: transform 1000ms cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s,
transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s;
transform: translateY(0px);
display: block;
}
}
h1 {
transition: transform 1000ms cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s,
transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) 0.2s;
transition-delay: 0.15s;
transform: scale(1);
}
transform: scale(1);
}
}
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.2.0/css/swiper.css"
/>
<div class="projectSlider">
<img src="" alt="" class="prjctbg" />
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="swiper-slide-container">
<div class="details">
<h1 class="elmt">
Audiovisual <br />
Design
</h1>
<p class="elmt">
<span> Video Installation</span>
</p>
</div>
</div>
</div>
<div class="swiper-slide">
<div class="swiper-slide-container">
<div class="details">
<h1 class="elmt">
Exhibition <br />
Design
</h1>
<p class="elmt">
<span> Multimedia Exhibition</span>
</p>
</div>
</div>
</div>
<div class="swiper-slide">
<div class="swiper-slide-container">
<div class="details">
<h1 class="elmt">
Texts and <br />
Images
</h1>
<p class="elmt">
<span> website + Print Magazine </span>
</p>
</div>
</div>
</div>
<div class="swiper-slide">
<div class="swiper-slide-container">
<div class="details">
<h1 class="elmt">
Material and <br />
Light
</h1>
<p class="elmt">
<span> Short Video</span>
</p>
</div>
</div>
</div>
<div class="swiper-slide">
<div class="swiper-slide-container">
<div class="details">
<h1 class="elmt">
Dimension <br />
Design
</h1>
<p class="elmt">
<span> Rendered Image </span>
</p>
</div>
</div>
</div>
<div class="swiper-slide">
<div class="swiper-slide-container">
<div class="details">
<h1 class="elmt">
App <br />
Design
</h1>
<p class="elmt">
<span> Sustainability App</span>
</p>
</div>
</div>
</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.2.0/js/swiper.js"></script>
I am building a quiz which will consist of a number of slides, while going between the slides using I want to apply a transition similar to this site where the next card slides in slightly.
I have tried applying the transition on my .active classes but this doesn't appear to have any affect.
CodePen
HTML:
<div class="row main-row align-items-center diagonal-stripe-1">
<div class="col d-flex justify-content-center">
<div class="card card1 w-50 active">
<div class="card-body text-center">
<h5 class="card-title">Questionnaire</h5>
<p class="card-text">This is some example text to show on landing page for questionnaire.</p>
Get Started
</div>
</div>
<div class="card card2 w-50">
<div class="card-body text-center">
<h5 class="card-title">Next Question Goes Here</h5>
<p class="card-text">This is some example text to show on landing page for questionnaire.</p>
Get Started
</div>
</div>
</div>
</div>
</div>
CSS:
.main-row {
/*border: 1px solid red;*/
height: 80vh;
}
.diagonal-stripe-1 { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSd3aGl0ZScvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J2JsYWNrJyBzdHJva2Utd2lkdGg9JzEnLz4KPC9zdmc+Cg=="); background-repeat: repeat; }
/* CARD STYLES */
.card {
display: none;
margin-left: 50px;
}
.card.active {
display: block;
margin-left: 0px;
transition: 2s;
/*transform:translate(0);*/
}
JS:
$(document).ready(function() {
$( ".first-btn" ).click(function() {
console.log( "Handler for .click() called." );
$(".card1").toggleClass('active');
$(".card2").toggleClass('active');
});
});
It's because your active card was not showing, I've tried to show your card2 first and call setTimeout to toggleClass, and it works:
$(document).ready(function() {
$( ".first-btn" ).on('click', function() {
$(".card1").toggleClass('active');
$(".card2").show();
setTimeout(() => {
$(".card2").toggleClass('active');
}, 10)
});
});
.main-row {
/*border: 1px solid red;*/
height: 80vh;
}
.diagonal-stripe-1 { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSd3aGl0ZScvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J2JsYWNrJyBzdHJva2Utd2lkdGg9JzEnLz4KPC9zdmc+Cg=="); background-repeat: repeat; }
/* CARD STYLES */
.card {
display: none;
margin-left: 50px;
}
.card.active {
transition: all 1s ease-in-out;
display: block;
margin-left: 0px;
/*transform:translate(0);*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="row main-row align-items-center diagonal-stripe-1">
<div class="col d-flex justify-content-center">
<div class="card card1 w-50 active">
<div class="card-body text-center">
<h5 class="card-title">Questionnaire</h5>
<p class="card-text">This is some example text to show on landing page for questionnaire.</p>
Get Started
</div>
</div>
<div class="card card2 w-50">
<div class="card-body text-center">
<h5 class="card-title">Next Question Goes Here</h5>
<p class="card-text">This is some example text to show on landing page for questionnaire.</p>
Get Started
</div>
</div>
</div>
</div>
</div>
You're using the wrong property, you want
transition-duration: 2s;
But this belongs under .card so it looks more like this:
.card {
display: none;
margin-left: 50px;
transition-duration: 2s;
}
.card.active {
display: block;
margin-left: 0px;
/*transform:translate(0);*/
//more .active css...
}
here's some more info
https://www.w3schools.com/csSref/css3_pr_transition-duration.asp
I believe this is what you are missing:
.card.active {
display: block;
margin-left: 0px;
-webkit-animation: slideIn 2s forwards;
-moz-animation: slideIn 2s forwards;
animation: slideIn 2s forwards;
}
#-webkit-keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
#-moz-keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
#keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
You could check the following fiddle or check codepen fork:
$(document).ready(function() {
$( ".first-btn" ).click(function() {
console.log( "Handler for .click() called." );
$(".card1").toggleClass('active');
$(".card2").toggleClass('active');
});
});
.main-row {
/*border: 1px solid red;*/
height: 80vh;
}
.diagonal-stripe-1 { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSd3aGl0ZScvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J2JsYWNrJyBzdHJva2Utd2lkdGg9JzEnLz4KPC9zdmc+Cg=="); background-repeat: repeat; }
/* CARD STYLES */
.card {
display: none;
margin-left: 50px;
}
.card.active {
display: block;
margin-left: 0px;
-webkit-animation: slideIn 2s forwards;
-moz-animation: slideIn 2s forwards;
animation: slideIn 2s forwards;
/*transform:translate(0);*/
}
#-webkit-keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
#-moz-keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
#keyframes slideIn {
0% {
transform: translateX(-900px);
}
100% {
transform: translateX(0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="row main-row align-items-center diagonal-stripe-1">
<div class="col d-flex justify-content-center">
<div class="card card1 w-50 active">
<div class="card-body text-center">
<h5 class="card-title">Questionnaire</h5>
<p class="card-text">This is some example text to show on landing page for questionnaire.</p>
Get Started
</div>
</div>
<div class="card card2 w-50">
<div class="card-body text-center">
<h5 class="card-title">Next Question Goes Here</h5>
<p class="card-text">This is some example text to show on landing page for questionnaire.</p>
Get Started
</div>
</div>
</div>
</div>
</div>
See link for more details regarding CSS Animations and Transitions
I have this simple set of CSS animations that I want to run indefinitely. But for some reason, it only runs twice and stops.
Here's a CodePen example.
Here is how I implement it using Jquery (this is also seen on the code)
$('#slide1').one(animationEnd, () => {
$('#slide1').css('display', 'none').removeClass('animate-1')
$('#slide2').css('display', '').addClass('animate-2')
})
$('#slide2').one(animationEnd, () => {
$('#slide2').css('display', 'none').removeClass('animate-2')
$('#slide3').css('display', '').addClass('animate-3')
})
$('#slide3').one(animationEnd, () => {
$('#slide3').css('display', 'none').removeClass('animate-3')
$('#slide1').css('display', '').addClass('animate-1')
})
See that #slide3 should revert to #slide1 for animation. It did, but it stops after 2 cycles.
You have defined counter variable as const, but it needs to be let to allow later reassignment.
let counter = 0;
Also you need to use $.on instead of $.one when binding to the animation end. $.on is used to bind handler to some event (every time it occurres), while $.one is used for one time binding only (run the handler first time the event occurres, but no more that that).
Here is your updated example:
https://codepen.io/anon/pen/WXNOKQ
answer already given and accepted, this is only for infos since the javaScript takes only three boxes into account.
animation-delay can be used to keep animation looping infinitly:
body {
color: #FFFFFF;
background-color: #27292d;
overflow: hidden;
background: #27292d url('bg.jpg') no-repeat fixed center;
font-family: 'Roboto', sans-serif;
}
.slider-container {
position: absolute;
right: 0;
top: 40%;
}
.slider-content {
position: relative;
font-size: 32px;
text-transform: uppercase;
}
.boxes {
float: left;
padding: 10px 20px;
margin: 5px;
position: relative;
}
.sub-box {
clear: both;
margin-left: 60px;
}
.sub-box span {
color: #000000;
padding: 10px 20px;
background-color: #FFFFFF;
}
.box1 {
background-color: #FF4F80;
}
.box2 {
background-color: #4CA2F0;
}
.box3 {
background-color: #53CEC8;
}
#keyframes heartbeat {
0% {
transform: translate(100px, 200px) scale(0)
}
50% {
transform: translate(100px, 200px) scale(0)
}
60% {
transform: translate(-100px) scale(1.5)
}
70% {
transform: translate(-100px) scale(1.5)
}
80% {
transform: translate(-100px) scale(1.5)
}
100% {
transform: translate(100px, -200px) scale(0)
}
}
.slider-single {
position: absolute;
right: 0;
width: 400px;
height: 50px;
margin: 20px;
transform: scale(0);
}
.animate-1 {
transition: 300ms cubic-bezier(.17, .67, .55, 1.43);
animation: ease-out heartbeat 6s -3s infinite;
}
.animate-2 {
transition: 300ms cubic-bezier(.17, .67, .55, 1.43);
animation: ease-out heartbeat 6s -1s infinite;
}
.animate-3 {
transition: 300ms cubic-bezier(.17, .67, .55, 1.43);
animation: ease-out heartbeat 6s 1s infinite;
}
<div class="slider-container">
<div class="slider-content">
<div id='slide1' class="slider-single animate-1">
<div class=''>
<p class='boxes box1'>Pink Header</p>
</div>
<div class='sub-box'>
<span>White Header</span>
</div>
</div>
<div id='slide2' class="slider-single animate-2">
<div>
<p class='boxes box2'>Another Header</p>
</div>
<div class='sub-box'>
<span>subheader</span>
</div>
</div>
<div id='slide3' class="slider-single animate-3">
<div>
<p class='boxes box3'>10 more to go</p>
</div>
</div>
</div>
</div>
<div class="slider-container">
<div class="slider-content">
<div id='slide1' class="slider-single animate-1">
<div class=''>
<p class='boxes box1'>Pink Header</p>
</div>
<div class='sub-box'>
<span>White Header</span>
</div>
</div>
<div id='slide2' class="slider-single" style='display:none;'>
<div>
<p class='boxes box2'>Another Header</p>
</div>
<div class='sub-box'>
<span>subheader</span>
</div>
</div>
<div id='slide3' class="slider-single" style='display:none;'>
<div>
<p class='boxes box3'>10 more to go</p>
</div>
</div>
</div>
</div>
I am currently working on a portfolio for an artist. I am using Masonry with Isotope to filter for specific kinds of paintigs. When the items are being clicked, it opens lightGallery: http://sachinchoolur.github.io/lightGallery/
Everything works fine so far, the problem is the following:
What I want to achieve is that, if you filter for nature paintings for example, only the nature paintings will be shown and if you click on one of the items it opens the gallery. But the problem is, that at the moment ALL images of ALL categories are been shown in the gallery of nature. So if you click through them, you also get images of the category 'people' for example.
I guess the aim there is to give the different categories different 'galleries'. But if the filter 'show all' is clicked, the user should also be able to click through all the images of all categories, so that the gallery is not ending when the category of the item being clicked 'ends'.
As Im not that good with javascript, I hope you may be able to help me a little bit and that you understand my problem ..
The Code
HTML MARKUP
<div class="categories">
<button data-filter="*">Alle</button>
<button data-filter=".ship">Schiff</button>
<button data-filter=".copop">CoPop</button>
<button data-filter=".grey_bg">grey bg</button>
</div>
<div class="grid" id="lightgallery">
<a class="grid__item copop" href="app/assets/img/co-pop.jpg">
<img class="grid__item__img" src="app/assets/img/co-pop.jpg">
</a>
<a class="grid__item ship" href="app/assets/img/ship.jpg">
<img class="grid__item__img" src="app/assets/img/ship.jpg">
</a>
<a class="grid__item copop" href="app/assets/img/co-pop.jpg">
<img class="grid__item__img" src="app/assets/img/co-pop.jpg">
</a>
<a class="grid__item ship" href="app/assets/img/ship.jpg">
<img class="grid__item__img" src="app/assets/img/ship.jpg">
</a>
<a class="grid__item copop" href="app/assets/img/co-pop.jpg">
<img class="grid__item__img" src="app/assets/img/co-pop.jpg">
</a>
<a class="grid__item ship" href="app/assets/img/ship.jpg">
<img class="grid__item__img" src="app/assets/img/ship.jpg">
</a>
</div>
</div>
JS initialize lightgallery
<script type="text/javascript">
$(document).ready(function() {
$("#lightgallery").lightGallery();
});
</script>
JS isotope
(function($) {
$('#wrap').imagesLoaded(function() {
$('.categories').on( 'click', 'button', function() {
var filterValue = $(this).attr('data-filter');
$grid.isotope({ filter: filterValue });
});
var $grid = $('.grid').isotope({
itemSelector: '.grid__item',
percentPosition: true,
masonry: {
columnWidth: '.grid__item'
}
})
});
So I guess I need to create several galleries and say in the code that only the items of that activated data-filter gallery will be shown when clicked. But maybe that would also work without creating extra multiple galleries? Because then the problem would maybe be, that when all items are active, only the ones in that specific gallery of the selected item will be shown in the lightGallery.
Thank you for your help in advance!
kindly check this pen to get what you need
$(document).ready(function() {
var $gallery = $('#gallery');
var $boxes = $('.revGallery-anchor');
$boxes.hide();
$gallery.imagesLoaded( {background: true}, function() {
$boxes.fadeIn();
$gallery.isotope({
// options
sortBy : 'original-order',
layoutMode: 'fitRows',
itemSelector: '.revGallery-anchor',
stagger: 30,
});
});
$('button').on( 'click', function() {
var filterValue = $(this).attr('data-filter');
$('#gallery').isotope({ filter: filterValue });
$gallery.data('lightGallery').destroy(true);
$gallery.lightGallery({
selector: filterValue.replace('*','')
});
});
});
$(document).ready(function() {
$("#gallery").lightGallery({
});
});
//button active mode
$('.button').click(function(){
$('.button').removeClass('is-checked');
$(this).addClass('is-checked');
});
//CSS Gram Filters on Mouse enter
$("#gallery a .nak-gallery-poster").addClass("inkwell");
$("#gallery a").on({
mouseenter : function() {
$(this).find(".nak-gallery-poster").removeClass("inkwell").addClass("walden");
},
mouseleave : function() {
$(this).find(".nak-gallery-poster").removeClass("walden").addClass("inkwell");
}
});
.revGallery-anchor, .gal-overlay, .nak-gallery-poster{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.revGallery-anchor{
overflow: hidden;
position: relative;
width: calc(100% / 5);
display: block;
float: left;
border: 5px solid #e9e9e9;
}
.gal-overlay{
display: block;
width: 100%;
height: 100%;
background: rgba(27,27,27, 0.6);
position: absolute;
top: 0;
left: 0;
transition: background .4s ease;
-webkit-transition: background .4s ease;
}
.revGallery-anchor:hover .gal-overlay{
background: rgba(27,27,27, 0);
}
.nak-gallery {
display: block;
width: 100%;
position: relative;
margin-top: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.nak-gallery-poster{
padding-bottom:100%;
transform-origin: 50% 50%;
-webkit-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform: scale(1, 1);
-webkit-transform: scale(1, 1);
-ms-transform: scale(1, 1);
transition: all .4s ease;
-webkit-transition: all .4s ease;
}
.revGallery-anchor:hover .nak-gallery-poster{
transform: scale(1.1, 1.1);
-webkit-transform: scale(1.1, 1.1);
-ms-transform: scale(1.1, 1.1);
}
.img-responsive{
display:none;
}
.button{
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-transition: all .4s ease;
-moz-transition: all .4s ease;
-o-transition: all .4s ease;
transition: all .4s ease;
width: 200px;
height: 48px;
border: 1px solid rgba(0,169,157,1);
background-color: rgba(0,169,157,1);
border-radius: 2px;
color: #fff;
letter-spacing: 2px;
}
.button:hover {
background-color: #363636;
text-shadow: 0 1px hsla(0, 0%, 100%, 0.5);
color: #fff;
}
.button:active,
.button.is-checked {
background-color: #28F;
}
.button.is-checked {
color: white;
text-shadow: 0 -1px hsla(0, 0%, 0%, 0.8);
}
.button:active {
box-shadow: inset 0 1px 10px hsla(0, 0%, 0%, 0.8);
}
.revGallery-anchor-width1{
width: 40%
}
.revGallery-anchor-width2{
width: 30%
}
.revGallery-anchor-width3{
width: 20%
}
.nak-gallery-height1{
padding-bottom: 400px
}
.nak-gallery-height2{
padding-bottom: 300px
}
.nak-gallery-height3{
padding-bottom: 200px
}
.preloader{
display: none;
}
.preloaderStyle{
background: red;
width: 100%;
height: 100px;
}
<button type="button" class="button is-checked" data-filter="">ALL</button>
<button type="button" class="button" data-filter=".design">DESIGN</button>
<button type="button" class="button" data-filter=".branding">BRANDING</button>
<div class="nak-gallery nlg1" id="gallery">
<a href="http://unsplash.com/photos/GYNxcQvBNzA/download" class="revGallery-anchor design">
<img class="img-responsive" src="http://unsplash.com/photos/GYNxcQvBNzA/download">
<div style="overflow:hidden">
<div class="nak-gallery-poster" style="background-image:url('http://unsplash.com/photos/GYNxcQvBNzA/download');background-size:cover;background-repeat:no-repeat;background-position:center center;display: block;width: 100%;height: 0;"></div>
</div>
<div class="gal-overlay">
<div class="photo"></div>
</div>
</a>
<a href="https://www.youtube.com/watch?v=Io0fBr1XBUA" class="revGallery-anchor branding">
<img class="img-responsive" src="http://unsplash.com/photos/ssAcdlJRsI4/download">
<div style="overflow:hidden">
<div class="nak-gallery-poster" style="background-image:url('http://unsplash.com/photos/ssAcdlJRsI4/download');background-size:cover;background-repeat:no-repeat;background-position:center center;display: block;width: 100%;height: 0;"></div>
</div>
<div class="gal-overlay">
<div class="photo"></div>
</div>
</a>
<a href="http://unsplash.com/photos/EKIyHUrUHWU/download" class="revGallery-anchor design">
<img class="img-responsive" src="http://unsplash.com/photos/EKIyHUrUHWU/download">
<div style="overflow:hidden">
<div class="nak-gallery-poster" style="background-image:url('http://unsplash.com/photos/EKIyHUrUHWU/download');background-size:cover;background-repeat:no-repeat;background-position:center center;display: block;width: 100%;height: 0;"></div>
</div>
<div class="gal-overlay">
<div class="photo"></div>
</div>
</a>
<a href="http://unsplash.com/photos/CFi7_hCXecU/download" class="revGallery-anchor branding">
<img class="img-responsive" src="http://unsplash.com/photos/CFi7_hCXecU/download">
<div style="overflow:hidden">
<div class="nak-gallery-poster" style="background-image:url('http://unsplash.com/photos/CFi7_hCXecU/download');background-size:cover;background-repeat:no-repeat;background-position:center center;display: block;width: 100%;height: 0;"></div>
</div>
<div class="gal-overlay">
<div class="photo"></div>
</div>
</a>
<a href="http://unsplash.com/photos/cFplR9ZGnAk/download" class="revGallery-anchor design">
<img class="img-responsive" src="http://unsplash.com/photos/cFplR9ZGnAk/download">
<div style="overflow:hidden">
<div class="nak-gallery-poster" style="background-image:url('http://unsplash.com/photos/cFplR9ZGnAk/download');background-size:cover;background-repeat:no-repeat;background-position:center center;display: block;width: 100%;height: 0;"></div>
</div>
<div class="gal-overlay">
<div class="photo"></div>
</div>
</a>
</div>
https://codepen.io/kannan3024/pen/YWoQgq
I am creating a "live search" feature, this works fine functionally, however, on responsive testing, it breaks almost as soon as you get to tablet/mobile size.
I am using bootstrap for layout and the injected content from the live search is basically just a template that is injected.
Here is my HTML, SCSS and JS as it stands:
$(function() {
$(".brand-page-search-box").on("input", function(e) {
e.preventDefault();
var containerTemplate,
itemTemplate,
root = 'http://jsonplaceholder.typicode.com';
containerTemplate = `<div class="row search-result-item-container"></div>`;
$.ajax({
url: root + '/posts/1',
method: 'GET'
}).then(function(data) {
$(".search-results").html(containerTemplate);
let returnedJSONToObj = JSON.parse(JSON.stringify(data)),
userID = returnedJSONToObj.userId,
id = returnedJSONToObj.id,
title = returnedJSONToObj.title,
body = returnedJSONToObj.body;
itemTemplate = `<div class="col-xs-12 col-sm-6 col-lg-4">
<div class="flip-container">
<div class="card card-inverse">
<div class="front">
<div class="card-block">
<h3 class="card-title">${title}</h3>
<p class="card-text">${body}</p>
Button
</div>
</div>
<div class="back">
<div class="card-block">
<h3 class="card-title">${title}</h3>
<p class="card-text">${body}</p>
Button
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-lg-4">
<div class="flip-container">
<div class="card card-inverse">
<div class="front">
<div class="card-block">
<h3 class="card-title">${title}</h3>
<p class="card-text">${body}</p>
Button
</div>
</div>
<div class="back">
<div class="card-block">
<h3 class="card-title">${title}</h3>
<p class="card-text">${body}</p>
Button
</div>
</div>
</div>
</div>
</div>`;
$(".search-result-item-container").append(itemTemplate);
});
return false;
});
});
.flip-container {
-webkit-perspective: 1000;
perspective: 1000;
.card {
position: relative;
-webkit-transition: all 1s ease;
transition: all 1s ease;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
&: hover {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
.front,
.back {
width: 100%;
height: 100%;
position: absolute;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.front {
z-index: 2;
.card-block {
background: url("http://lorempixel.com/1920/1080/");
}
}
.back {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
.card-block {
background: url("http://lorempixel.com/900/500/");
}
}
}
}
<div class="container-fluid brand-search-bar">
<div class="row">
<div class="col-xs-12">
<nav class="navbar">
<div class="container">
<ul class="nav navbar-nav">
<li class="nav-item">
<form action="#" id="form">
<div class="input-group">
<input type="text" class="form-control brand-page-search-box" placeholder="Search">
<span class="input-group-btn">
<button type="submit" class="btn">
<i class="fa fa-search" aria-hidden="true"></i>
</button>
</span>
</div>
</form>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
<div class="container brand-img-container search-results"></div>
Now, the cards inject into the post fine, but look at the following screens to see how the sizing goes:
Desktop:
Laptop/Tablet:
Mobile:
As you can see, on mobile, it totally breaks for some reason and the cards "fold" into one another, but if bootstrap is meant to be handling the layout, why is this happening?
The inspector isnt being much help, nor are some of the articles I have been reading on here and elsewhere, unusually, anyone got any ideas on how to fix this?
I am using bootstrap 4 and jquery 2 if that helps.
If you have any questions, comments or requests, please do ask in the comments below.
You need to fix the flip effect css. Nothing to do with twitter bootstrap.
Your .flip-container is not getting height, so in xs when many containers stack you see the probleme.
You could set a fixed height for your .flip-container but since you want dynamic height here is a solution
Add .front{ position:relative} and .back{top: 0}
.flip-container {
-webkit-perspective: 1000;
perspective: 1000;
.card {
position: relative;
-webkit-transition: all 1s ease;
transition: all 1s ease;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
&:hover {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
.front,
.back {
width: 100%;
height: 100%;
position: absolute;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.front {
z-index: 2;
position:relative; <---
.card-block {
background: url("http://lorempixel.com/1920/1080/");
}
}
.back {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
top:0; <---
.card-block {
background: url("http://lorempixel.com/900/500/");
}
}
}
}