I must be doing something wrong. Trying to set arrow hotkeys for videos to skip through the timeline and adjust the volume. Console logs return the desired new values, but they are not set.
document.onkeydown = function(e) {
var vid = document.getElementsByTagName('VIDEO');
if (vid.length) {
var vol = vid[0].volume;
var time = vid[0].currentTime;
var start = vid[0].seekable.start(0) + 10;
var end = vid[0].seekable.end(0) - 10;
if (e.keyCode === 37) {
if (start < time) {
time = time - 10;
console.log(time);
}
e.preventDefault();
}
if (e.keyCode === 38) {
if (vol < 1.0) {
vol = vol + 0.1;
console.log(vol);
}
e.preventDefault();
}
if (e.keyCode === 39) {
if (time < end) {
time = time + 10;
console.log(time);
}
e.preventDefault();
}
if (e.keyCode === 40) {
if (0.0 < vol) {
vol = vol - 0.1;
console.log(vol);
}
e.preventDefault();
}
}
};
You are not updating the vid.
Let's take an instance for volume updation.
What's happening here is you are taking value out of vol[0].volume into another variable 'volume' and upon event you are updating volume as a variable not vid, which you are using actually. Same goes for other keys (start, end and time).
Update vid as well.
Related
As the title says - I'm looking to add some auto-scrolling on a specific webpage but the script that I have at the moment stops it completely from scrolling, which doesn't look visually appealing during presentations IMHO.
Is there a possibility to slow down instead of harshly stopping the auto-scrolling of the webpage on a specific keystroke?
This is the JS that I tried.
let scrollerID;
let paused = true;
let speed = 2; // 1 - Fast | 2 - Medium | 3 - Slow
let interval = speed * 5;
function startScroll(){
let id = setInterval(function() {
window.scrollBy(0, 2);
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// Reached end of page
stopScroll();
}
}, interval);
return id;
}
function stopScroll() {
clearInterval(scrollerID);
}
document.body.addEventListener('keypress', function (event)
{
if (event.which == 13 || event.keyCode == 13) {
// It's the 'Enter' key
if(paused == true) {
scrollerID = startScroll();
paused = false;
}
else {
stopScroll();
paused = true;
}
}
}, true);
Thanks in advance!
The code works in the following way:
- holding shoot/drop button generate bullet and the bomb that is drawn/shown in canvas,
- it executes all the time in the function draw that refreshes around 60times per second.
Instead I want to set sth as:
- setInterval(shoot, 1000);
- setInterval(drop, 2000);
so it should be like:
- when user presses the key, it creates the bullet/bomb with the interval of 1/2 seconds
- it should all happen without realising the key
Below I provide the sample code:
let left = false;
let up = false;
let right = false;
let down = false;
let shoot = false;
let drop = false;
document.onkeydown = function (e) {
if (e.keyCode == 37) left = true;
if (e.keyCode == 38) up = true;
if (e.keyCode == 39) right = true;
if (e.keyCode == 40) down = true;
if (e.keyCode == 17) shoot = true;
if (e.keyCode == 32) drop = true;
e.preventDefault();
}
document.onkeyup = function (e) {
if (e.keyCode == 37) left = false;
if (e.keyCode == 38) up = false;
if (e.keyCode == 39) right = false;
if (e.keyCode == 40) down = false;
if (e.keyCode == 17) shoot = false;
if (e.keyCode == 32) drop = false;
e.preventDefault();
}
function draw() {
requestAnimationFrame(draw);
if (shoot) {
bullet = new Bullet(player.x - 3, player.y - 3, 6, 10)
bullets.push(bullet);
}
for (i = 0; i < bullets.length; i++) {
bullets[i].show();
bullets[i].move();
}
if (drop) {
bomb = new Bomb(player.x - 8, player.y + 50, 16, 1)
bombs.push(bomb);
}
for (i = 0; i < bombs.length; i++) {
bombs[i].show();
bombs[i].move();
}
}
requestAnimationFrame(draw);
Full code on remote server:
https://stacho163.000webhostapp.com
Is that a way to do it in my code or i have to change the way the buttons work?
If there is a solution without jQuery, that would be great.
e: checked the first tip, but after creating the first single bullet/bomb it's working as it was before.
Thank you for your tips :)
You should set some sort of wait variable, that indicates that the key is currently pressed, and no processing needs to take place:
let dropping = false;
// indicates that the bomb is dropping right now. Do not drop a new bomb
//...
if (e.keyCode == 32) {
drop = true;
dropping = true;
setTimeout(function () { dropping = false; }, 1000);
// if 1 second has passed, reset the dropping variable, to allow another bomb to drop
}
//...
if (drop && !dropping) {
bomb = new Bomb(player.x - 8, player.y + 50, 16, 1)
bombs.push(bomb);
}
This way, your bomb will only drop once every 1 second. Rinse and repeat :)
I'm making a game in which a player character moves left and right.
Since simply using an onKeyDown eventListener had my character move in a choppy fashion, and with a slight delay, I tried using requestAnimationFrame to call the movement function as often as possible, as suggested by another answer(How can I move my JS objects smoothly using keyboard input?)
however, that has changed nothing.
Here is my Javascript Code
var NodoCampo = document.getElementById("campo");
var NodoGiocatore = null;
var Left = false;
var Right = false;
var FRAMERATE = 20;
//cache giocatore
var LARG_GIOCATORE = 30;
var ALT_GIOCATORE = 30;
var X_GIOCATORE = 300;
var Y_GIOCATORE = 1100;
var VEL_GIOCATORE = 10;
function mostra_giocatore() {
if (NodoGiocatore === null) {
NodoGiocatore = document.createElement('div');
NodoGiocatore.setAttribute ('id', 'player');
NodoCampo.appendChild (NodoGiocatore);
}
NodoGiocatore.style.marginLeft = (X_GIOCATORE - LARG_GIOCATORE) + 'px';
NodoGiocatore.style.marginTop = (Y_GIOCATORE - ALT_GIOCATORE) + 'px';
}
function muovi() {
if (Left) {
X_GIOCATORE = X_GIOCATORE - VEL_GIOCATORE;
//aggiorno immagine
mostra_giocatore();
}
else if (Right) {
X_GIOCATORE = X_GIOCATORE + VEL_GIOCATORE;
//aggiorno immagine
mostra_giocatore();
}
}
function stop() {
Left = false;
Right = false;
}
function interfaccia(e) {
//freccia sinstra
if (e.keyCode === 37) {
X_GIOCATORE = X_GIOCATORE - VEL_GIOCATORE;
//aggiorno immagine
mostra_giocatore();
}
//freccia destra
else if (e.keyCode === 39) {
X_GIOCATORE = X_GIOCATORE + VEL_GIOCATORE;
//aggiorno immagine
mostra_giocatore();
}
}
function inizia() {
mostra_giocatore();
requestAnimationFrame(muovi);
}
window.document.onkeypress = interfaccia;
window.document.onkeyup = stop;
Your choppy movement is likely a result of the amount you are moving the player on each frame with VEL_GIOCATORE. Try reducing this amount to observe smoother movement.
The delay you are experiencing is likely due to your operating system or browsers individual settings on how key presses should repeat. You can work around this by implementing your own key tracking -- it looks like you've started to experiment with this. Track the state of your left and right keys by updating a boolean value in onkeydown and onkeyup event listeners.
var keys = {
left: false,
right: false
};
window.document.onkeydown = function (e) {
if (e.keyCode === 37) {
keys.left = true;
} else if (e.keyCode === 39) {
keys.right = true;
}
window.document.onkeyup = function (e) {
if (e.keyCode === 37) {
keys.left = false;
} else if (e.keyCode === 39) {
keys.right = false;
}
Then, in your muovi function, check the state of these variables to determine if you should update the position of the player.
While using the mobile mode in Chrome dev tools, everything works fine. However, as soon as I upload my code to the server and try it on my iPhone, it is unresponsive.
Here is the a link to the unresponsive app and below is the code for my event listeners..
Link: Running App
Code:
// touch timer to stop and start
time.addEventListener('touchstart', (e) => {
if (running === false){
running = true;
timer = setInterval(startTimer, 100);
}
else {
running = false;
clearInterval(timer);
}
});
// touch '+' to increase speed by 0.5 mph
up.addEventListener('touchstart', (e) => {
mph += 0.5;
speed.innerHTML = `${mph.toFixed(1)} mph`
});
// touch '-' to decrease speed by 0.5 mph
down.addEventListener('touchstart', (e) => {
if (mph >= 0.5){
mph -= 0.5;
speed.innerHTML = `${mph.toFixed(1)} mph`
}
});
//Gathers start position for finger swipe
speedRow.addEventListener('touchstart', (e) => {
xStart = e.changedTouches[0].pageX;
});
// Swipe finger to change speed
speedRow.addEventListener('touchmove', (e) => {
e.preventDefault();
xEnd = e.changedTouches[0].pageX;
if (xStart < xEnd){
mph += (Math.abs(xEnd - xStart)/1500)
}
else if (xStart > xEnd && mph > 0) {
mph -= (Math.abs(xEnd - xStart)/1500)
}
speed.innerHTML = `${mph.toFixed(1)} mph`
});
Not sure if this answers your question, but mac desktop safari is throwing an error when your JS loads because "speed" is already a property on window that it doesn't want overwritten. It's likely that iOS safari is throwing the same error. EDIT: And that error may be stopping code execution.
You should either namespace all those constants in an object. Or wrap all of your code in an iffy to prevent that. You can't be sure what properties will already exist in the global context.
Update:
Also, on the live site you're not passing 'e' in the 'touchstart' listener for speedRow, that could also be stopping execution on iOS safari.
UPDATE WITH THE ACTUAL ANSWER
Just tested the live site on my iPhone. iOS safari is erroring and stopping execution because you're trying to overwrite the global time variable. Looks like it's working in chrome because Chrome doesn't have a global time variable. If you wrap your code in a iffy like this it will work:
(function () {var mili = 0;
var sec = 0;
var min = 0;
var running = false;
var timer;
var mph = 0;
var distanceTraveled = 0;
var xStart;
var xEnd;
const navbar = document.getElementById('navbar');
const time = document.getElementById('time');
const elapsedTime = document.getElementById('time');
const up = document.getElementById('increase');
const down = document.getElementById('decrease');
const runSpeed = document.getElementById('speed');
const distance = document.getElementById('distance');
const speedRow = document.getElementById('speedRow');
function startTimer(){
mili += 100;
if (mili > 999){
mili = 0;
sec +=1;
distanceTraveled += (1/3600) * mph;
if (sec > 59){
sec = 0;
min += 1;
}
}
if (sec < 10){
var strSec = `0${sec}`;
}
else{
strSec =`${sec}`;
}
if (min < 10){
var strMin = `0${min}`;
}
else{
strMin =`${min}`;
}
if(mili < 100){
if(mili === 0){
strMili = '00'
}
else{
var strMili = `${mili}`;
strMili = strMili.slice(0, -1);
strMili = `0${strMili}`;
}
}
else{
strMili = `${mili}`;
strMili = strMili.slice(0, -1);
}
elapsedTime.innerHTML = `${strMin}:${strSec}:${strMili}`;
distance.innerHTML = `${distanceTraveled.toFixed(2)} miles`;
}
time.addEventListener('touchstart', () => {
if (running === false){
running = true;
timer = setInterval(startTimer, 100);
}
else {
running = false;
clearInterval(timer);
}
});
up.addEventListener('touchstart', () => {
mph += 0.5;
runSpeed.innerHTML = `${mph.toFixed(1)} mph`
});
down.addEventListener('touchstart', () => {
if (mph >= 0.5){
mph -= 0.5;
runSpeed.innerHTML = `${mph.toFixed(1)} mph`
}
});
speedRow.addEventListener('touchstart', (e) => {
xStart = e.changedTouches[0].pageX;
});
speedRow.addEventListener('touchmove', (e) => {
e.preventDefault();
xEnd = e.changedTouches[0].pageX;
if (xStart < xEnd){
mph += (Math.abs(xEnd - xStart)/1500)
}
else if (xStart > xEnd && mph > 0) {
mph -= (Math.abs(xEnd - xStart)/1500)
}
runSpeed.innerHTML = `${mph.toFixed(1)} mph`
});
})()
If you have a mac you can use desktop Safari's inspector to debug mobile safari.
I have this event to turn my music of by fading it out
$(bgMusic).on('timeupdate', function () {
var vol = 1,
interval = 250;
if (bgMusic.volume == 1) {
var intervalID = setInterval(function () {
if (vol > 0) {
vol -= 0.05;
bgMusic.volume = vol.toFixed(2);
} else {
clearInterval(intervalID);
}
}, interval);
}
});
I now want the same thing for turning the music on.
I have tried creating the opposite like this:
$(bgMusic).off('timeupdate', function () {
var vol = 0,
interval = 250;
if (bgMusic.volume == 0) {
var intervalID = setInterval(function () {
if (vol < 0) {
vol += 0.05;
bgMusic.volume = vol.toFixed(2);
} else {
clearInterval(intervalID);
}
}, interval);
}
});
Where am I going wrong?
If you change:
if (vol < 0) {
to:
if (vol < 1) {
... I think the volume should gradually increase until it meets it maximum value of 1, hence giving you the "fade in" effect you ask for.
Not sure about your code but I think you don't want to use the off function in your second example.
jQuery off:
Description: Remove an event handler.
So try your second code with on to, since you want to register to the event, not remove it.
since your vol is 0 , it doesnot goes inside the if condition.. if (vol < 0) {...
it should be
if (vol < 1) {
vol += 0.05;
bgMusic.volume = vol.toFixed(2);
} else {
clearInterval(intervalID);
}