Slide Animation of div with centered text - javascript

My web application has a listener for barcode scans. How I got that working is another story.
Anyhow, I need to be able to alert the user when a scan is detected and if the back-end processing that ingested that scan was successful.
To help with that I have taken 2 divs and overlaid them.
The bottom div has some text that says "Ready To Scan" and the top div has some text that describes that status of the last scan. So basically, the way this will work, the user will "scan" something and then the div will display 100% of it's width some message that says "OK" or "Stop!" or "Do something..." depending on some business logic. But about 2-3 seconds later I want that div to slide to the left exposing the bottom div that says "Ready to scan". That way the user can continue scanning and they are aware that their last scan was "accepted."
Here is the code. To get the div to slide - hit the space bar.:
var counter = 0;
window.onkeyup = function(e) {
var key = e.keyCode ? e.keyCode : e.which;
if (key == 32) {
if (counter == 0) {
slide();
}
}
}
function slide() {
var $lefty = $('#scanner-status-error');
var $percentage = $lefty.outerWidth() - ($lefty.outerWidth() * .15);
$lefty.animate({
left: parseInt($lefty.css('left'),10) == 0 ?
-$percentage : 0
});
}
#scanner-status {
position: relative;
}
#scanner-status img {
display: inline-block;
max-width: 15px;
margin-right: 3px;
}
#scanner-status-ready {
top: 0;
left: 0;
width: 100%;
position: absolute;
vertical-align: middle;
text-align: center;
background-color: #939598;
max-height: 28px;
font-family: "Times New Roman", Times, serif;
font-weight: bold;
}
#scanner-status-error {
top: 0;
left: 0;
width: 100%;
position: absolute;
vertical-align: middle;
text-align: center;
background-color: #e54a5c;
max-height: 28px;
font-family: "Times New Roman", Times, serif;
color: white;
font-weight: bold;
z-index: 10;
}
.scanner-status-message {
display: inline-block;
line-height: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="scanner-status">
<div id="scanner-status-error">
<div class="scanner-status-message">Stop!</div>
</div>
<div id="scanner-status-ready">
<div class="scanner-status-message">Ready to Scan</div>
</div>
</div>
Question / Problem: I'm using JQuery to do the animation and my text is centered in the top div. The problem I'm running into is that as my div moves to the left of the screen, the div isn't shrinking in size, but just moving to the left, thus the centered text is no longer seen. How do I adjust for the moving div but at the same time ensure that my text is "centered"?

You were animating the left property instead of the width property.
var counter = 0;
window.onkeyup = function(e) {
var key = e.keyCode ? e.keyCode : e.which;
if (key == 32) {
if (counter == 0) {
slide();
}
}
}
function slide() {
var $lefty = $('#scanner-status-error');
var $percentage = $lefty.outerWidth() - ($lefty.outerWidth() * .15);
$lefty.animate({
width: "40"
});
}
#scanner-status {
position: relative;
}
#scanner-status img {
display: inline-block;
max-width: 15px;
margin-right: 3px;
}
#scanner-status-ready {
top: 0;
left: 0;
width: 100%;
position: absolute;
vertical-align: middle;
text-align: center;
background-color: #939598;
max-height: 28px;
font-family: "Times New Roman", Times, serif;
font-weight: bold;
}
#scanner-status-error {
top: 0;
left: 0;
width: 100%;
position: absolute;
vertical-align: middle;
text-align: center;
background-color: #e54a5c;
max-height: 28px;
font-family: "Times New Roman", Times, serif;
color: white;
font-weight: bold;
z-index: 10;
}
.scanner-status-message {
display: inline-block;
line-height: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="scanner-status">
<div id="scanner-status-error">
<div class="scanner-status-message">Stop!</div>
</div>
<div id="scanner-status-ready">
<div class="scanner-status-message">Ready to Scan</div>
</div>
</div>

Related

If I click the button, is there a way to see the accordion menu calculated in height?

I have a question.
When I click on a specific text button, I want to make the accordion box automatically calculated in height visible.
Now, the accordion box itself works in a way that clicks like a giant button, not a specific text button.
I want to modify the code that the 'active' class will add when the 'text button' is clicked, rather than the 'accordion box' is clicked.
I don't know how. I need your help.
Thank you!
TEST WEBSITE
if (matchMedia("all and (max-width: 812px)").matches) {
} else {
var acc = document.getElementsByClassName("info-box");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this;
if (panel.style.height) {
panel.style.height = null;
} else {
panel.style.height = panel.scrollHeight + "px";
}
});
}
}
.info-box {
display: block;
position: fixed;
bottom: 0;
left: 0;
height: 62px;
width: 100%;
transition: height 0.3s;
background: transparent;
z-index: 99;
}
.shopbtn {
display: inline-block;
position: fixed;
width: auto;
height: auto;
font-size: 12px;
font-weight: 300;
line-height: 12px;
letter-spacing: 1.4px;
z-index: 9999999999;
bottom: 12px;
left: 12px;
cursor: pointer;
text-transform: uppercase;
}
<div class="info-box" style>
<div class="shopbtn">Information</div>
test test test
</div>

