I'm trying to control video playback depending on where my mouse is on screen.
I've split the width of the window into 3 areas - left, centre and right. This works fine so far.
When the mouse is in the 'left' I want to specify to jump to a certain time, same for centre and right.
The issue I'm having is that every time the mouse moves the video playback restarts, I want it to change only when it changes from 'left' to 'right' or 'centre'. I've made a current_pos and new_pos variable but can't figure out how to update them properly.
Many thanks!
PS have left out the video code for now, just trying to get the position working.
var viewport_width = document.documentElement.clientWidth;
var viewport_height = document.documentElement.clientHeight;
var current_pos;
var new_pos;
function getMousePos(e) {
return {x:e.clientX,y:e.clientY};
}
document.onmousemove=function(e) {
var mousecoords = getMousePos(e);
//left
if (mousecoords.x < viewport_width/3){
current_pos = 'left';
//centre
}else if (mousecoords.x > viewport_width/3 && mousecoords.x < viewport_width*.66){
current_pos = 'centre';
//right
}else {
current_pos = 'right';
}
console.log(current_pos);
};
You need to check whether current_pos has been changed every time you attempt to change it.
var viewport_width = document.documentElement.clientWidth;
var viewport_height = document.documentElement.clientHeight;
var current_pos;
function getMousePos(e) {
return {
x: e.clientX,
y: e.clientY
};
}
document.onmousemove = function(e) {
var mousecoords = getMousePos(e);
//left
if (mousecoords.x < viewport_width / 3) {
if(current_pos != 'left') {
current_pos = 'left';
// Play your video from the desired point
}
//centre
} else if (mousecoords.x > viewport_width / 3 && mousecoords.x < viewport_width * .66) {
if(current_pos != 'centre') {
current_pos = 'centre';
// Play your video from the desired point
}
//right
} else {
if(current_pos != 'right') {
current_pos = 'right';
// Play your video from the desired point
}
}
console.log(current_pos);
};
Related
I followed Paul Lewis's guide to debounce and requestAnimationFrame. I'm translating an image across the screen on scroll when it comes into view.
var bicycles = $('.tandem-bike', context),
lastScrollY = 0,
ticking = false;
function update() {
var windowHeight = window.innerHeight,
windowWidth = $(window).width(),
bikeTop = [];
bicycles.each( function (i, el) {
bikeTop[i] = $(this).offset();
});
bicycles.each(function(i, el) {
var position = bikeTop[i];
var fromTop = position.top - windowHeight;
var imgHeight = $(this).height();
// When this image scrolls into view.
if (lastScrollY > fromTop && lastScrollY < position.top + imgHeight && i == 1 ) { // 375 ~= height of image
var translate = Math.floor((lastScrollY - fromTop) / ((windowHeight + imgHeight + 300) / windowWidth));
console.log('add tp tranlate ', translate);
$(this).css('transform', 'translateX(' + (translate - 275) + 'px)');
}
});
ticking = false;
}
function onScroll() {
lastScrollY = window.scrollY;
requestTick();
}
function requestTick() {
if(!ticking) {
requestAnimationFrame(update);
ticking = true;
}
}
window.addEventListener('scroll', onScroll, false);
This works great and the bicycle-built-for-two slides effortlessly across the screen. However, I want the image to "bounce" when the user stops scrolling. I figure an easy way would be to add a class when the animation ends, and pull it off when the animation starts. The obvious place to do that is within the if block in requestTick().
if(!ticking) {
$('.tandem-bike').removeClass('bounce');
requestAnimationFrame(update);
$('.tandem-bike').addClass('bounce');
ticking = true;
}
or
if(!ticking) {
requestAnimationFrame(update);
$('.tandem-bike').addClass('bounce');
ticking = true;
} else {
$('.tandem-bike').removeClass('bounce');
}
}
Neither works, and I don't love then because I'm whole-sale adding classes to all the animated images on the page. (I would live with that if it worked)
I'm attempting to make it, so that when the mouse is within the boundaries set by var play, it changes image. I used the same method I've used for changing images on click, but mouseover and mouseout don't want to work here.
var play = {
x: 650,
y: 360,
width: 200,
height: 100
}
var playUpButton = new Image();
playUpButton.src = "images/PlayUp.png";
var playDownButton = new Image();
playDownButton.src = "images/PlayDown.png";
var playHovering = false;
thisCanvas.addEventListener('click', checkPlay);
thisCanvas.addEventListener('mouseover', hoverPlay, false);
thisCanvas.addEventListener('mouseout', hoverPlay, false);
function seen_move(e)
{
var bounding_box = thisCanvas.getBoundingClientRect();
mouseX = ((e.clientX-bounding_box.left) *(thisCanvas.width/bounding_box.width));
mouseY = ((e.clientY-bounding_box.top) * (thisCanvas.height/bounding_box.height));
}
function draw_start()
{
context.drawImage(menubg, menubg.x, menubg.y, menubg.width, menubg.height);
if(playHovering)
{
context.drawImage(playDownButton, play.x, play.y, play.width, play.height);
}
}
function mouseInArea(top, right, bottom, left)
{
if(mouseX >= left && mouseX < right && mouseY >= top && mouseY < bottom)
{
return true;
}
else
{
return false;
}
}
function hoverPlay()
{
if(mouseInArea(play.y, play.x + play.width, play.y + play.height, play.x))
{
console.log("Hovering");
if(playHovering)
{
playHovering = false;
}
else
{
playHovering = true;
}
}
}
It looks like the following is missing from your code.
var thisCanvas = document.getElementById("thisCanvas");
The function checkPlay also seems to be missing.
Take a look at these articles:
http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
http://www.informit.com/articles/article.aspx?p=1903884&seqNum=6
You must call function seen_move(e) to get the mouse position.
BTW, I'm confused about what the extra code in seen_move is. I'm guessing you're making the mouse position relative to the bounding box. I just mention it in case that's also a problem:
// this usually get the mouse position
var bounding_box = thisCanvas.getBoundingClientRect();
mouseX = e.clientX-bounding_box.left;
mouseY = e.clientY-bounding_box.top;
// and you have this extra bit:
// *(thisCanvas.width/bounding_box.width)); and
// * (thisCanvas.height/bounding_box.height));
mouseX = ((e.clientX-bounding_box.left) *(thisCanvas.width/bounding_box.width));
mouseY = ((e.clientY-bounding_box.top) * (thisCanvas.height/bounding_box.height));
I am a JS noob. I am getting into browser game programming and wanted to make a quick example of a ball dropping and bouncing just to learn. For some reason, when I created a jsfiddle my code actually didn't work, the onclick event for my div id="ball" didn't seem to be attaching, but when I run it in my browser it does. But that is not my question.
In this code, the user clicks the ball, which is just a div with a black bg. The div then follows the users cursor, and when the user clicks a second time, the div begins to fall towards the bottom of the window. When it hits the bottom, it should bounce back up, with an apex half the distance between the y coordinate of where it was originally dropped and the bottom of window. So if it was dropped at y position 600 and the bottom of the page is 800, the apex for the first bounce should be 700. The 2nd bounce, the apex would be 750. 3rd bounce, 775. You get the idea. Can someone help me a bit here? I am guessing I need to increment a counter each time the ball hits the bottom?
<html>
<head>
<style>
#ball {
width: 50px;
height: 50px;
background-color: black;
position: absolute;
}
</style>
<script>
window.onload = function() {
var ballClicked = false;
var ballFalling = false;
var ballX = 100;
var ballY = 100;
var timesBounced = 0;
var bounceApex = 0;
var startingDropHeight = 0;
var intervalVar;
var ball = document.getElementById("ball");
ball.style.left = ballX;
ball.style.top = ballY;
ball.onclick = function() {
if (ballClicked == false) {
ballClicked = true;
} else {
ballClicked = false;
ballFalling = true;
startingDropHeight = ballY;
intervalVar = setInterval(function(){dropBall()} , 5);
}
};
document.onmousemove = function(e) {
if (ballClicked == true) {
ballX = e.pageX;
ballY = e.pageY;
ball.style.left = ballX;
ball.style.top = ballY;
}
};
function dropBall() {
if (ballFalling == true) {
ballY = ballY + 1;
ball.style.top = ballY;
if (ballY == window.innerHeight - 50) {
timesBounced = timesBounced + 1;
bounceApex = (startingDropHeight + (window.innerHeight - 50)) / 2;
ballFalling = false;
if (bounceApex > window.innerHeight - 50) {
clearInterval(intervalVar);
}
};
} else {
ballY = ballY - 1;
ball.style.top = ballY;
if (ballY == bounceApex) {
ballFalling = true;
};
}
};
};
</script>
</head>
<body>
<div id="ball"></div>
</body>
</html>
When adding left and top styles, you need to specify the unit as well. So, instead of:
ball.style.left = 100;
it should be:
ball.style.left = "100px";
I've fixed that in your code and made a working jsfiddle, will improve the bouncing in a bit. See it here: http://jsfiddle.net/12grut99/
About the repetitive bouncing, this line is the issue:
bounceApex = (startingDropHeight + (window.innerHeight - 50)) / 2;
You're always calculating the apex based on the original drop height, yet after every bounce, the drop height should be the previous bounceApex (the highest point the ball reached).
Please help i tried a couple of things but whenever i move the small object to the larger one it gets stuck after collision detection. Here is my code its easy enough to understand.
i have also tried to detect collision detection on individual sides of the other object.
// Setup requestAnimationFrame
requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
// Create the canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// Game objects
var player = {
width:50,
height:50,
x:50,
y:50,
speed:100,
color:'#3C1BE0'
};
var wall={
width:50,
height:150,
x:300,
y:100,
color:'#E01B5D'
};
// Handle keyboard controls
var keysDown = {};
addEventListener("keydown", function (e) {
keysDown[e.keyCode] = true;
},false);
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode];
},false);
//check collisions
var collisions=function(){
}
// Update game objects
var update = function (modifier) {
//test for collisions
//player collision with wall(red cube)
if(player.x+player.width>wall.x &&
player.x<wall.x+wall.width &&
player.y<wall.y+wall.height &&
player.y+player.height>wall.y
)
{
player.speed=0;
}
//player collission with canvas
if(player.x < 0 )
{
player.x=0;
}
else if(player.x+player.width> canvas.width)
{
player.x=canvas.width-player.width;
}
else if(player.y <0 )
{
player.y=0;
}
else if(player.y+player.width>=canvas.height)
{
player.y=canvas.height-player.height;
}
if (38 in keysDown) { // Player holding up
player.y -= player.speed*modifier;
}
if (40 in keysDown) { // Player holding down
player.y += player.speed*modifier;
}
if (37 in keysDown) { // Player holding left
player.x -= player.speed*modifier;
}
if (39 in keysDown) { // Player holding right
player.x += player.speed*modifier;
}
};
// Draw everything
var render = function () {
ctx.clearRect(0,0,600,400);
ctx.fillStyle=wall.color;
ctx.fillRect(wall.x,wall.y,wall.width,wall.height);
ctx.fillStyle=player.color;
ctx.fillRect(player.x,player.y,player.width,player.height);
};
// The main game loop
var main = function () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
render();
then = now;
requestAnimationFrame(main);
};
// Let's play this game!
var then = Date.now();
main();
The issue may be that you are never setting the speed to something above 0 after you have set it to zero on the collision.
if(player.x+player.width>wall.x &&
player.x<wall.x+wall.width &&
player.y<wall.y+wall.height &&
player.y+player.height>wall.y) {
player.speed=0; // this never gets unset
}
You would need to probably figure out where the player wants to go based on the keystroke and calculate a delta. If the delta is allowable (not colliding), then you update the player's position, otherwise you don't apply the delta.
I have found a solution to my problem.I have added the direction of the keyboard to the arguments and created a stand alone collision detection function.if you think i make any improvements to my collision code i would appreciate any useful input.
var collisions=function(sprite1,sprite2){
return sprite1.x < sprite2.x + sprite2.width &&
sprite1.x + sprite1.width > sprite2.x &&
sprite1.y < sprite2.y + sprite2.height &&
sprite1.y + sprite1.height > sprite2.y;
}
if(collisions(player,wall)){
if(player.y+player.height>wall.y &&
40 in keysDown
)
{
player.y=wall.y-player.height;
}
if(player.y<wall.y+wall.height &&
38 in keysDown
)
{
player.y=wall.y+wall.height;
}
if(player.x+player.width>wall.x &&
39 in keysDown
)
{
player.x=wall.x-player.width;
}
if(player.x<wall.x+wall.width &&
37 in keysDown
)
{
player.x=wall.x+wall.width;
}
}
I have a carousel that is working just fine for all browsers and all devices except for ipad/iphone. When I swipe the carousel, it will use jqueries easing and bounce several times before stopping. The only way to make it behave, as it does in all other browsers, is to have an alert message pop up after swiping, then it works perfectly.
[code]
$("#CarouselWrap").bind("touchmove", function(event){
if(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
whichWayMovingX[1] = event.originalEvent.touches[0].pageX;
whichWayMovingY[1] = event.originalEvent.touches[0].pageY;
}else{
whichWayMovingX[1] = event.originalEvent.changedTouches[0].pageX;
whichWayMovingY[1] = event.originalEvent.changedTouches[0].pageY;
}
if(whichWayMovingX[0] > whichWayMovingX[1]){
if(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)){
alert("left");
moveLeft();
}else{
moveLeft();
}
}else{
if(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)){
alert("right");
moveRight();
}else{
moveRight();
}
}
});
[/code]
The moveLeft and moveRight functions are used with the arrows on the left and right of the carousel, so I know that these work, but only for onclick events.
[code]
switch(amountToMove) {
case -1011:
$("#CarouselFeed").animate({marginLeft: amountToMove},{duration: 'slow', easing: 'easeOutBack', wipe:'true'});
[/code]
Why would this code work so well for onclick, but not for touchmove?
I have tried to combine the binds of touchstart, touchend and touchmove - nada
I have tried to use touchmove mousemove - diddlesquat
I have tried to use a setTimeout thinking that I had to wait for the last event - nothing
Please help, this is driving me nuts.
Found the solution via some code for addressing the default behavior of a swipe.
First, set up the listeners:
if(document.getElementById("CarouselFeed")){
$("#CarouselFeed").bind("touchstart", function(event){
touchStart(event,"CarouselFeed")
});
$("#CarouselFeed").bind("touchend", function(event){
touchEnd(event);
});
$("#CarouselFeed").bind("touchmove", function(event){
touchMove(event);
});
}
I found the following code on a web site, that thanked two other web sites for their code and just as that web site changed the code a little to suit their needs, I have done the same:
// TOUCH-EVENTS SINGLE-FINGER SWIPE-SENSING JAVASCRIPT
// Courtesy of PADILICIOUS.COM and MACOSXAUTOMATION.COM
// redefined a few things to make this applicable to our needs
// this script can be used with one or more page elements to perform actions based on them being swiped with a single finger
var triggerElementID = null; // this variable is used to identity the triggering element
var fingerCount = 0;
var startX = 0;
var startY = 0;
var curX = 0;
var curY = 0;
var deltaX = 0;
var deltaY = 0;
var horzDiff = 0;
var vertDiff = 0;
var minLength = 72; // the shortest distance the user may swipe
var swipeLength = 0;
var swipeAngle = null;
var swipeDirection = null;
// The 4 Touch Event Handlers
// NOTE: the touchStart handler should also receive the ID of the triggering element
// make sure its ID is passed in the event call placed in the element declaration, like:
//
var touchStart = function(event,passedName){
// disable the standard ability to select the touched object
// event.preventDefault();
// get the total number of fingers touching the screen
fingerCount = event.originalEvent.touches.length;
// since we're looking for a swipe (single finger) and not a gesture (multiple fingers),
// check that only one finger was used
if(fingerCount == 1){
// get the coordinates of the touch
startX = event.originalEvent.touches[0].pageX;
startY = event.originalEvent.touches[0].pageY;
// store the triggering element ID
triggerElementID = passedName;
}else{
// more than one finger touched so cancel
touchCancel(event);
}
}
var touchMove = function(event){
event.preventDefault();
if ( fingerCount == 1 ){
curX = event.originalEvent.touches[0].pageX;
curY = event.originalEvent.touches[0].pageY;
}else{
touchCancel(event);
}
}
var touchEnd = function(event){
// event.preventDefault();
// check to see if more than one finger was used and that there is an ending coordinate
if (fingerCount == 1 && curX != 0){
// use the Distance Formula to determine the length of the swipe
swipeLength = Math.round(Math.sqrt(Math.pow(curX - startX,2) + Math.pow(curY - startY,2)));
// if the user swiped more than the minimum length, perform the appropriate action
if(swipeLength >= minLength){
caluculateAngle();
determineSwipeDirection();
processingRoutine();
touchCancel(event); // reset the variables
}else{
touchCancel(event);
}
}else{
touchCancel(event);
}
}
var touchCancel = function(event){
// reset the variables back to default values
fingerCount = 0;
startX = 0;
startY = 0;
curX = 0;
curY = 0;
deltaX = 0;
deltaY = 0;
horzDiff = 0;
vertDiff = 0;
swipeLength = 0;
swipeAngle = null;
swipeDirection = null;
triggerElementID = null;
}
var caluculateAngle = function(){
var X = startX-curX;
deltaX = X;
var Y = curY-startY;
var Z = Math.round(Math.sqrt(Math.pow(X,2)+Math.pow(Y,2))); //the distance - rounded - in pixels
var r = Math.atan2(Y,X); //angle in radians (Cartesian system)
swipeAngle = Math.round(r*180/Math.PI); //angle in degrees
if (swipeAngle < 0) {swipeAngle = 360 - Math.abs(swipeAngle);}
}
var determineSwipeDirection = function(){
if( (swipeAngle <= 45) && (swipeAngle >= 0) ){
swipeDirection = 'left';
}else if( (swipeAngle <= 360) && (swipeAngle >= 315) ){
swipeDirection = 'left';
}else if( (swipeAngle >= 135) && (swipeAngle <= 225) ){
swipeDirection = 'right';
}else if( (swipeAngle > 45) && (swipeAngle < 135) ){
swipeDirection = 'down';
}else{
swipeDirection = 'up';
}
}
var processingRoutine = function(){
var swipedElement = document.getElementById(triggerElementID);
if( swipeDirection == 'left' ){
moveLeft();
}else if( swipeDirection == 'right' ){
moveRight();
}else if( (swipeDirection == 'up') || (swipeDirection == 'left') ){
moveLeft();
}else if( (swipeDirection == 'up') || (swipeDirection == 'right') ){
moveRight();
}else if( (swipeDirection == 'down') || (swipeDirection == 'left') ){
moveLeft();
}else if( (swipeDirection == 'down') || (swipeDirection == 'right') ){
moveRight();
}
}
One note, I have this swipe working on a carousel that has banners. In order for the links for the banners to work, you have to comment out the event.preventDefault() within the touchStart and touchEnd functions.
And that is all it takes