How to style text from JS string - javascript

I am using this typewriter effect made with JavaScript, HTML and CSS (method seen below) but I am wanting to take it a step further. Is there a way I can change the font of each word that is typed? I've looked around for solutions but I honestly don't even know what to search for. Please let me know if this is possible.
var words = ['Design','Create','Dream', 'Inspire'],
currentStep = 0,
textEl = document.querySelector('.change-text'),
oldWord = '';
setTimeout(changeWord, 2000);
function changeWord() {
oldWord = textEl.innerHTML;
// check if there is a word atm or not
if (oldWord.length < 1) {
if (currentStep !== words.length -1) {
currentStep ++;
}else {
currentStep = 0;
}
addNextWord();
} else {
setTimeout(deleteWord, 1400);
}
};
function deleteWord() {
var WordLength = oldWord.length,
currentWord = textEl.innerHTML,
currentLength = currentWord.length;
// The word is deleted so, start adding in the new one
if (currentLength < 1) {
changeWord();
return;
}
// Remove a charachter
textEl.innerHTML = currentWord.substring(0, currentLength - 1);
setTimeout(deleteWord, 140);
}
function addNextWord() {
var currentWord = textEl.innerHTML,
currentLength = currentWord.length,
nextWord = words[currentStep],
nextWordLength = nextWord.length;
if (currentLength === nextWordLength) {
changeWord();
return;
}
// add a charachter
textEl.innerHTML = nextWord.substring(0, currentLength + 1);
setTimeout(addNextWord, 240);
}
#first-section{
z-index: 4;
background-image: linear-gradient(to top, #205ba8 0%, #537895 100%);
position: relative;
width: 100%;
min-height: 100vh;
display: flex;
}
.inspire{
padding: 0;
margin: 0;
position: absolute;
top: 0;
left: 10%;
color: #fff;
font-size: 50px;
font-weight: 600;
font-family: sans-serif;
}
.change-text {
position: absolute;
bottom: 0;
left: 10%;
color: #fff;
line-height: 500px;
font-size: 70px;
font-weight: 900;
cursor: context-menu;
}
#keyframes blinking {
0% { opacity: 0; }
50% { opacity: 0; }
51% { opacity: 1; }
100% { opacity: 1; }
}
.change-text:after {
content: '_';
animation: blinking 1.2s infinite;
}
<section id="first-section">
<h1 class="inspire" data-aos="fade-right">
HERE TO:
</h1>
<div class="change-text" data-aos="fade-right">Design</div>
</section>

you can use array of objects for the words.
Add your custom fonts to each word.
And then change the font dynamically.
I have tweaked the timer to show it quick between.
var words = [
{
word: 'Design',
font: 'Cursive'
},
{
word: 'Create',
font: 'Serif'
},
{
word: 'Dream',
font: 'Sans-Serif'
},
{
word: 'Inspire',
font: `'Pangolin', cursive`
}
],
currentStep = 0,
textEl = document.querySelector('.change-text'),
oldWord = '';
setTimeout(changeWord, 2000);
function changeWord() {
oldWord = textEl.innerHTML;
// check if there is a word atm or not
if (oldWord.length < 1) {
if (currentStep !== words.length -1) {
currentStep ++;
}else {
currentStep = 0;
}
textEl.style.fontFamily = words[currentStep].font;
addNextWord();
} else {
setTimeout(deleteWord, 100);
}
};
function deleteWord() {
var WordLength = oldWord.length,
currentWord = textEl.innerHTML,
currentLength = currentWord.length;
// The word is deleted so, start adding in the new one
if (currentLength < 1) {
changeWord();
return;
}
// Remove a charachter
textEl.innerHTML = currentWord.substring(0, currentLength - 1);
setTimeout(deleteWord, 140);
}
function addNextWord() {
var currentWord = textEl.innerHTML,
currentLength = currentWord.length,
nextWord = words[currentStep].word,
nextWordLength = nextWord.length;
if (currentLength === nextWordLength) {
changeWord();
return;
}
// add a charachter
textEl.innerHTML = nextWord.substring(0, currentLength + 1);
setTimeout(addNextWord, 240);
}
#import url('https://fonts.googleapis.com/css2?family=Pangolin&display=swap');
#first-section{
z-index: 4;
background-image: linear-gradient(to top, #205ba8 0%, #537895 100%);
position: relative;
width: 100%;
min-height: 100vh;
display: flex;
}
.inspire{
padding: 0;
margin: 0;
position: absolute;
top: 0;
left: 10%;
color: #fff;
font-size: 50px;
font-weight: 600;
font-family: sans-serif;
}
.change-text {
position: absolute;
bottom: 0;
left: 10%;
color: #fff;
line-height: 500px;
font-size: 70px;
font-weight: 900;
cursor: context-menu;
}
#keyframes blinking {
0% { opacity: 0; }
50% { opacity: 0; }
51% { opacity: 1; }
100% { opacity: 1; }
}
.change-text:after {
content: '_';
animation: blinking 1.2s infinite;
}
<section id="first-section">
<h1 class="inspire" data-aos="fade-right">
HERE TO:
</h1>
<div class="change-text" data-aos="fade-right"></div>
</section>