Adding a space between spans so that the string looks normal even after removing the spans

Here is a piece of my code. Using a for loop I wrap each of spanPhrases elements with a specific span with its id and class and then add them as a single sentence to the page.
After 2 seconds (using jQuery) I remove the spans while I maintain the whole sentence like this:
// After 2 seconds remove spans and maintain text
$('#answerSentence').find(".spans").contents().unwrap();
The issue is I can't find a way to add a space between spans so that the sentence looks normal. So far there is no space between spans and only when we remove spans in the removeSpans function the sentence looks normal in case of word spacing.
I want no change in word spacing after 2 seconds.
Note: I want answerSentence in the removeSpans function without any &nbsp
let answerPhrases = ['i was sent', 'to earth', 'to live'];
let spanPhrases = ["I was sent", " to Earth,", " to live."];
let answer = '';
// put each of spanPhrases into a span with id and class
for (let i = 0; i < spanPhrases.length; i++) {
answer += `<span class='spans' id='spanID${i}'>${spanPhrases[i]}</span>`;
};
// add the text with spans to the page
answerSentence.innerHTML = `${answer}`;
setTimeout(function() {
removeSpans();
function removeSpans() {
// After 2 seconds remove spans and maintain text
$('#answerSentence').find(".spans").contents().unwrap();
}
}, 2000)
.containerAnswering {
position: absolute;
overflow: hidden;
left: 9.5vw;
top: 48vh;
height: 29vh;
width: 82vw;
outline: 0.1vw dashed orange;
}
.answerSentence-class {
position: absolute;
white-space: nowrap;
font-family: 'Open Sans', sans-serif;
font-size: 150%;
font-weight: 700;
color: rgb(128, 128, 128);
left: 0.5vw;
opacity: 1;
margin: 0;
top: 0;
bottom: 4vh;
display: flex;
align-items: center;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<div class="containerAnswering">
<div id="answerSentence" class="answerSentence-class"></div>
</div>
Why not change your text wrapping to pre-wrap?
let answerPhrases = ['i was sent', 'to earth', 'to live'];
let spanPhrases = ["I was sent", " to Earth,", " to live."];
let answer = '';
// put each of spanPhrases into a span with id and class
for (let i = 0; i < spanPhrases.length; i++) {
answer += `<span class='spans' id='spanID${i}'>${spanPhrases[i]}</span>`;
};
// add the text with spans to the page
answerSentence.innerHTML = `${answer}`;
setTimeout(function() {
removeSpans();
function removeSpans() {
// After 2 seconds remove spans and maintain text
$('#answerSentence').find(".spans").contents().unwrap();
}
}, 2000)
.containerAnswering {
position: absolute;
overflow: hidden;
left: 9.5vw;
top: 48vh;
height: 29vh;
width: 82vw;
outline: 0.1vw dashed orange;
}
.answerSentence-class {
position: absolute;
white-space: pre-wrap; // Update text wrap
font-family: 'Open Sans', sans-serif;
font-size: 150%;
font-weight: 700;
color: rgb(128, 128, 128);
left: 0.5vw;
opacity: 1;
margin: 0;
top: 0;
bottom: 4vh;
display: flex;
align-items: center;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<div class="containerAnswering">
<div id="answerSentence" class="answerSentence-class"></div>
</div>
Your JavaScript is correct. You should fix CSS styles. This weird behavior disappears if replace display: flex; align-items:center; with line-height: 29vh;(to be aligned within parent container) in .answerSentence-class.
I would change that CSS as follows:
.answerSentence-class {
position: absolute;
white-space: nowrap;
font-family: 'Open Sans', sans-serif;
font-size: 150%;
font-weight: 700;
color: rgb(128, 128, 128);
left: 0.5vw;
opacity: 1;
margin: 0;
top: 0;
bottom: 4vh;
line-height: 29vh;
}
Unfortunately I have no answer why does flex truncate spaces.

Different events based on number of clicks

I have been struggling to get something to work:
https://jsfiddle.net/CreativeAU/ys12ed05/
warningbutton.onclick = function buttonClicks() {
count += 1;
if (count > 1) {
window.location.href = "http://www.google.com.au";
}
else {
warningbutton.onclick = function() {warningpopup.style.display = "block";}
}};
What I'm currently trying to do
The first time a user clicks 'Go To Page 2', a warning popup will appear. Once they close the warning and click the button again - it will take them to Page 2.
Right now:
Nothing happens on the first button click.
On the second click, and every button click after = the warning popup appears.
Ideally what I want
When a user arrives to a page (let's call it Page1), I want them to have to have clicked Box 1 OR Box 2 at least once - before clicking the 'Go To Page 2' button. If they haven't - then a 'warning popup' will appear over the screen telling them that they need to. I have very little idea how to code this using other divs.
If anyone is able to help me solve 'Ideally what I want' that would be awesome, but otherwise I will settle for what 'I'm currently trying to do'.
I've set it all up on the JsFiddle page just so you can visualise what I'm after.
this does what you want i think.
the link to google wont work, but this is because of stackoverflow.
var counter = 0;
$(document).ready(function(){
$('#first').click(function(){
counter++
});
$('#second').click(function(){
counter++
});
$('#next-page').click(function(){
if (counter >= 1) {
window.location.href = "http://www.google.com.au";
}else{
$('#warning-popup').css("display", "block");
}
});
$('#warning-popup').click(function(){
$(this).css("display", "none");
});
});
#wrapper {
max-width: 1200px;
margin: 0 auto;
}
#first, #second, #next-page {
text-align: center;
vertical-align: middle;
line-height: 125px;
font-size: 25px;
color: #FFF;
margin: 10px;
}
#first, #second {
display: inline-block;
background-color: #189a3d;
width: 125px;
height: 125px;
}
#next-page {
display: block;
background-color: #2e82d0;
width: 270px;
height: 125px;
}
.overlay {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.75);
text-align: center;
padding-top: 25px;
font-size: 40px;
color: #FFF;
}
#close {
color: orange;
float: right;
font-size: 30px;
text-decoration: underline;
margin-top: -0.35em;
}#wrapper {
max-width: 1200px;
margin: 0 auto;
}
#first, #second, #next-page {
text-align: center;
vertical-align: middle;
line-height: 125px;
font-size: 25px;
color: #FFF;
margin: 10px;
}
#first, #second {
display: inline-block;
background-color: #189a3d;
width: 125px;
height: 125px;
}
#next-page {
display: block;
background-color: #2e82d0;
width: 270px;
height: 125px;
}
.overlay {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.75);
text-align: center;
padding-top: 25px;
font-size: 40px;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="first">B1</div>
<div id="second">B2</div>
<div id="warning-popup" class="overlay">
WARNING TEXT HERE
</div>
<div id="next-page">Go to Page 2</div>
</div>
The following code should work, showing the alert if clicked the first time, and redirecting to google after another click.
var count = 0;
warningbutton.onclick = function buttonClicks() {
count += 1;
if (count > 1) {
window.location.href = "http://www.google.com.au";
}
else {
warningpopup.style.display = "block";
}
};
You need to change your else code.
You bind a new event on click, but do not trigger a click. You simply need to change the display attribute of your warning pop-up, without binding it on the click event.
A simple fix:
if (count > 1) {
window.location.href = "http://www.google.com.au";
}
else {
warningpopup.style.display = "block";
}};
you are basically registering a new function with the onclick event when the count is not greater than 1. solution should be
warningbutton.onclick = function buttonClicks() {
count += 1;
console.log(count);
if (count > 1) {
window.location.href = "http://www.google.com.au";
}
else {
warningpopup.style.display = "block";
}};

