javascript animation - buttons using previous end point - javascript

I'm trying to have a bar slide up and down over the below image, based on certain values triggered by buttons. Ideally the new "start" position every time is the previously entered "end" position (unless there is a better method). Here is the
example image
My code below accomplished most of what I want, except I'd love to have the bar smoothly slide between the desired values after each button click. Thanks!
<!DOCTYPE html>
<html>
</script>
</body>
</html>
<style>
#container {
width: 19px;
height: 186px;
position: relative;
background: clear;
margin: 0px;
}
#animate {
border: 1px solid white;
width: 32px;
height: 12px;
position: absolute;
background-color: #252525;
}
</style>
<body>
<p>
<button onclick="myMove(0 ,20)">Move to Orange</button>
<button onclick="myMove(20, 100)">Move to Green</button>
<button onclick="myMove(100, 155)">Move to Blue</button>
</p>
<div id ="container">
<img src="https://dl.dropboxusercontent.com/u/377009668/webGL/stuff/legendVertical.png" alt="Fit Map Legend" style="float:left">
<div id ="animate"></div>
</div>
<script>
function myMove(start, stop) {
var elem = document.getElementById("animate");
var id = setInterval(frame, 5);
function frame() {
if (start == stop) {
clearInterval(id);
} else {
start++;
elem.style.top = start + 'px';
}
}
}
</script>
</body>
</html>

In order to have the bar slide smoothly to the next position, rather than sliding from the top again, you need to know where the bar currently is starting from.
This can be achieved in a few ways, either by having a global variable store the current position, or by recalculating the current position of it each time you call myMove.
The other thing you need to take into account is that the slider may need to slide up to get to the correct position, not just down. This is easiest to handle in the same if/else statement that you are already using to check if the bar is already in the correct position.
Example using a global variable to keep track of the current position:
(as a bonus myMove() no longer needs to be given a starting location as a parameter, just the location you want the bar to end up at).
<!DOCTYPE html>
<html>
</script>
</body>
</html>
<style>
#container {
width: 19px;
height: 186px;
position: relative;
background: clear;
margin: 0px;
}
#animate {
border: 1px solid white;
width: 32px;
height: 12px;
position: absolute;
background-color: #252525;
}
</style>
<body>
<p>
<button onclick="myMove(20)">Move to Orange</button>
<button onclick="myMove(100)">Move to Green</button>
<button onclick="myMove(5)">Move to Blue</button>
</p>
<div id ="container">
<img src="https://dl.dropboxusercontent.com/u/377009668/webGL/stuff/legendVertical.png" alt="Fit Map Legend" style="float:left">
<div id ="animate"></div>
</div>
<script>
var start = 0;
function myMove(stop) {
var elem = document.getElementById("animate");
var id = setInterval(frame, 5);
function frame() {
if (start == stop) {
clearInterval(id);
} else if (start > stop){
start--;
elem.style.top = start + 'px';
} else {
start++;
elem.style.top = start + 'px';
}
}
}
</script>
</body>
</html>

Amazing smooth animation using CSS3 transition
Use of data-* attribute instead of inline JS calls
Simple JS code
var moveBtn = document.querySelectorAll("[data-move]");
var bar = document.getElementById("animate");
function move(el) {
el.addEventListener("click", function(){
bar.style.transform = "translateY("+ this.dataset.move +"px)";
});
}
[].forEach.call(moveBtn, move);
#container {
width: 19px;
height: 186px;
position: relative;
}
#animate {
border: 3px solid #444;
width: 14px;
height: 8px;
position: absolute;
top:0;
-webkit-transition: 0.4s;
transition: 0.4s;
}
<p>
<button data-move="20">Move to Orange</button>
<button data-move="100">Move to Green</button>
<button data-move="170">Move to Blue</button>
</p>
<div id ="container">
<img src="http://i.stack.imgur.com/3pLSG.png" alt="Fit">
<div id="animate"></div>
</div>

Related

Bi-directional Progression Bar Javascirpt is not working