Follow my example i add a simple if, engines the counter of array word and finally change font.
var words = ['Design','Create','Dream', 'Inspire'],
currentStep = 0,
textEl = document.querySelector('.change-text'),
oldWord = '';
setTimeout(changeWord, 2000);
function changeWord() {
oldWord = textEl.innerHTML;
// check if there is a word atm or not
if (oldWord.length < 1) {
if (currentStep !== words.length -1) {
currentStep ++;
}else {
currentStep = 0;
}
if(currentStep == 0){
textEl.style.fontFamily = "Impact,Charcoal,sans-serif";
}else if(currentStep== 1){
textEl.style.fontFamily = "Times New Roman";
}else if(currentStep == 2){
textEl.style.fontFamily = "Palatino Linotype";
}else if(currentStep == 3){
textEl.style.fontFamily = "Georgia";
}
addNextWord();
} else {
setTimeout(deleteWord, 1400);
}
};
function deleteWord() {
var WordLength = oldWord.length,
currentWord = textEl.innerHTML,
currentLength = currentWord.length;
// The word is deleted so, start adding in the new one
if (currentLength < 1) {
changeWord();
return;
}
// Remove a charachter
textEl.innerHTML = currentWord.substring(0, currentLength - 1);
setTimeout(deleteWord, 140);
}
function addNextWord() {
var currentWord = textEl.innerHTML,
currentLength = currentWord.length,
nextWord = words[currentStep],
nextWordLength = nextWord.length;
if (currentLength === nextWordLength) {
changeWord();
return;
}
// add a charachter
textEl.innerHTML = nextWord.substring(0, currentLength + 1);
setTimeout(addNextWord, 240);
}
#first-section{
z-index: 4;
background-image: linear-gradient(to top, #205ba8 0%, #537895 100%);
position: relative;
width: 100%;
min-height: 100vh;
display: flex;
}
.inspire{
padding: 0;
margin: 0;
position: absolute;
top: 0;
left: 10%;
color: #fff;
font-size: 50px;
font-weight: 600;
font-family: sans-serif;
}
.change-text {
position: absolute;
bottom: 0;
left: 10%;
color: #fff;
line-height: 500px;
font-size: 70px;
font-weight: 900;
cursor: context-menu;
}
#keyframes blinking {
0% { opacity: 0; }
50% { opacity: 0; }
51% { opacity: 1; }
100% { opacity: 1; }
}
.change-text:after {
content: '_';
animation: blinking 1.2s infinite;
}
<section id="first-section">
<h1 class="inspire" data-aos="fade-right">
HERE TO:
</h1>
<div class="change-text" data-aos="fade-right">Design</div>
</section>

You can add all the fonts that you wish to use to an array, then create a function that selects them randomly.
var fonts = ['verdana', 'arial', 'timesNewRoman'];
function changeFont() {
var font = fonts[Math.floor(Math.random() * fonts.length)];
textEl.style.fontFamily = font;
}
Then call this function right after you call addNextWord
function changeWord() {
oldWord = textEl.innerHTML;
// check if there is a word atm or not
if (oldWord.length < 1) {
if (currentStep !== words.length -1) {
currentStep ++;
}else {
currentStep = 0;
}
addNextWord();
changeFont(); // Call changeFont Here!!
} else {
setTimeout(deleteWord, 1400);
}
}

Related

How to stop effect of click during setTimeout?

I have a simple function which change opacity of divs every x seconds.
When I click on "pause button", this one make a pause in this loop, and get the color of the current div. When I click a second time on this button, the loop restart to play after a setTimeout.
My problem is that when I multi click (fast) on button, there is a bug in the loop.
My condition doesn't work.
Is there a solution to stop effect of click during setTimeout with stopPropagation or e.preventDefault or something else?
var j = 0;
var myElements = document.querySelectorAll('.div_child');
var myButton = document.querySelector('.my_button');
var colorArray = []
for (let i = 0; i < myElements.length; i++) {
let currentColor = getComputedStyle(myElements[i]).backgroundColor;
colorArray[i] = currentColor;
}
function my_fonction() {
myElements[j].style.opacity = 1;
for (let k = 0; k < myElements.length; k++) {
if (k != j) {
myElements[k].style.opacity = 0;
}
}
j++;
if (j == myElements.length) {
j = 0
}
playForbidden = false;
}
function setIntervalAndExecuteFn(fn, t) {
fn();
return (setInterval(fn, t));
}
var myIndice = j;
var myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
var play = true;
var playForbidden = false;
myButton.addEventListener('click', function() {
if (playForbidden == false) {
if (play == true) {
play = false;
clearInterval(myIntervalId);
if (j == 0) {
myIndice = myElements.length - 1;
} else {
myIndice = j - 1;
}
myButton.style.backgroundColor = colorArray[myIndice]
} else {
play = true;
myButton.style.backgroundColor = 'transparent';
setTimeout(function() {
myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
}, 500);
}
playForbidden == true;
} else {
return;
}
});
.div_parent {
position: relative;
width: 500px;
height: 300px;
border: 1px solid black;
}
.my_button {
width: 300px;
height: 100px;
border: 1px solid black;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 20px;
padding: 20px;
color: black;
}
.div_child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 500px;
height: 300px;
}
.div_child_one {
opacity: 0;
background-color: red;
}
.div_child_two {
opacity: 0;
background-color: green;
}
.div_child_three {
opacity: 0;
background-color: violet;
}
.div_child_four {
opacity: 0;
background-color: rgb(104, 104, 104);
}
<div class="div_parent">
<div class="div_child div_child_one"></div>
<div class="div_child div_child_two"></div>
<div class="div_child div_child_three"></div>
<div class="div_child div_child_four"></div>
</div>
<div class="my_button">PAUSE BUTTON</div>
The problem in your code is the setTimeout function. When you execute your setTimeout, what you are saying is "Start the interval in 0.5 seconds". But the problem is that this command is not stopped if you click on pause again really fast (within 0.5 seconds). What you can do is clearing the timeout at every click of the button. This way, you can cancel the command "Start the interval in 0.5 seconds".
You can see a working snippet of what I mean here below:
var j = 0;
var myElements = document.querySelectorAll('.div_child');
var myButton = document.querySelector('.my_button');
var colorArray = []
for(let i=0; i<myElements.length; i++){
let currentColor = getComputedStyle(myElements[i]).backgroundColor;
colorArray[i] = currentColor;
}
function my_fonction(){
myElements[j].style.opacity = 1;
for(let k = 0; k < myElements.length; k++){
if(k!=j){
myElements[k].style.opacity = 0;
}
}
j++;
if(j == myElements.length){ j = 0}
playForbidden = false;
}
function setIntervalAndExecuteFn(fn, t){
fn();
return(setInterval(fn, t));
}
var myIndice = j;
var myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
var myTimeoutId;
var play = true;
var playForbidden = false;
myButton.addEventListener('click', function(){
clearTimeout(myTimeoutId);
if(playForbidden == false){
if(play == true){
play = false;
clearInterval(myIntervalId);
if(j == 0){
myIndice = myElements.length-1;
}else{
myIndice = j-1;
}
myButton.style.backgroundColor = colorArray[myIndice]
}else{
play = true;
myButton.style.backgroundColor = 'transparent';
myTimeoutId = setTimeout(function() {
myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
}, 500);
}
playForbidden == true;
}else{
return;
}
});
.div_parent{
position: relative;
width: 500px;
height: 300px;
border: 1px solid black;
}
.my_button{
width: 300px;
height: 100px;
border: 1px solid black;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 20px;
padding: 20px;
color: black;
}
.div_child{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 500px;
height: 300px;
}
.div_child_one{
opacity: 0;
background-color: red;
}
.div_child_two{
opacity: 0;
background-color: green;
}
.div_child_three{
opacity: 0;
background-color: violet;
}
.div_child_four{
opacity: 0;
background-color: rgb(104, 104, 104);
}
<div class="div_parent">
<div class="div_child div_child_one"></div>
<div class="div_child div_child_two"></div>
<div class="div_child div_child_three"></div>
<div class="div_child div_child_four"></div>
</div>
<div class="my_button">PAUSE BUTTON</div>