Limit a DIV to appear within another DIV of specific size

I'm currently working on this small project that randomly displays a div (#box) of 100px width and height. I want this div to appear ONLY in another div (#boxBorder) so it appears to be limited to a specific area on the page.
Here is the content of my HTML:
<h1>Test your reactions!</h1>
<p id="directions">Click the shape as fast as you can!</p>
<p id="scoreC">Click score: <span id="cScore">0</span>s</p>
<p id="scoreT">Total score: <span id="tScore">0</span>s</p>
<div id="boxBorder"></div>
<div id="box"></div>
Here is the CSS:
#boxBorder {
height: 500px;
width: 500px;
margin: 20px auto;
left: 0;
right: 0;
background-color: white;
border: 1px black solid;
position: absolute;
z-index: 0;
}
#box {
margin: 0 auto;
height: 100px;
width: 100px;
background-color: red;
display: none;
border-radius: 50px;
position: relative;
z-index: 1;
}
h1 {
margin: 15px 0 0 0;
}
#directions {
margin: 0;
padding: 5px;
font-size: 0.8em;
}
#scoreT, #scoreC {
font-weight: bold;
margin: 10px 50px 0 0;
}
#tScore, #cScore {
font-weight: normal;
}
h1, #directions, #scoreT, #scoreC {
width: 100%;
text-align: center;
}
And lastly, the javascript function for random position:
//Get random position
function getRandomPos() {
var pos = Math.floor((Math.random() * 500) + 1);
console.log("POS: " + pos + "px");
return pos + "px";
}
Which I call within a timeout method:
setTimeout(function() {
createdTime = Date.now();
console.log("make box: " + createdTime);
document.getElementById("box").style.top=getRandomPos();
document.getElementById("box").style.left=getRandomPos();
document.getElementById("box").style.backgroundColor=getRandomColor();
document.getElementById("box").style.borderRadius=getRandomShape();
document.getElementById("box").style.display="block";
}, rTime);
I'm not very skilled in positioning and I can't seem to get these two divs to align so that the #box div can recognize the size of the #boxBorder div and stay within those limits. Any help would be appreciated!
Couple things wrong here:
You need the box div nested inside the borderBox div if you want to use the relative positioning.
<div id="boxBorder">
<div id="box"></div>
</div>
The randomPos function needs to take into account the size of the box, so only multiply by 400 instead of 500.
function getRandomPos() {
var pos = Math.floor((Math.random() * 400));
return pos + "px";
}
Set the style to inline-block, not block for the box.
Use setInterval instead of setTimeout to have it repeat.
var rTime = 1000;
function getRandomPos() {
var pos = Math.floor((Math.random() * 400));
console.log("POS: " + pos + "px");
return pos + "px";
}
function getRandomColor() {
return ['#bf616a', '#d08770', '#ebcb8b', '#a3be8c', '#96b5b4', '#8fa1b3', '#b48ead'][(Math.floor(Math.random() * 7))];
}
function randomizeBox() {
createdTime = Date.now();
console.log("make box: " + createdTime);
document.getElementById("box").style.top = getRandomPos();
document.getElementById("box").style.left = getRandomPos();
document.getElementById("box").style.backgroundColor = getRandomColor();
}
setInterval(randomizeBox, rTime);
#boxBorder {
height: 500px;
width: 500px;
margin: 20px auto;
left: 0;
right: 0;
background-color: white;
border: 1px black solid;
position: absolute;
z-index: 0;
}
#box {
margin: 0 auto;
height: 100px;
width: 100px;
border-radius: 50px;
position: relative;
z-index: 1;
display: inline-block;
}
h1 {
margin: 15px 0 0 0;
}
#directions {
margin: 0;
padding: 5px;
font-size: 0.8em;
}
#scoreT,
#scoreC {
font-weight: bold;
margin: 10px 50px 0 0;
}
#tScore,
#cScore {
font-weight: normal;
}
h1,
#directions,
#scoreT,
#scoreC {
width: 100%;
text-align: center;
}
<h1>Test your reactions!</h1>
<p id="directions">Click the shape as fast as you can!</p>
<p id="scoreC">Click score: <span id="cScore">0</span>s</p>
<p id="scoreT">Total score: <span id="tScore">0</span>s</p>
<div id="boxBorder">
<div id="box"></div>
</div>

