In a dice game I created a simple progress bar which supposed to dynamically show a player's progress. Here's the function:
function gameProgress(myScore) {
let myProgress = document.getElementById('progress');
let id = setInterval(frame, 50);
function frame() {
myProgress.style.width = myScore + 'px';
}
}
The function accepts the game score and supposed to reflect it on the progress bar. What actually happens is that the div's style="width:" keeps on jumping back and forth showing 2px, 7px, 17px, 22px, 32px and so on.
Any way to solve this problem? I want the element to display the latest updated width only but not all the values.
you don't have to use setInterval if you are updating the width only at one time.
function gameProgress(myScore) {
let myProgress = document.getElementById('progress');
prg.style.width = myScore + 'px'; // this should be a percentage of the actual total width of the div.
}
Related
I have a ball-game. width of board is 600px. 3 ball at that time coming down and on click it disappearing. but i want to have a one time 3 balls should be coming from different places. top 0 but left amount should be different. i write css
#keyframes ball-move {
0% {
top: 0;
left: 0;
}
For generate random width i make var.
var boardWidth = Math.floor(Math.random() * 600 + 1);
but i am not understanding how can i over right css in JS. i want to have top:0 to enter ball in frame but i want to enter from different width.
i tried with entering in css over ride but.JS is not reading my css.
I have to use only HTML, CSS,j javascript only.
Give each ball a class of ball and select them with javascript to loop through and set custom CSS
document.querySelectAll('.ball').forEach(ball => {
ball.style.left = Math.floor(Math.random() * 600);
}
If you want the ball to fall down from differenct place every time, you may use "on animationiteration". The below will set a new left value to the ball everytime the animation is itreataed.
The line
// Get all ball class element and loop through each
$(".ball").each(function(){
// Set random initial left value for tha ball
let boardWidth = Math.floor(Math.random() * 600);
$(this).css("left", boardWidth + "px");
// Set random left everytime the animation is iterated
$(this).on("animationiteration", function() {
let boardWidth = Math.floor(Math.random() * 600);
$(this).css("left", boardWidth + "px");
})
}
For the function you are using for boardWidth, you may want to consider taking the ball width into account as well, currently your ball may not be shown on the UI when left: 600px.
So. Like in my question, i create a Matrix intro, on my deskop(chrome) everything going smoothly. But, when i upload everything in to CodePen my animation stops on final step... Where is a issue?!
For sure there is a trouble with that part of code:
setTimeout(function() {
var elem = document.getElementById("spark");
var size = 0;
var pos=50;
var id = setInterval(frame, 1);
function frame() {
if(size>200){
//if would you like to run animation ones and relocate user to your main website use window.location.href=''; instead of location.reload();
window.location.reload();
}
else{
size+=2;
pos-=1;
elem.style.top = pos+"%";
elem.style.left = pos+"%";
elem.style.width = size + '%';
elem.style.height = size + '%';
}
}
},30000);
full code avaible on codepen
I try to change size, use only location.reload() but nothing. on a spot when function should reload it stops...
2nd issue is that, my function executes so slow... on mobile devices(samsung J5). So there needs to be some problem also but with ones?!
history.go(0); not working eater.
So what I want to happen is that when viewing the Span the text is normal but as you scroll down it starts moving until it looks like such:
Before the effect:
While the effect occurs:
The header is represented by spans for each letter. In the initial state, the top pixel value for each is 0. But the idea as mentioned is that that changes alongside the scroll value.
I wanted to keep track of the scroll position through JS and jQuery and then change the pixel value as needed. But that's what I have been having trouble with. Also making it smooth has been another issue.
Use the mathematical functions sine and cosine, for characters at even and odd indices respectively, as the graphs of the functions move up and down like waves. This will create a smooth effect:
cos(x) == 1 - sin(x), so in a sense, each character will be the "opposite" of the next one to create that scattered look:
function makeContainerWiggleOnScroll(container, speed = 0.01, distance = 4) {
let wiggle = function() {
// y-axis scroll value
var y = window.pageYOffset || document.body.scrollTop;
// make div pseudo-(position:fixed), because setting the position to fixed makes the letters overlap
container.style.marginTop = y + 'px';
for (var i = 0; i < container.children.length; i++) {
var span = container.children[i];
// margin-top = { amplitude of the sine/cosine function (to make it always positive) } + { the sine/cosine function (to make it move up and down }
// cos(x) = 1 - sin(x)
var trigFunc = i % 2 ? Math.cos : Math.sin;
span.style.marginTop = distance + distance * trigFunc(speed * y)/2 + 'px';
}
};
window.addEventListener('scroll', wiggle);
wiggle(); // init
}
makeContainerWiggleOnScroll(document.querySelector('h2'));
body {
height: 500px;
margin-top: 0;
}
span {
display: inline-block;
vertical-align: top;
}
<h2>
<span>H</span><span>e</span><span>a</span><span>d</span><span>e</span><span>r</span>
</h2>
Important styling note: the spans' display must be set to inline-block, so that margin-top works.
Something like this will be the core of your JS functionality:
window.addEventListener('scroll', function(e) {
var scrl = window.scrollY
// Changing the position of elements that we want to go up
document.querySelectorAll('.up').forEach(function(el){
el.style.top = - scrl/30 +'px';
});
// Changing the position of elements that we want to go down
document.querySelectorAll('.down').forEach(function(el){
el.style.top = scrl/30 +'px';
});
});
We're basically listening in on the scroll event, checking how much has the user scrolled and then act upon it by offsetting our spans (which i've classed as up & down)
JSBin Example
Something you can improve on yourself would be making sure that the letters wont go off the page when the user scrolls a lot.
You can do this with simple math calculation, taking in consideration the window's total height and using the current scrollY as a multiplier.
- As RokoC has pointed out there is room for performance improvements.Implement some debouncing or other kinds of limiters
function jsiBoxAdjustTop()
{
var top
if ( jsiBox.preloadImg.height <= 699){
top = 216;
}
else{
top = 17;
}
jsiBox.boxNode.style.top = (top) + 'px';
}
I'm using that function to adjust a div's top position depending on the image that is in it's height. It's on a light box sort of script so every time I click the next button, a new image which could either be taller or smaller appears. It's working alright and it adjusts its position when the image is taller but my problem is it just jumps to that position. I'm really new to javascript so can anyone help me out to make this as if it's travelling/animating to it's position? I tried using setTimeOut but I think I was doing it wrong. I'd really love to know what I'm doing wrong.
Here's the full script if that helps. Link
you can use jQuery or YUI to do animate, such as
jQuery(jsiBox.boxNode).animate({'top': top}, 3000);
or you can write some simple code with setTimeout just for this case;
following code assume the begin top is 0.
var boxStyle = jsiBox.boxNode.style;
function animateTop(to) {
boxStyle.top = parseInt(boxStyle.top, 10) + 1 + 'px';
if (parseInt(boxStyle.top, 10) != to) {
setTimeout(function() {
animate(to);
}, 50);
}
}
animateTop(top);
What I'm essentially building is a webkit based controller that communicates with a program called Ecoute.app.
The controller has a progressbar that indicates the progress made through the currently playing song, but I want to make this bar's position adjustable with a click.
function barClick() {
var progress = Ecoute.playerPosition();
var width = 142.5;
var percentElapsed = progress / length;
var position = width * percentElapsed;
Ecoute.setPlayerPosition(position);
}
Is what I have, with Ecoute.playerPosition() returning the player's current position.
Width has previously been defined as a dynamic value at
var width = 142.5 / length * progress + 1.63;
With length being the current track length and progress being the player's position. This has been able to dynamically stretch a progression overlay image to indicate the position of the track via the desktop controller.
However, the max width used in the second function does not appear to allow the first function to work properly.
Any help possibly determining the correct value or approach would be hugely appreciated.
It is hard to really know where you are getting stuck. My guess is you are having problems getting the click to work and determining where to set the progress.
My solution is to have 2 elements, one wrapping the other. The outer element takes the click event and the size gets reflected by the inner element. You will have to do your own work integrating with the Ecoute player but I showed how to calculate the percentage.
var outside = document.getElementById('outside');
var inside = document.getElementById('inside');
outside.addEventListener('click', function(e) {
inside.style.width = e.offsetX + "px";
// calculate the %
var pct = Math.floor((e.offsetX / outside.offsetWidth) * 100);
inside.innerHTML = pct + " %";
}, false);
I didn't bother with any cross browser work since this is for a webkit based application.
Demo: http://jsbin.com/ubana3/5
In your HTML,
0% played< /progress>
In JQuery,
mediaPlayer = document.getElementById(playerId);
progressBar = document.getElementById('progress-bar');
progressBar.addEventListener('click', function(e) {
var percentage = Math.floor((e.offsetX / this.offsetWidth) * 100);
mediaPlayer.currentTime = mediaPlayer.duration*(percentage/100);
progressBar.value = percentage;
progressBar.innerHTML = percentage + '% played';
});