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';
});
Related
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.
}
I've rather roughly built this website which uses an effect similar to the iOS Safari tab view to look at various pages of a virtual book. Everything is working fine apart from the fact that I can't centre each page in the visible viewport. For example if you scroll down to the final 'page' and click on it, it jumps to the top of the document, instead of staying in the centre of the visible viewport.
I think this is to do with the fact that the scrollable div uses overflow-y:scroll, but I just can't figure out for the life of me how to fix the problem.
Any help would be greatly appreciated!!
Here's my jQuery:
jQuery(document.body).on('click', '.page', function() { //Change to touchstart
// Generate number between 1 + 2
var randomClass = 3;
var randomNumber = Math.round(Math.random() * (randomClass - 1)) + 1;
// Initialise & Random Number
jQuery(this).addClass("activated").addClass('scaled-' + randomNumber);
// Exiting - Reset All
jQuery(document.body).on('click', '.activated', function() { //Change to Touchstart
jQuery(this).removeClass("activated scaled-1 scaled-2 scaled-3");
});
});
And here is a jsfiddle with all my code in it so you can get a better idea of what I'm trying to achieve.
https://jsfiddle.net/ontu1ngq/
Thanks!
You need to get the amount that #wrapper has been scrolled, so that you can use that to set the top of the .page accordingly. Then, when you remove the .activated class, you will just need to remove the inline top style.
jQuery(document.body).on('click', '.page', function() {
var randomClass = 3;
var randomNumber = Math.round(Math.random() * (randomClass - 1)) + 1;
jQuery(this).addClass("activated").addClass('scaled-' + randomNumber);
var wrapper_scrollTop = $("#wrapper").scrollTop(); //gets amount scrolled
var half_wrapper = $("#wrapper").height()*(0.5); //50% of wrapper height
jQuery(this).css("top",half_wrapper+wrapper_scrollTop);
jQuery(document.body).on('click', '.activated', function() {
jQuery(this).removeClass("activated scaled-1 scaled-2 scaled-3");
jQuery(this).css("top","") //returns top to original value specified in css
});
});
Check out this working fiddle: https://jsfiddle.net/tardhepc/1/
I'm trying to manually create a parallax effect of sorts, and so far here's my JavaScript:
var bottom = document.getElementById("bottom");
var top = document.getElementById("top");
window.addEventListener("deviceorientation", function(e) {
var gamma = e.gamma;
var beta = e.beta;
$(bottom).css('left',(gamma/2)+'px').css('top',(beta/2)+'px');
$(top).css('left',(gamma)+'px').css('top',(beta)+'px');
});
So far its working great and I have the effect I want, but the starting position of the device is not quite what I want. Currently the alpha, beta, and gamma values are only at 0,0,0 if the device is flat on the table. What I want to do is that when you load the page, that position is taken as 0,0,0.
For example, if I am reading my phone in my hand, then of course my phone is going to be at an angle already, and I want to take this starting position as 0,0,0 when the page is loaded.
So to put that into some sort of pseudo code, here's what I'm trying to achieve:
gammaOnLoad and betaOnLoad = initial device orientation
gammaCurrent and betaCurrent = e.gamma and e.beta (from event listener)
gammaDifference and betaDifference = Math.abs(gammaOnLoad - gammaCurrent)
$(elem).css('left', gammaDifference + 'px').css('top', betaDifference + 'px');
So essentially you take in the values when loading the page and use those as 0, your point of origin. This means that whatever angle your phone is at, when you load the page the image will always look normal and from there it will begin the parallax effect.
I wanted to do the same thing as you. This is very basic, but it seems to work:
$(document).ready(function() {
var origLR, origFB;
function setOrigin(eventData) {
origLR = eventData.gamma;
origFB = eventData.beta;
}
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', setOrigin, false);
setTimeout(function() {
window.removeEventListener('deviceorientation', setOrigin, false);
window.addEventListener('deviceorientation', function(eventData) {
var tiltLR = eventData.gamma,
tiltFB = eventData.beta;
tiltLR = (origLR - tiltLR);
tiltFB = (origFB - tiltFB);
deviceOrientationHandler(tiltLR, tiltFB);
}, false);
}, 100);
};
function deviceOrientationHandler(tiltLR, tiltFB) {
$('.bottom').css('transform','translateX(' + (tiltLR/5) + 'px) translateY(' + (tiltFB/5) + 'px)');
$('.top').css('transform','translateX(' + (tiltLR/2.5) + 'px) translateY(' + (tiltFB/2.5) + 'px)');
}
});
I added an event listener for 100ms that sets the initial device orientation values, then removed it and replaced it with one that calculates the difference between initial and current.
This can probably be more efficient, I'm not a particularly experienced programmer.
--> Please goto Edit part of this Question
I want to synchronise scroll bar of two divs and this is how I am doing it
var div1 = document.getElementById('element1'),
div2 = document.getElementById('element2');
div1.addEventListener('touchmove', scrolled, false);
div2.addEventListener('touchmove', scrolled, false);
function getscrollTop(node) {
return node.pageYOffset || node.scrollTop;
}
function scrolled() {
var node = this, scrollTop = getscrollTop(node);
var percentage = scrollTop / (node.scrollHeight - node.clientHeight);
var other = document.getElementById({
"element1": "element2",
"element2": "element1"
}[node.id]);
other.scrollTop = percentage * (other.scrollHeight - other.clientHeight);
};
Fiddle -> used scroll instead touchmove
But the problem is it is flickering in low end devices and would like to make it smooth in event low end devices.
Edit
I have used below code to smoothen the scrolling
var children = document.querySelectorAll('.scrolldiv');
var getscrollTop = function(node) {
return node.pageYOffset || node.scrollTop;
}, toInt = function(n) {
return Math.round(Number(n));
};
window.setInterval(function() {
var scrollTop = getscrollTop(children[0]);
var percentage = scrollTop / (children[0].scrollHeight - children[0].clientHeight);
var oscrollTop = percentage * (children[1].scrollHeight - children[1].clientHeight);
// console.log(1);
children[1].scrollTop = toInt(oscrollTop);
}, 2);
It is smoother in Desktop browsers but in iOS browser, when setting second DIv's scroll it is jerking, jerking in the sense setting scrollTop once scrolling is completed, not while scrolling.
If you round your scroll value numbers to integers then this problem goes away :
http://jsfiddle.net/2Cj4S/15/
I just used a rounding function :
function toInt(n){ return Math.round(Number(n)); };
and this seems to have fixed it. Double values really confused GUI widgets like scrollbars, and 2D drawing.
I don't see why you have to calculate a new percentage here, value which you hand over to the second scroll.. that's probably the reason for the jerking.. instead you could simply take the scroll value from the first scroll and assign it directly to the other scroll.. This will remove the jerky-ness in the other scroll.. and synchronising them..
I just added the following line to the bottom of your scrolled function..
other.scrollTop = getscrollTop(node);
The modified function:-
function scrolled() {
var node = this,
scrollTop = getscrollTop(node);
var id = node.id;
var percentage = getscrollTop(node) / (node.scrollHeight - node.clientHeight);
var other = document.getElementById({
"element1": "element2",
"element2": "element1"
}[id]);
var oscrollTop = percentage * (other.scrollHeight - other.clientHeight)
//other.scrollTop = oscrollTop;
//Please note that I have commented out the above line.. and added the following line
other.scrollTop = getscrollTop(node);
};
I hope this the behaviour you were hoping for, i tested it out on jsfiddle, both scrolls are well synchronised.
I have a #wrapper div and a #grid div nested inside. currently I can scroll around with this function below.
getCursorPos : function(){
// set the empty cursor object
var cursor = {};
//get the offset from the left of the grid container
var grid
//offset loop
$(function getCursorPos(){
grid = $('#grid').offset();
setTimeout(getCursorPos, game.loopSpeed);
});
//continuosly get the position
var that = this;
$(document).mousemove(function(e){
//if game mode is menu exit
if(game.mode === 'menu'){
return;
}
// NOTE: this looks a litle over done but don't remove anything
// its like this because javascript uses floating points
// and so in order to line up to the nearest hunderedth I
// had to make the cursor and div position intergers by
// muliplying by ten. one the two are added I reduced them
// and rounded them.
that.x = Math.round(((e.pageX * 10) - (grid.left * 10)) / 10);
that.y = Math.round(((e.pageY * 10) - (grid.top * 10)) / 10);
});
},
the problem is that the mouse coordinates only update when the mouse moves. is there any way to get the coordinates with out moving the mouse?
You always have the latest up-to-date coordinates of the mouse from the last mouse move, clarify why those are not useful to you.