jQuery animation screwing up when switching tabs

I have a simple animation on my page that cycles through quotes (from a javascript array, currently). Before a new quote is loaded, jQuery moves the div to the right a bit and hides it. Then it loads the new text and moves the div back to the left while fading it in.
Here is the
JavaScript:
var lastIndex;
$(document).ready(function () {
cycleTestimonial(); // set first testimonial
setInterval(cycleTestimonial, 9000); // cycle through testimonials every x seconds after that
});
function cycleTestimonial() {
var testi = getTestimonial(); // retrieve testimonial
if (!testi) return; // usually means duplicate of last quote, so skip setting HTML
$('#testimonial').hide(0, function () { // erase current quote
$('#testimonial > #quote').html(testi['quote'].replace(/'/g, "’"));
$('#testimonial > #author').html(testi['auth']);
$('#testimonial > #tagline').html(testi['tag']);
$(this).velocity({ // set opacity to 0 and move right instantaneously to prepare to fade new quote in
right: '-=60',
opacity: 0.0
}, 0, function () {
var testiH = $(this).height();
var headH = $('#home-header').height() / 2;
$(this).offset({ 'top': (headH-(testiH/2)) });
$(this).show().velocity({ // fade in new quote and slide left
right: '+=60',
opacity: 1.0
}, 600);
});
});
}
function getTestimonial(index) {
var t = [ { "quote" : "I love this product.",
"auth" : "John Doe",
"tag" : "Preferred Client"
},
...
];
if (!index) { // no specific testimonial asked for, get a random one
index = Math.floor(Math.random() * t.length);
if (index == lastIndex) { // retrieved same testimonial as last time
cycleTestimonial(); // re-run until we get a new testimonial from last time
return;
}
else lastIndex = index; // set to ensure no repeats back-to-back
}
return t[index];
}
For thoroughness, here is the corresponding
HTML:
<div id="home-header">
<div class="boundary">
<div id="testimonial">
<div id="quote">
quote
</div>
<div id="author">
author
</div>
<div id="tagline">
tagline
</div>
</div>
</div>
</div>
And, finally, relevant
CSS:
.boundary {
display: block;
position: relative;
margin: 0 auto;
max-width: 1080px;
min-width: 720px;
height: inherit;
}
#home-header {
display: block;
position: relative;
height: 420px;
width: inherit;
}
#home-header #testimonial {
position: absolute;
display: block;
top: 40px;
right: 0px;
min-width: 350px;
max-width: 470px;
}
#home-header #testimonial #quote {
display: block;
width: inherit;
text-align: left;
font-size: 26pt;
font-style: italic;
line-height: 1.2;
color: #0085df;
font-weight: 300;
}
#home-header #testimonial #author {
display: block;
width: inherit;
text-align: right;
font-size: 14pt;
font-weight: 700;
color: #999;
}
#home-header #testimonial #tagline {
display: block;
width: inherit;
text-align: right;
text-transform: uppercase;
font-weight: 400;
font-size: 8pt;
color: #999;
}
Now, this code works great most of the time. However, when I switch away from the page to a different tab or window, and then come back to it, the alignment is all screwy until a new quote is loaded.
Also, when I load the page, occasionally the alignment gets screwed up then too, like it was placed before the page was fully loaded or loaded enough for it to place properly.
Is there a better way to do what I'm doing that won't come with these issues on placement?

Categories