I want to create a bidirectional bar, one start with negative value the other with positive one. Negative statement in the Javascript code is not working
html code
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h3>Example of Progress Bar Using JavaScript</h3>
<input style="height:50px; width:50px; font-size:30px" type = text id="btn1" name = "btn10" > <span id ="option1" style="font-size:30px">Percentage</span>
<p>Pogress Bar</p>
<div style = "position: relative; left: 500px; top: 10px" id="Progress_Status">
<div id="myprogressBar"></div>
</div>
<div style = "position: relative; left: 42.5px; top: -10px" id="Progress_Status2">
<div id="myprogressBar2"></div>
</div>
<br>
<button onclick="Negative_or_Positive()">Start Download</button>
</body>
<script src = "index.js"> </script>
</html>
javascript code
var i = 0;
var My_Button = (document.getElementById("btn1"))
function update() {
var element = document.getElementById("myprogressBar");
var width = parseInt(My_Button.value) || 1;
element.style.width = width + '%';
}
function update2() {
var element = document.getElementById("myprogressBar2");
var width = parseInt(My_Button.value) || 1;
element.style.width = width + '%';
}
function Negative_or_Positive() {
if (My_Button.value > 0){
update()
}else if (My_Button.value <0) {
update2()
}
}
css code
#Progress_Status {
width: 25%;
background-color: #ddd;
}
#myprogressBar {
width: 1%;
height: 20px;
background-color: red;
transition: width .2s;
}
#Progress_Status2 {
width: 25%;
background-color: #ddd;
}
#myprogressBar2 {
width: 1%;
height: 20px;
background-color: blue;
transition: width .2s;
}
the negative statement is not working. When I place a negative value noone of the two bar is growing.
Someone has any idea of why?
You are setting a negative value on the elements width property in your update2() function. Because you know the value of the input element is negative at this point you can simply negate the parsed value:
var width = -parseInt(My_Button.value) || 1;
I put it all in a fiddle and applied the suggested change

Undo does not work for a replaced content on a div in html

I am trying to create a code that works when you put it on the google search bar, that is a must and i created a div you can edit, also i created a reset button that replaces the content on the div with the default text, but when I try to press ctrl + z it does not go back, and i don't know how to make it work
-I cannot get rid of the: data:text/html, part because it wouldn't work in the search bar for google
-i do have to have all the code types in just one document, because i have to copy paste it all on the google search bar
function reset() {
div_1.innerHTML = '<p> Default text<p>';
}
.div_1 {
display: block;
background-color: rgba(255, 0, 0, 0.5);
height: 80%;
position: relative;
width: 60%;
position-left: 100px;
}
<div contenteditable="true" class="div_1" id="div_1">
<p> Default text<p>
</div>
<button onclick="reset()">reset</button>
function reset() {
div_1.innerHTML = ''; //set the inner HTML to empty string
}
.div_1 {
display: block;
background-color: rgba(255, 0, 0, 0.5);
height: 80%;
position: relative;
width: 60%;
position-left: 100px;
}
<div contenteditable="true" class="div_1" id="div_1">
<p> Default text<p>
</div>
<button onclick="reset()">reset</button>
I think you are trying to make the form empty when you press reset button.
So you have to change the inner HTML to an empty string in order to do that.
I hope it helped
i was able to find an option with the memento pattern and creating an event for the ctrl + z input on the keyboard
function copy(){
inp1.select();
navigator.clipboard.writeText(inp1.value);
ctn.innerHTML = inp1.value;
}
var mementos = [];
function reset() {
mementos.push(document.getElementById('div_1').innerHTML);
div_1.innerHTML= '<p>caller name: </p><p>reason for the call:</p><p>CTN: <div class="ctn" id="ctn"></p><p><br></p><p></p>';
}
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 'z') {
var lastMemento = mementos.pop();
div_1.innerHTML = lastMemento;
}
});
function undo() {
var lastMemento = mementos.pop();
div_1.innerHTML = lastMemento;
}
input{
width:200px;
height: 100%;
}
.div_1{
display: block;
background-color:rgba(255, 0, 0, 0.5);
height:400px;
position: relative;
width: 400px;
padding-left: 2px;
}
button{
position: relative;
}
.ctn {
display: inline;
background-color: red;
}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Notes</title>
</head>
<body>
<link rel="stylesheet" href="syles.css">
<input placeholder="(000)-000-0000" maxlength="10" id="inp1">
<button onclick="reset()">reset</button>
<button onclick="copy()">copy</button>
<button onclick="undo()">Undo</button>
<div contenteditable="true"class="div_1" id="div_1">
<p>caller name: </p><p>reason for the call:</p><p>CTN: <div class="ctn" id="ctn"></p><p><br></p><p></p>
</div>
</body>
</html>

How to add width to an element using jquery each function?