How can I add a newline after my "&" characters, instead of the issue shown in my code snippet (adding extra space, not line breaks)?

I'm trying to add a line break after the "&" characters in three span elements.
Specifically, here:
<span class="word pomegranate text_animation">creativity &
categories</span>
<span class="word wisteria text_animation">form &
function</span>
<span class="word belize text_animation">style &
systems</span>
In the code above, &#65286 is the ampersand (&). I'd like to create a line break directly after this ampersand (and have tried using white space and a physical new line shown above).
I've created a personalized version of this lovely codepen and I'm running into a problem. I'm using white-space: pre-wrap; to add a line break into each span with rotating text. The reason I've resorted to this particular css property is because I've already tried using <br>, \n, \r\n, ␤, ␤, 
, and
with no luck (with and without the white-space property applied). I've managed to recreate this issue with the snippet below. Am I missing something? Is there a better way to go about this without using the white-space property?
TLDR; I can't manage to create a line-break after the ampersand in my span. The span is animated.
EDIT: I've added some comments into the snippet to highlight what I believe to be the code causing this issue. See comments at the top of the .js and .css snippets.
//not necessary to read through all of this, only thing that might be important is that
//each character in the original span is taken as a single letter for animation purposes
// (see line 25 for change word function)
var creativityAndCategories = document.querySelector('.pomegranate');
var styleAndSystems = document.querySelector('.belize');
var formAndFunction = document.querySelector('.wisteria');
factorForWidth();
function factorForWidth() {
var mywidth = window.innerWidth;
if (mywidth < 1170) {}
}
var words = document.getElementsByClassName('word');
var wordArray = [];
var currentWord = 0;
words[currentWord].style.opacity = 1;
for (var i = 0; i < words.length; i++) {
splitLetters(words[i]);
}
function changeWord() {
var cw = wordArray[currentWord];
var nw = currentWord == words.length - 1 ? wordArray[0] : wordArray[currentWord + 1];
for (var i = 0; i < cw.length; i++) {
animateLetterOut(cw, i);
}
for (var i = 0; i < nw.length; i++) {
nw[i].className = 'letter behind';
nw[0].parentElement.style.opacity = 1;
if (nw.length == 15) {
if (i < 5) {
nw[i].style.color = "#d67c5c";
}
if (i == 5 || i == 6) {
nw[i].style.color = "black";
}
if (i >= 7) {
nw[i].style.color = "#71acc1";
}
}
if (nw.length == 23) {
if (i < 11) {
nw[i].style.color = "#d67c5c";
}
if (i == 11) {
nw[i].style.color = "black";
}
if (i >= 12) {
nw[i].style.color = "#71acc1";
}
}
animateLetterIn(nw, i);
}
currentWord = (currentWord == wordArray.length - 1) ? 0 : currentWord + 1;
}
function animateLetterOut(cw, i) {
setTimeout(function() {
cw[i].className = 'letter out';
}, i * 80);
}
function animateLetterIn(nw, i) {
setTimeout(function() {
nw[i].className = 'letter in';
}, 340 + (i * 80));
}
function splitLetters(word) {
var content = word.innerHTML;
word.innerHTML = '';
var letters = [];
for (var i = 0; i < content.length; i++) {
var letter = document.createElement('span');
letter.className = 'letter';
letter.innerHTML = content.charAt(i);
word.appendChild(letter);
letters.push(letter);
}
wordArray.push(letters);
}
changeWord();
setInterval(changeWord, 5000);
/* ---------------- css that relates to the issue ------------------*/
.word {
position: absolute;
width: 100%;
opacity: 0;
white-space: pre;
}
.text_animation {
font-weight: 600 !important;
margin: 0 !important;
line-height: 5.944rem;
}
/* ---------------- css you don't have to worry about --------------------- */
/* ------------- but is included for snippet functionality --------------- */
#import url(https://fonts.googleapis.com/css?family=Open+Sans:600);
.invisible_text {
color: transparent !important;
line-height: 5.944rem;
font-weight: 600 !important;
margin: 0;
}
.rotating_text_container {
position: relative;
width: 100%;
}
.my_rotating_text {
position: absolute;
width: 100%;
left: 0;
height: 400px;
top: 12px;
}
.kb_rotating {
line-height: 5.944rem;
}
.kb_text {
display: block;
vertical-align: top;
margin: 0;
font-weight: 600;
font-size: 4.833rem;
}
#media screen and (max-width: 990px) {
.kb_text {
font-size: 4.278rem;
}
.text_animation,
.kb_rotating,
.invisible_text {
line-height: 5.278rem;
}
}
#media screen and (max-width: 765px) {
.kb_text {
font-size: 3.722rem;
}
.text_animation,
.kb_rotating,
.invisible_text {
line-height: 4.5rem;
}
}
#media screen and (max-width: 550px) {
.kb_text {
font-size: 3.278rem;
}
.text_animation,
.kb_rotating,
.invisible_text {
line-height: 4.5rem;
}
}
.letter {
display: inline-block;
position: relative;
float: left;
transform: translateZ(25px);
transform-origin: 50% 50% 25px;
}
.letter.out {
transform: rotateX(90deg);
transition: transform 0.32s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.letter.behind {
transform: rotateX(-90deg);
}
.letter.in {
transform: rotateX(0deg);
transition: transform 0.38s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.wisteria {
color: gray;
}
.belize {
color: black;
}
.pomegranate {
color: red;
}
.green {
color: #16a085;
}
.midnight {
color: #2c3e50;
}
<div class="rotating_text_container">
<p class="invisible_text kb_text">Solving problems at the intersection of creativity & categories</p>
<div class="my_rotating_text">
<p class="text_animation kb_text">Solving problems at the intersection of</p>
<p class="kb_text kb_rotating">
<span class="word pomegranate text_animation">creativity &
categories</span>
<span class="word wisteria text_animation">form &
function</span>
<span class="word belize text_animation">style &
systems</span>
</p>
</div>
</div>
white-space: pre preserves all white-space. The extra spaces are because you indented the words after the newlines. `
Use white-space: pre-line to preserve the line breaks, but collapse other white-space.
var creativityAndCategories = document.querySelector('.pomegranate');
var styleAndSystems = document.querySelector('.belize');
var formAndFunction = document.querySelector('.wisteria');
factorForWidth();
function factorForWidth() {
var mywidth = window.innerWidth;
if (mywidth < 1170) {}
}
var words = document.getElementsByClassName('word');
var wordArray = [];
var currentWord = 0;
words[currentWord].style.opacity = 1;
for (var i = 0; i < words.length; i++) {
splitLetters(words[i]);
}
function changeWord() {
var cw = wordArray[currentWord];
var nw = currentWord == words.length - 1 ? wordArray[0] : wordArray[currentWord + 1];
for (var i = 0; i < cw.length; i++) {
animateLetterOut(cw, i);
}
for (var i = 0; i < nw.length; i++) {
nw[i].className = 'letter behind';
nw[0].parentElement.style.opacity = 1;
if (nw.length == 15) {
if (i < 5) {
nw[i].style.color = "#d67c5c";
}
if (i == 5 || i == 6) {
nw[i].style.color = "black";
}
if (i >= 7) {
nw[i].style.color = "#71acc1";
}
}
if (nw.length == 23) {
if (i < 11) {
nw[i].style.color = "#d67c5c";
}
if (i == 11) {
nw[i].style.color = "black";
}
if (i >= 12) {
nw[i].style.color = "#71acc1";
}
}
animateLetterIn(nw, i);
}
currentWord = (currentWord == wordArray.length - 1) ? 0 : currentWord + 1;
}
function animateLetterOut(cw, i) {
setTimeout(function() {
cw[i].className = 'letter out';
}, i * 80);
}
function animateLetterIn(nw, i) {
setTimeout(function() {
nw[i].className = 'letter in';
}, 340 + (i * 80));
}
function splitLetters(word) {
var content = word.innerHTML;
word.innerHTML = '';
var letters = [];
for (var i = 0; i < content.length; i++) {
var letter = document.createElement('span');
letter.className = 'letter';
letter.innerHTML = content.charAt(i);
word.appendChild(letter);
letters.push(letter);
}
wordArray.push(letters);
}
changeWord();
setInterval(changeWord, 5000);
#import url(https://fonts.googleapis.com/css?family=Open+Sans:600);
.invisible_text {
color: transparent !important;
line-height: 5.944rem;
font-weight: 600 !important;
margin: 0;
}
.rotating_text_container {
position: relative;
width: 100%;
}
.my_rotating_text {
position: absolute;
width: 100%;
left: 0;
height: 400px;
top: 12px;
}
.kb_rotating {
line-height: 5.944rem;
}
.kb_text {
display: block;
vertical-align: top;
margin: 0;
font-weight: 600;
font-size: 4.833rem;
}
.text_animation {
font-weight: 600 !important;
margin: 0 !important;
line-height: 5.944rem;
}
#media screen and (max-width: 990px) {
.kb_text {
font-size: 4.278rem;
}
.text_animation,
.kb_rotating,
.invisible_text {
line-height: 5.278rem;
}
}
#media screen and (max-width: 765px) {
.kb_text {
font-size: 3.722rem;
}
.text_animation,
.kb_rotating,
.invisible_text {
line-height: 4.5rem;
}
}
#media screen and (max-width: 550px) {
.kb_text {
font-size: 3.278rem;
}
.text_animation,
.kb_rotating,
.invisible_text {
line-height: 4.5rem;
}
}
.word {
position: absolute;
width: 100%;
opacity: 0;
white-space: pre-line;
}
.letter {
display: inline-block;
position: relative;
float: left;
transform: translateZ(25px);
transform-origin: 50% 50% 25px;
}
.letter.out {
transform: rotateX(90deg);
transition: transform 0.32s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.letter.behind {
transform: rotateX(-90deg);
}
.letter.in {
transform: rotateX(0deg);
transition: transform 0.38s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.wisteria {
color: gray;
}
.belize {
color: black;
}
.pomegranate {
color: red;
}
.green {
color: #16a085;
}
.midnight {
color: #2c3e50;
}
<div class="rotating_text_container">
<p class="invisible_text kb_text">Solving problems at the intersection of creativity & categories</p>
<div class="my_rotating_text">
<p class="text_animation kb_text">Solving problems at the intersection of</p>
<p class="kb_text kb_rotating">
<span class="word pomegranate text_animation">creativity &
categories</span>
<span class="word wisteria text_animation">form &
function</span>
<span class="word belize text_animation">style &
systems</span>
<!--<span class="word green">beautiful.</span>
<span class="word midnight">cheap.</span>-->
</p>
</div>
</div>
For anyone else than ever runs into this problem, I figured it out:
Instead of using line breaks, since each individual letter is a span, you should set the span of what you want on a new line to display: block;. Every span following and preceding the display: block; span should be set to display: inline-block; (if you're looking for an output like the one I've shown below). I'll include the code snippet as an example, where the word after the & is on a newline after the window size is below 900px.
Additionally, for this method, I didn't use the white-space property at all.
var creativityAndCategories = document.querySelector('.pomegranate');
var styleAndSystems = document.querySelector('.belize');
var formAndFunction = document.querySelector('.wisteria');
var invisibleText = document.querySelector('.invisible_text');
var width;
window.addEventListener("resize", factorWidth);
factorWidth();
function factorWidth(){
width = window.innerWidth;
}
var words = document.getElementsByClassName('word');
var wordArray = [];
var currentWord = 0;
words[currentWord].style.opacity = 1;
for (var i = 0; i < words.length; i++) {
splitLetters(words[i]);
}
function changeWord() {
var cw = wordArray[currentWord];
var nw = currentWord == words.length-1 ? wordArray[0] : wordArray[currentWord+1];
for (var i = 0; i < cw.length; i++) {
animateLetterOut(cw, i);
}
for (var i = 0; i < nw.length; i++) {
nw[i].className = 'letter behind';
nw[0].parentElement.style.opacity = 1;
if(nw.length == 19 && nw[0].innerHTML == "s"){
if(i < 5){
nw[i].style.color = "#d67c5c";
}
if(i == 9){
nw[i].style.color = "black";
}
if(i == 11 && width < 900){
nw[i].style.display = "block";
invisibleText.innerHTML = "Solving problems at the intersection of<br>creativity &<br>categories";
}
if(i == 11 && width > 900){
nw[i].style.display = "inline-block";
invisibleText.innerHTML = "Solving problems at the intersection of<br>creativity & categories";
}
if(i >= 10){
nw[i].style.color = "#71acc1";
}
}
if(nw.length == 19 && nw[0].innerHTML == "f"){
if(i < 5){
nw[i].style.color = "#d67c5c";
}
if(i == 7){
nw[i].style.color = "black";
}
if(i == 10 && width < 900){
nw[i].style.display = "block";
invisibleText.innerHTML = "Solving problems at the intersection of<br>creativity &<br>categories";
}
if(i == 10 && width > 900){
nw[i].style.display = "inline-block";
invisibleText.innerHTML = "Solving problems at the intersection of<br>creativity & categories";
}
if(i >= 11){
nw[i].style.color = "#71acc1";
}
}
if(nw.length == 27){
if(i < 11){
nw[i].style.color = "#d67c5c";
}
if(i == 13){
nw[i].style.color = "black";
}
if(i == 16 && width < 900){
nw[i].style.display = "block";
invisibleText.innerHTML = "Solving problems at the intersection of<br>creativity &<br>categories";
}
if(i == 16 && width > 900){
nw[i].style.display = "inline-block";
invisibleText.innerHTML = "Solving problems at the intersection of<br>creativity & categories";
}
if(i >= 14){
nw[i].style.color = "#71acc1";
}
}
animateLetterIn(nw, i);
}
currentWord = (currentWord == wordArray.length-1) ? 0 : currentWord+1;
}
function animateLetterOut(cw, i) {
setTimeout(function() {
cw[i].className = 'letter out';
}, i*80);
}
function animateLetterIn(nw, i) {
setTimeout(function() {
nw[i].className = 'letter in';
}, 340+(i*80));
}
function splitLetters(word) {
var content = word.innerHTML;
word.innerHTML = '';
var letters = [];
for (var i = 0; i < content.length; i++) {
var letter = document.createElement('span');
letter.className = 'letter';
letter.innerHTML = content.charAt(i);
word.appendChild(letter);
letters.push(letter);
}
wordArray.push(letters);
}
changeWord();
setInterval(changeWord, 5000);
#import url(https://fonts.googleapis.com/css?family=Open+Sans:600);
.invisible_text{
color: transparent !important;
line-height: 5.944rem;
font-weight: 600 !important;
margin: 0;
}
.rotating_text_container{
position: relative;
width: 100%;
}
.my_rotating_text {
position: absolute;
width: 100%;
left: 0;
height: 400px;
top: 12px;
}
.kb_rotating{
line-height: 5.944rem;
}
.kb_text{
display: block;
vertical-align: top;
margin: 0;
font-weight: 600;
font-size: 4.833rem;
}
.text_animation{
font-weight: 600 !important;
margin: 0 !important;
line-height: 5.944rem;
}
#media screen and (max-width: 990px){
.kb_text{
font-size: 4.278rem;
}
.text_animation, .kb_rotating, .invisible_text{
line-height: 5.278rem;
}
}
#media screen and (max-width: 765px){
.kb_text{
font-size: 3.722rem;
}
.text_animation, .kb_rotating, .invisible_text{
line-height: 4.5rem;
}
}
#media screen and (max-width: 550px){
.kb_text{
font-size: 3.278rem;
}
.text_animation, .kb_rotating, .invisible_text{
line-height: 4.5rem;
}
}
.word {
position: absolute;
display: block;
width: 100%;
opacity: 0;
}
.letter {
display: inline-block;
position: relative;
transform: translateZ(25px);
transform-origin: 50% 50% 25px;
}
.letter.out {
transform: rotateX(90deg);
transition: transform 0.32s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.letter.behind {
transform: rotateX(-90deg);
}
.letter.in {
transform: rotateX(0deg);
transition: transform 0.38s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.wisteria {
color: gray;
}
.belize {
color: black;
}
.pomegranate {
color: transparent;
}
.green {
color: #16a085;
}
.midnight {
color: #2c3e50;
}
<div class="rotating_text_container">
<p class="invisible_text kb_text">Solving problems at the intersection of<br>creativity & categories</p>
<div class="my_rotating_text">
<p class="text_animation kb_text">Solving problems at the intersection of</p>
<p class="kb_text kb_rotating">
<span class="word pomegranate text_animation">creativity   &   categories</span>
<span class="word wisteria text_animation">form   &   function</span>
<span class="word belize text_animation">style   &   systems</span>
<!--<span class="word green">beautiful.</span>
<span class="word midnight">cheap.</span>-->
</p>
</div>
</div>

Best replacement for scrollBy

I have a carousel that I have to hard code and I need some help. I want to make a slide effect for mobile phones but I can't find a replacement for album.scrollBy. If you take a look at the code, you can see that on touchMove I scroll the parent element of the carousel but after the touch is done I transform the carousel and the album remains scrolled. So the only solution I found was to remove the scroll after the transition but is doesn't look good. Any ideas?
This is the carousel index.html
<body>
<div id="album" autoCall="true" class='album'>
<ul id="carousel" class='carousel is-set'>
<li class='container carousel-element'>
<img src="assets/img1.jpeg">
</li>
<li class='container carousel-element'>
<img src="assets/img2.jpeg">
</li>
<li class='container carousel-element'>
<img src="assets/img3.jpeg">
</li>
<li class='container carousel-element is-ref'>
<img src="assets/img4.jpeg">
</li>
</ul>
<div class="left-arrow"></div>
<div class="right-arrow"></div>
</div>
<script src="SLID/js/index.js"></script>
</body>
This is the CSS file that contains the transitions:
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
scroll-behavior: smooth;
}
.album {
overflow: hidden;
width: 100%;
height: 100%;
margin: auto;
position: relative;
}
.carousel {
height: 100%;
width: 100%;
display: flex;
left: -100%;
list-style: none;
margin: 0;
padding: 0;
position: relative;
}
.carousel.toNext {
transform: translateX(100%);
}
.carousel.toPrev {
transform: translateX(-100%);
}
.carousel.is-set {
transform: none;
transition: transform 0.5s cubic-bezier(0.215, 0.610, 0.355, 1);
}
.carousel-element {
background: #ddd;
flex: 1 0 100%;
text-align: center;
order: 2;
position: relative;
height: 100% !important;
max-width: 100% !important;
padding: 0;
}
.carousel-element:nth-child(even) {
background: #d5d5d5;
}
.carousel-element.is-ref {
order: 1;
}
.controls {
padding: 2em;
text-align: center;
}
.container {
margin: 0 auto;
height: 100%;
width: 100%;
}
.carousel-element >img, video {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
max-width: 100%;
max-height: 100%;
margin: auto;
padding: 0 !important;
}
.left-arrow,
.right-arrow {
height: 100%;
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
width: 15%;
color: #fff;
text-align: center;
opacity: .5;
transition: opacity .15s ease
}
.left-arrow {
left: 0;
background: red
}
.right-arrow {
right: 0;
background: blue;
}
And here is the JS file:
let album = document.getElementById("album");
let carousel = document.getElementById("carousel");
let seats = document.querySelectorAll("ul > li");
if (seats.length === 1)
carousel.style.left = 0;
class SLID {
constructor() {
this.nextDisable = false;
this.prevDisable = false;
this.startX = 0;
this.finalX = 0;
this.lastX = 0;
this.didTheTouchMove = false;
}
goToNext() {
this.nextDisable = true;
var el, i, j, new_seat, ref;
el = document.querySelector("ul > li.is-ref");
el.classList.remove('is-ref');
new_seat = el.nextElementSibling || seats[0];
new_seat.classList.add('is-ref');
new_seat.style.order = 1;
for (i = j = 2, ref = seats.length; (2 <= ref ? j <= ref : j >= ref); i = 2 <= ref ? ++j : --j) {
new_seat = new_seat.nextElementSibling || seats[0];
new_seat.style.order = i;
}
carousel.classList.remove('toPrev');
carousel.classList.add('toNext');
carousel.classList.remove('is-set');
document.getElementById('carousel').addEventListener("transitionend", () => {
this.nextDisable = false;
}, {
once: true,
});
return setTimeout((function () {
return carousel.classList.add('is-set');
}), 50);
}
goToPrev() {
this.prevDisable = true;
var el, i, j, new_seat, ref;
el = document.querySelector("ul > li.is-ref");
el.classList.remove('is-ref');
new_seat = el.previousElementSibling || seats[seats.length - 1];
new_seat.classList.add('is-ref');
new_seat.style.order = 1;
for (i = j = 2, ref = seats.length; (2 <= ref ? j <= ref : j >= ref); i = 2 <= ref ? ++j : --j) {
new_seat = new_seat.nextElementSibling || seats[0];
new_seat.style.order = i;
}
carousel.classList.remove('toNext');
carousel.classList.add('toPrev');
carousel.classList.remove('is-set');
document.getElementById('carousel').addEventListener("transitionend", () => {
this.prevDisable = false;
}, {
once: true
});
return setTimeout((function () {
return carousel.classList.add('is-set');
}), 50);
}
}
if (document.getElementById("album").getAttribute('autoCall') === "true") {
let s = new SLID();
document.addEventListener("keydown", (e) => {
if (e.keyCode === 37)
if (s.prevDisable === false)
s.goToPrev();
if (e.keyCode === 39)
if (s.nextDisable === false)
s.goToNext();
})
carousel.addEventListener("touchstart", (e) => {
s.startX = e.touches[0].clientX;
s.lastX = e.touches[0].clientX;
})
carousel.addEventListener("touchmove", (e) => {
album.scrollBy(s.lastX - e.touches[0].clientX, 0);
s.lastX = e.touches[0].clientX;
})
carousel.addEventListener("touchend", (e) => {
album.scrollBy(s.lastX - s.startX, 0);
s.goToNext();
})
}

Images not Appearing in Carousel

The following code looks daunting, but a lot of it is repetitive. Try clicking on the red buttons.
<body>
<ul id="carousel" class="carousel">
<button id="moveSlideLeft" class="moveSlide moveSlideLeft"></button>
<div id="track" class="track">
<li class="slide1" data-shown="true2" title="true2"><img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Frajatbhageria%2Ffiles%2F2017%2F09%2Fcode-copy-1200x1200.jpg"></li>
<li class="slide2" data-shown="false3" title="false3"><img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Frajatbhageria%2Ffiles%2F2017%2F09%2Fcode-copy-1200x1200.jpg"></li>
<li class="slide3" data-shown="false1" title="false1"><img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Frajatbhageria%2Ffiles%2F2017%2F09%2Fcode-copy-1200x1200.jpg"></li>
</div>
<button id="moveSlideRight" class="moveSlide moveSlideRight"></button>
</ul>
</body>
<style>
.carousel {
list-style-type: none;
position: relative;
}
.moveSlideLeft {
left: 0px;
}
.moveSlideLeft>img {
width: 10px;
height: 10px;
transform: rotate(180deg);
}
.moveSlide {
margin: none;
padding: none;
width: 20px;
height: 20px;
background-color: red;
border: none;
float: left;
position: absolute;
z-index: 1;
}
.carousel>.track {
margin: none;
padding: none;
left: 0px;
width: 99px;
height: 100px;
overflow: hidden;
position: absolute;
}
.carousel>.track>li[data-shown="false1"] {
transform: translateX(-99px);
z-index: 0;
transition: transform 1s ease-out;
}
.carousel>.track>li[data-shown="true2"] {
transform: translateX(0px);
z-index: 2;
transition: transform 1s ease-out;
}
.carousel>.track>li[data-shown="false3"] {
transform: translateX(99px);
z-index: 0;
transition: transform 1s ease-out;
}
.carousel>.track>li>img {
float: left;
width: 99px;
height: 100px;
}
.moveSlideRight {
left: 80px;
}
.moveSlideRight>img {
width: 10px;
height: 10px;
}
</style>
<script>
const left = document.getElementById("moveSlideLeft");
const right = document.getElementById("moveSlideRight");
left.onclick = function() {
var carouselValues = [];
var tagReferences = document.getElementById("carousel").getElementsByTagName("li");
for (var i=0; i<=2; i++) {
carouselValues[i] = tagReferences[i].dataset.shown;
}
var placeholder;
for (var i=0; i<=2; i++) {
if (carouselValues[i] == "true2") {
placeholder = i;
break;
}
}
if (placeholder == 0) {
carouselValues[0] = "false3";
carouselValues[1] = "false1";
carouselValues[2] = "true2";
}
else if (placeholder == 1) {
carouselValues[0] = "true2";
carouselValues[1] = "false3";
carouselValues[2] = "false1";
}
else if (placeholder == 2) {
carouselValues[0] = "false1";
carouselValues[1] = "true2";
carouselValues[2] = "false3";
}
for (var i = 0; i<=2; i++) {
tagReferences[i].dataset.shown = carouselValues[i];
tagReferences[i].title = carouselValues[i];
}
}
right.onclick = function() {
var carouselValues = [];
var tagReferences = document.getElementById("carousel").getElementsByTagName("li");
for (var i=0; i<=2; i++) {
carouselValues[i] = tagReferences[i].dataset.shown;
}
var placeholder;
for (var i = 0; i<=2; i++) {
if (carouselValues[i] == "true2") {
placeholder = i;
break;
}
}
if (placeholder == 0) {
carouselValues[0] = "false1";
carouselValues[1] = "true2";
carouselValues[2] = "false3";
}
else if (placeholder == 1) {
carouselValues[0] = "false3";
carouselValues[1] = "false1";
carouselValues[2] = "true2";
}
else if (placeholder == 2) {
carouselValues[0] = "true2";
carouselValues[1] = "false3";
carouselValues[2] = "false1";
}
for (var i = 0; i<=2; i++) {
tagReferences[i].dataset.shown = carouselValues[i];
tagReferences[i].title = carouselValues[i];
}
}
</script>
I don't know why only one image is showing up. I'm trying to make a sliding carousel. Every time a button is clicked, the data-shown attribute is changed. Based on the value of the data-shown attribute, a new slide should slide in. Where is my error?
You just need to add position: absolute to carousel>.track>li>img to list them in one line because you position them floating to left but in top of each other
const left = document.getElementById("moveSlideLeft");
const right = document.getElementById("moveSlideRight");
left.onclick = function() {
var carouselValues = [];
var tagReferences = document.getElementById("carousel").getElementsByTagName("li");
for (var i=0; i<=2; i++) {
carouselValues[i] = tagReferences[i].dataset.shown;
}
var placeholder;
for (var i=0; i<=2; i++) {
if (carouselValues[i] == "true2") {
placeholder = i;
break;
}
}
if (placeholder == 0) {
carouselValues[0] = "false3";
carouselValues[1] = "false1";
carouselValues[2] = "true2";
}
else if (placeholder == 1) {
carouselValues[0] = "true2";
carouselValues[1] = "false3";
carouselValues[2] = "false1";
}
else if (placeholder == 2) {
carouselValues[0] = "false1";
carouselValues[1] = "true2";
carouselValues[2] = "false3";
}
for (var i = 0; i<=2; i++) {
tagReferences[i].dataset.shown = carouselValues[i];
tagReferences[i].title = carouselValues[i];
}
}
right.onclick = function() {
var carouselValues = [];
var tagReferences = document.getElementById("carousel").getElementsByTagName("li");
for (var i=0; i<=2; i++) {
carouselValues[i] = tagReferences[i].dataset.shown;
}
var placeholder;
for (var i = 0; i<=2; i++) {
if (carouselValues[i] == "true2") {
placeholder = i;
break;
}
}
if (placeholder == 0) {
carouselValues[0] = "false1";
carouselValues[1] = "true2";
carouselValues[2] = "false3";
}
else if (placeholder == 1) {
carouselValues[0] = "false3";
carouselValues[1] = "false1";
carouselValues[2] = "true2";
}
else if (placeholder == 2) {
carouselValues[0] = "true2";
carouselValues[1] = "false3";
carouselValues[2] = "false1";
}
for (var i = 0; i<=2; i++) {
tagReferences[i].dataset.shown = carouselValues[i];
tagReferences[i].title = carouselValues[i];
}
}
.carousel {
list-style-type: none;
position: relative;
}
.moveSlideLeft {
left: 0px;
}
.moveSlideLeft>img {
width: 10px;
height: 10px;
transform: rotate(180deg);
}
.moveSlide {
margin: none;
padding: none;
width: 20px;
height: 20px;
background-color: red;
border: none;
float: left;
position: absolute;
z-index: 1;
}
.carousel>.track {
margin: none;
padding: none;
left: 0px;
width: 99px;
height: 100px;
overflow: hidden;
position: absolute;
}
.carousel>.track>li[data-shown="false1"] {
transform: translateX(-99px);
z-index: 0;
transition: transform 1s ease-out;
}
.carousel>.track>li[data-shown="true2"] {
transform: translateX(0px);
z-index: 2;
transition: transform 1s ease-out;
}
.carousel>.track>li[data-shown="false3"] {
transform: translateX(99px);
z-index: 0;
transition: transform 1s ease-out;
}
.carousel>.track>li>img {
float: left;
width: 99px;
height: 100px;
position: absolute;
}
.moveSlideRight {
left: 80px;
}
.moveSlideRight>img {
width: 10px;
height: 10px;
}
<ul id="carousel" class="carousel">
<button id="moveSlideLeft" class="moveSlide moveSlideLeft"></button>
<div id="track" class="track">
<li class="slide1" data-shown="true2" title="true2"><img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Frajatbhageria%2Ffiles%2F2017%2F09%2Fcode-copy-1200x1200.jpg"></li>
<li class="slide2" data-shown="false3" title="false3"><img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Frajatbhageria%2Ffiles%2F2017%2F09%2Fcode-copy-1200x1200.jpg"></li>
<li class="slide3" data-shown="false1" title="false1"><img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Frajatbhageria%2Ffiles%2F2017%2F09%2Fcode-copy-1200x1200.jpg"></li>
</div>
<button id="moveSlideRight" class="moveSlide moveSlideRight"></button>
</ul>

JS:Select and move a specific div to front

I'm working on a simple card stack which rotates when clicked, my problem is I cant select a specific card and send it to the front and arrange again the cards according to number. I change the codes but luck, I consumed half a day to make it works, still not working.
I hope you understand me.
Thanks
here is a sample code.
codepen
var cardStack = document.getElementsByClassName('card');
var cardArray = []; // Does not change
var stateArray = []; // Changes - keeps track of card state
var prevStateArray = [];
function cardInit() {
for (var i=0; i<cardStack.length; i++) {
var cNum = i + 1;
var cName = 'card' + cNum.toString();
cardStack[i].classList.add(cName);
cardArray.push(cNum);
stateArray = cardArray;
};
};
function stackRefresh() {
prevStateArray = stateArray.slice(0);
stateArray.unshift(stateArray.pop());
}
function nextCard() {
stackRefresh();
for (var i=0; i<cardStack.length; i++) {
var cName = 'card' + prevStateArray[i].toString();
var cNameNew = 'card' + stateArray[i].toString();
cardStack[i].classList.remove(cName);
cardStack[i].classList.add(cNameNew);
};
}
cardInit();
body {
background-color: #2a2a2a;
}
.card {
width: 200px;
height: 320px;
background-color: #fff;
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.4);
border-radius: 5px;
display: inline-block;
position: absolute;
transform-origin: 0% 50%;
transition: all 1s ease;
}
.card-stack {
display: inline-block;
text-align: center;
position: relative;
left: 50%;
transform: translateX(-100px);
}
.card1 {
z-index: 1000;
left: 0;
}
.card2 {
z-index: 800;
transform: scale(0.99);
filter: brightness(0.9);
left: 20px;
}
.card3 {
z-index: 600;
transform: scale(0.98);
filter: brightness(0.8);
left: 40px;
}
.card4 {
z-index: 400;
transform: scale(0.97);
filter: brightness(0.7);
left: 60px;
animation-name: remove;
animation-duration: 1s;
}
#keyframes remove {
0% {transform: translateX(0px); opacity: 1};
50% {transform: translateX(-80px); opacity: 0};
51% {transform: translateX(10px) scale(0.97); opacity: 0};
100% {transform: translateX(0px) scale(0.97); opacity: 1;}
}
<div class="card-stack" onclick="nextCard();">
<div class="card">A</div>
<div class="card">B</div>
<div class="card">C</div>
<div class="card">D</div>
</div>
Try this sample
I changed html
<div class="card-stack" onclick="nextCard(event);">
...
And js function
function nextCard(e) {
var clickedCssClass = e.srcElement.classList[1];
if (!clickedCssClass) return;
var match = /(\d+)/.exec(clickedCssClass);
var clickedNumber = match[0];
for(var j = 1; j < clickedNumber ; j++){
stackRefresh();
for (var i=0; i<cardStack.length; i++) {
var cName = 'card' + prevStateArray[i].toString();
var cNameNew = 'card' + stateArray[i].toString();
cardStack[i].classList.remove(cName);
cardStack[i].classList.add(cNameNew);
};
}
}
First include the following statement in head section of the html:
<script src="http://code.jquery.com/jquery-3.2.1.js"></script>
Add then change the following tag
<div class="card-stack" onclick="nextCard();">
To
<div class="card-stack">
Finally, I modified the function cardInit as follow:
function cardInit() {
for (var i=0; i<cardStack.length; i++) {
var cNum = i + 1;
var cName = 'card' + cNum.toString();
cardStack[i].classList.add(cName);
$(cardStack[i]).on("click",function()
{
prevClassName=this.classList[1];
$(".card1").removeClass("card1").addClass(prevClassName);
this.className=this.className.replace(prevClassName,"card1");
});
cardArray.push(cNum);
stateArray = cardArray;
};
};
did you mean this?
I have added a moveTop function like
function moveTop() {
event.preventDefault();
event.stopPropagation();
var index = Array.prototype.slice.call(event.target.parentNode.querySelectorAll('.card')).indexOf(event.target)
var temp = stateArray[index];
prevStateArray = stateArray.slice(0);
stateArray.splice(index, 1);
stateArray.unshift(temp);
refreshCards();
}
var cardStack = document.getElementsByClassName('card');
var cardArray = []; // Does not change
var stateArray = []; // Changes - keeps track of card state
var prevStateArray = [];
function cardInit() {
for (var i = 0; i < cardStack.length; i++) {
var cNum = i + 1;
var cName = 'card' + cNum.toString();
cardStack[i].classList.add(cName);
cardArray.push(cNum);
stateArray = cardArray;
};
};
function stackRefresh() {
prevStateArray = stateArray.slice(0);
stateArray.unshift(stateArray.pop());
}
function nextCard() {
stackRefresh();
refreshCards();
}
function refreshCards() {
for (var i = 0; i < cardStack.length; i++) {
var cName = 'card' + prevStateArray[i].toString();
var cNameNew = 'card' + stateArray[i].toString();
cardStack[i].classList.remove(cName);
cardStack[i].classList.add(cNameNew);
};
}
function moveTop() {
event.preventDefault();
event.stopPropagation();
var index = Array.prototype.slice.call(event.target.parentNode.querySelectorAll('.card')).indexOf(event.target)
var temp = stateArray[index];
prevStateArray = stateArray.slice(0);
stateArray.splice(index, 1);
stateArray.unshift(temp);
refreshCards();
}
cardInit();
body {
background-color: #2a2a2a;
}
.card {
width: 200px;
height: 320px;
background-color: #fff;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.4);
border-radius: 5px;
display: inline-block;
position: absolute;
transform-origin: 0% 50%;
transition: all 1s ease;
text-align: right;
}
.card-stack {
display: inline-block;
text-align: center;
position: relative;
left: 50%;
transform: translateX(-100px);
}
.card1 {
z-index: 1000;
left: 0;
}
.card2 {
z-index: 800;
transform: scale(0.99);
filter: brightness(0.9);
left: 20px;
}
.card3 {
z-index: 600;
transform: scale(0.98);
filter: brightness(0.8);
left: 40px;
}
.card4 {
z-index: 400;
transform: scale(0.97);
filter: brightness(0.7);
left: 60px;
animation-name: remove;
animation-duration: 1s;
}
#keyframes remove {
0% {
transform: translateX(0px);
opacity: 1
}
;
50% {
transform: translateX(-80px);
opacity: 0
}
;
51% {
transform: translateX(10px) scale(0.97);
opacity: 0
}
;
100% {
transform: translateX(0px) scale(0.97);
opacity: 1;
}
}
<div class="card-stack" onclick="nextCard();">
<div class="card" onclick="moveTop()">A</div>
<div class="card" onclick="moveTop()">B</div>
<div class="card" onclick="moveTop()">C</div>
<div class="card" onclick="moveTop()">D</div>
</div>
The problem you are having is that you don't know which card was clicked. My guess is to pass the event when calling nextCard():
onclick="nextCard(event)"
And within the function:
function nextCard(event) {
// detect which card was picked
console.log(event.target);
// logic to bring picked card to the top
...
}

Categories