I want to build a loading bar effect using two seperate divs inside each other. I got it all positioned and all that but how can I make one of them increase its width from %1 to %100 with transition? I want it to be filled in 10 sec.
Thanks.
<div class="loading-container">
<div class="outside-loading"></div>
<div class="inside-loading"></div>
</div>
Fairly simple with jQuery animate() which you can customize for step or easing and also use callbacks for start or complete as needed
$('.outside-loading').animate({width: '100%'}, 3000);// using 3 sec for demo
.outside-loading {
background: blue;
width: 0;
height: .5em
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="loading-container">
<div class="outside-loading"></div>
<div class="inside-loading"></div>
</div>
Vanilla Javascript
Create a function and increase the width with your set interval function. Add a conditional that checks if the width is 100% and if it is, then clear the interval. I also moved the divs within each other and set the display of the inner span tag to inline-block...
You can also target the elements textContent and display the widths progress in percent as well...
var i = 0;
function move() {
if (i == 0) {
i = 1;
var elem = document.getElementsByClassName("inside-loading");
var width = 1;
var id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem[0].style.width = width + "%";
elem[0].textContent = width + "%";
}
}
}
}
move();
.outside-loading {
width: 100%;
height: 30px;
background-color: grey;
}
.inside-loading {
display: inline-block;
width: 1%;
height: 100%;
background-color: red;
text-align: right;
vertical-align: middle;
font-size: 30px;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
}
<br><br><br>
<div class="loading-container">
<div class="outside-loading">
<span class="inside-loading">
</span>
</div>
</div>

JavaScript moving text animation doesn't work. FULL CODE

JS: My problem is in running the following JS script, it's supposed to be very easy ,i think, but i can't understand why won't it run. I've just started coding and i'm already stuck in this problem. I want the text to go up (by increasing the bottom in CSS) for 5px until it reaches pos=6 ; then clearInterval should do its job.
CSS: I've put the position of div's to RELATIVE as i've read in some tutorials but didn't put the " container's " position to ABSOLUTE, may it be the problem?
<html>
<head>
<style>
html {
height: 100%;
}
body {
height: ;
width: 100%;
background-color: ;
margin: 0px;
padding: 0px;
}
#generale {
height: 100%;
width: 100%;
}
#intestazione {
height: 7%;
width: 100%;
float: left;
background-image: url(immagini/sfumatura.png);
position: static;
}
#profilo {
position: static;
float: right;
width: 12%;
height: 100%;
}
.testo_rialzato {
position: relative;
float: right;
width: auto;
height: 100%;
padding-left: 20px;
padding-right: 20px;
background-color: transparent;
}
</style>
</head>
<body>
<div id="generale">
<div id="intestazione">
<div id="profilo"></div>
<div class="testo_rialzato sumba">
<p>Sp</p>
</div>
<div class="testo_rialzato ap">
<p>App</p>
</div>
<div class="testo_rialzato te">
<p>Te</p>
</div>
<div class="testo_rialzato do">
<p>Dom</p>
</div>
<div class="testo_rialzato big">
<p style="line-height:70%; margin-top:8px; text-align:center;">Big</p>
</div>
</div>
<script>
var ez = document.querySelectorAll(".sumba , .ap , .te , .do, .big");
ez.onmouseover = alza();
var intervallo = setInterval(alza, 100);
function alza() {
var pos = 0;
if (pos = 6) {
clearInterval(intervallo);
} else {
ez.style.bottom = pos + "px";
}
}
</script>
</div>
</body>
</html>
First thing is , why declaring you are using event on an array of dome node (result of querySelectorAll will return array of domenodes ) so in order to attach mouseover and also apply some style you have to loop around those nodes .
Seconde thing while declaring set interval, its usless to use mousemovehere ?
Also the condition if is wrong you're using assignment , so you have to use == or === in order to make comaparison .
See below snippet :
var ez = document.querySelectorAll(".sumba , .ap , .te , .do, .big");
var pos = 0;
var intervallo = setInterval(alza, 100);
ez.forEach(function(el){
el.addEventListener("mouseover", alza);
})
function alza() {
if (pos == 25) {
clearInterval(intervallo);
} else {
ez.forEach(function(el){
el.style.bottom = pos + "px";
});
pos++;
}
}
.sumba, .ap {
position:absolute;
}
.ap {
color:red;
left:40px
}
<!-- begin snippet: js hide: false console: true babel: false -->
<div class="sumba">Text</div>
<div class="ap">Text 2</div>
try this
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
}
</style>
<body>
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id ="container">
<div id ="animate">ggg</div>
</div>
<script>
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.left = pos + 'px';
}
}
}
</script>
</body>
</html>

Looking for a solution to load a url once then be able to click on element

I need help with loading a URL one time into a HTML5 audio player and then be able to click on an elements to do additional controls.
This is the code so far:
<div class="primary">
<article id="145">
<div class="loaddata" data-rel="http://www.jplayer.org/audio/mp3/Miaow-01-Tempered-song.mp3" onclick="setTimeout(function() { document.getElementById('145').classList.add('dataloaded'); }, 1)"> Load "Song1" </div>
</article>
<article id="139">
<div class="loaddata" data-rel="http://feeds.soundcloud.com/stream/327164631-scott-johnson-27-tms-1281.mp3" onclick="setTimeout(function() { document.getElementById('139').classList.add('dataloaded'); }, 1)"> Load "Song2" </div>
</article>
<article id="133" class="dataloaded">
<div class="loaddata" data-rel="http://archive.org/download/DTH20170611/DTH20170611.mp3" onclick="setTimeout(function() { document.getElementById('133').classList.add('dataloaded'); }, 1)"> Load "Song3" </div>
</article>
The player:
<div class="audio-player-wrapper">
<div class="mejs__button mejs__group-left">
<div class="rewind-btn">
<button title="Rewind 15 seconds">15</button>
</div>
<div class="playpause-btn">
<button title="Play" class="play" id="ppbtn"></button>
</div>
<div class="forward-btn">
<button title="Forward 15 seconds">15</button>
</div>
</div>
<div class="current-time">00:00</div>
<div class="duration-time">00:00</div>
<div class="mejs__button mobile-mute">
<button class="mobile-mute-btn mobile-mute-off"></button>
</div>
<audio width="100%" height="75px" id="audio-player" controls="controls">
<source id="sourceMp3" src="#" type="audio/mp3">
</audio>
</div>
JS:
$(".loaddata").on("click", function() {
var mp3Url = $(this).data('rel');
$("#audio-player_html5").attr('src', mp3Url);
});
$(".loaddata").click(function(){
$('.dataloaded').removeClass();
$('#ppbtn').click();
});
What the code above does is when a user clicks on loaddata the JS loads the url in data-rel into the src in sourceMP3. Then it scans 'primary' for any class called dataloaded and removes it. One millisecond later, it adds dataloaded to the article ID. Then the player starts playing the loaded URL in jquery $('#ppbtn').click();.
What I'm trying to find is a way to load the URL on the first click then be able to control the play/pause button after the first click. I tried doing .one() on loading the URL once but when all three elements have been clicked once, it won't load the URL in the clicked element and all three elements div.loaddata can control the player.
I guess the easy way of explaining it: remove existing .dataloaded, add URL to player, add .dataloaded to the article that was clicked then be able to click on play/pause button only on the div.loaddata with 'dataloaded'.
New question: is there a way to change a function when you click on an element? Like a new onclick?
I saw this answer this morning (but had a busy day!) .. I created a jsfiddle for playing multiple sounds some time ago but when I re-read the question this evening, it seemed not quite enough to cover what you were trying to do.
I found that there is a library called MediaElement.js available; the source code is outlined extensively in this article and there is a demo also
Alternately there is very good (slightly lengthy!) article about designing a custom audio player by Rose (second name not given) on her website where there is also a demo
Best of all though, a fellow SO-er gives a wonderful answer to a similar question (about a year ago) and there is a jsfiddle provided in that answer (top pick i think..)
the code (hope there's room!):
var audio_player = $("#audio-player");
var play_button = $('#play');
var progress_bar = $("#progressbar");
var time = $("#time");
var mute_button = $('#mute');
var volume_bar = $('#volume');
var more_info = $('#more-info-box');
var info_tray = $("#info-tray");
var player = document.getElementById('player');
var duration = 0;
var volume = 0.75;
player.onloadedmetadata = function() {
duration = player.duration;
progress_bar.progressbar("option", { 'max' : duration });
};
player.load();
player.volume = 0.75;
player.addEventListener("timeupdate", function() {
progress_bar.progressbar('value', player.currentTime);
time.text(getTime(player.currentTime));
}, false);
function getTime(t) {
var m=~~(t/60), s=~~(t % 60);
return (m<10?"0"+m:m)+':'+(s<10?"0"+s:s);
}
function getProgressBarClickInfo(progress_bar, e) {
var offset = progress_bar.position();
var x = e.pageX - offset.left; // or e.offsetX (less support, though)
var y = e.pageY - offset.top; // or e.offsetY
var max = progress_bar.progressbar("option", "max");
var value = x * max / progress_bar.width();
return { x: x, y: y, max: max, value: value };
}
volume_bar.progressbar({
value : player.volume*100,
});
volume_bar.click(function(e) {
var info = getProgressBarClickInfo($(this), e);
volume_bar.progressbar('value', info.value);
player.volume = info.value / info.max;
});
progress_bar.progressbar({
value : player.currentTime,
});
progress_bar.click(function(e) {
var info = getProgressBarClickInfo($(this), e);
player.currentTime = player.duration / info.max * info.value;
});
play_button.click(function() {
player[player.paused ? 'play' : 'pause']();
$(this).toggleClass("fa-play", !player.paused);
$(this).toggleClass("fa-pause", player.paused);
});
mute_button.click(function() {
if (player.volume == 0) {
player.volume = volume;
} else {
volume = player.volume;
player.volume = 0;
}
volume_bar.progressbar('value', player.volume * 100);
$(this).toggleClass("fa-volume-up", player.volume != 0);
$(this).toggleClass("fa-volume-off", player.volume == 0);
});
more_info.click(function() {
audio_player.animate({
height: (audio_player.height() == 50) ? 100 : 50
}, 1000);
});
#audio-player {
height: 50px;
width: 500px;
overflow: hidden;
background-color: #2B2B2B;
color: white;
-webkit-user-select: none; /* webkit (safari, chrome) browsers */
-moz-user-select: none; /* mozilla browsers */
-khtml-user-select: none; /* webkit (konqueror) browsers */
-ms-user-select: none; /* IE10+ */
}
#controls {
height: 50px;
background-color: #808080;
width: 350px;
}
.time {
font-size: 10px;
color: white;
position: relative;
top: 14px;
margin: 5px;
}
.ui-progressbar {
background: #2B2B2B;
}
.ui-progressbar-value {
background: white;
}
#progressbar, #volume {
height: 10px;
display: inline-block;
border-radius: 0px;
border: none;
position: relative;
top: 16px;
}
#progressbar {
width: 150px;
}
#play, #mute {
font-size: 16px;
width: 20px;
position: relative;
top: 17px;
}
#play {
margin-left: 15px;
}
#volume {
width: 50px;
}
#more-info-box {
display: inline-block;
width: 150px;
height: 50px;
position: relative;
left: 350px;
top: -50px;
padding-top: 18px;
text-align: center;
font-family: sans-serif;
font-size: 12px;
color: white;
}
#more-info-box, #more-info-box > span {
cursor: context-menu;
}
#info-tray {
display: inline-block;
color: white;
position: relative;
width: 100%;
top: -65px;
height: 50px;
padding: 5px;
}
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<audio id="player">
<source src="http://www.noiseaddicts.com/samples_1w72b820/2543.mp3" type="audio/mpeg" />
</audio>
<div id="audio-player">
<div id="controls">
<i id="play" class="fa fa-pause"></i>
<span id="start-time" class="time">00:00</span>
<div id="progressbar"></div>
<span id="time" class="time">00:00</span>
<i id="mute" class="fa fa-volume-up"></i>
<div id="volume"></div>
</div>
<div id="more-info-box">
<span id="more-info">MORE INFO</span>
</div>
<div id="info-tray">
Track: <span id="track">Semper Fidelis March</span>
</div>
</div>
Hope one of these solutions helps!
I was able to find a working solution. It's not pretty but it works.
First I had two elements, one that loads the data and other controls the player.
<article id="145">
<div class="loaddata" data-rel="http://www.jplayer.org/audio/mp3/Miaow-01-Tempered-song.mp3" onclick="setTimeout(function() { document.getElementById('145').classList.add('dataloaded');document.getElementById('145').classList.add('dataloaded'); }, 1);"> Load "Song1" </div>
<div class="front-playpause">song loaded</div>
</article>
JS:
$(".loaddata").on("click", function() {
var mp3Url = $(this).data('rel');
$("#audio-player_html5").attr('src', mp3Url);
$('.dataloaded').removeClass();
$('#ppbtn').click();
});
$(".front-playpause").click(function(){
$('#ppbtn').click();
});
CSS:
.front-playpause {display:none}
.dataloaded .front-playpause {display:block}
.dataloaded .loaddata {display:none}
When loaddata is clicked, it adds the class 'dataloadedto the article ID and then the CSS hidesloaddataand then displaysfront-playpause` and that's how I found a work around.
Thanks everyone for the help.

Categories