How to implement touch controls on my code? - javascript

How I put in my funtion moveBloco() to control the white bars through the touch.
I want to make the white bars touchable for a smarthphone user. To move the bars up and down through the touch.
function moveBloco(){
if(87 in keyBoard && left.y > 0)
left.y -= left.speed;
if(83 in keyBoard && left.y + left.altura < canvas.height)
left.y += left.speed;
if(38 in keyBoard && right.y >0)
right.y -= right.speed;
if(40 in keyBoard && right.y + right.altura < canvas.height)
right.y += right.speed;
};
https://jsfiddle.net/bd7v016e/1/

You need to handle touch using TouchEvents. You'll have to add 3 more event listeners corresponding to touchstart, touchmove, and touchend. For a touch you can get the pageX and pageY. You'll have to convert these to position relative to the canvas and apply your logic for moving the bars up or down.
document.addEventListener("touchstart", handleTouchStart, false);
document.addEventListener("touchend", handleTouchMove, false);
document.addEventListener("touchend", handleTouchEnd, false);
var touchPosition = {
x: 0,
y: 0
};
function handleTouchStart(e) {
e.preventDefault();
touchPosition.x = e.changedTouches[0].pageX;
touchPosition.y = e.changedTouches[0].pageY;
var canvasPosition = canvas.getBoundingClientRect();
if (touchPosition.x - canvasPosition.left > canvas.width/2) {
// Trigger Right Bar
if (touchPosition.y - canvasPosition.top > right.y) {
// Move Down the Right Bar
}
else {
// Move Up the Right Bar
}
}
else {
// Trigger Left Bar and apply same logic as above
if (touchPosition.y - canvasPosition.top > right.y) {
// Move Down the left bar
}
else {
// Move Up the left bar
}
}
}
function handleTouchMove(e) {
// Handle When User drags along the touch point
}
function handleTouchEnd(e) {
// Handle Touch End
}

Related

How can I stop slider moved by mouse wheel at the last image?

I am working on a multi-image slider (i.e. several images appear next to each other at the same time and move together) that can be moved with the mouse wheel. I detect the direction of the mouse wheel (up or down) and the slider moves to the left or the right accordingly. It works quite well, the only problem is that I can't get the last picture to stop at the edge of the slider, so it doesn't jump inside if you roll a bigger with the mouse wheel (same for the first picture if you scroll backwards). I would be really grateful for some assistance. Thank you in advance. This is my JS code:
// move slider on mouse wheel scrolling depending on mouse wheel direction
aboutSliders[i].addEventListener('wheel', () => {
// let slideWidth = firstImg.getBoundingClientRect().width;
// get the first slide's position from left side of screen
let sliderLeft = firstImg.getBoundingClientRect().left;
// get the slider wrapper's position from left side of screen
let sliderWrapperLeft = aboutSliders[i].getBoundingClientRect().left;
// get the last slide's position from left side of screen
let sliderRight = lastImg.getBoundingClientRect().right;
// get the slider wrapper's position from left side of screen
let sliderWrapperRight = aboutSliders[i].getBoundingClientRect().right;
// detect mouse wheel's direction (up or down)
function detectMouseWheelDirection(e) {
var delta = null,
direction = false;
if (!e) {
// if the event is not provided, we get it from the window object
e = window.event;
}
if (e.wheelDelta) {
// will work in most cases
delta = e.wheelDelta / 60;
} else if (e.detail) {
// fallback for Firefox
delta = -e.detail / 2;
}
if (delta !== null) {
direction = delta > 0 ? 'up' : 'down';
}
return direction;
}
function handleMouseWheelDirection(direction) {
// if mousewheel direction is 'down' and the slider wrapper's position is not further to the right than the last slide's, move the slider to the left
if (direction == 'down' && sliderRight >= sliderWrapperRight) {
innerSlider.style.marginLeft = --count * 5 + '%';
// if mousewheel direction is 'up', and the slider wrapper's position is not further to the left than the first slide's, move the slider to the right
} else if (direction == 'up' && sliderLeft <= sliderWrapperLeft) {
innerSlider.style.marginLeft = ++count * 5 + '%';
}
}
document.onmousewheel = function (e) {
handleMouseWheelDirection(detectMouseWheelDirection(e));
};
if (window.addEventListener) {
document.addEventListener('DOMMouseScroll', function (e) {
handleMouseWheelDirection(detectMouseWheelDirection(e));
});
}
});

Control video playback when mouse in defined zone

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);
};

The touch event in my canvas is not working as intended and I am not able to identify the reason why it is not working

So I am currently trying to create a notebook styled module for a web application. Currently it is working perfectly fine with its mouse event but not when using touch events.
//TOUCH LISTENER
theCanvas.addEventListener("touchstart", startT, false);
theCanvas.addEventListener("touchend", endT, false);
theCanvas.addEventListener("touchmove", moveT, false);
//MOUSE LISTENER
theCanvas.addEventListener("mousedown", start);
theCanvas.addEventListener("mouseup", end);
theCanvas.addEventListener("mousemove", move, false);
//MOUSE EVENTS
function start(event) {
if (event.button === MAIN_MOUSE_BUTTON) {
shouldDraw = true;
setLineProperties(theContext);
theContext.beginPath();
let elementRect = event.target.getBoundingClientRect();
theContext.moveTo(event.clientX - elementRect.left, event.clientY - elementRect.top);
console.log(PenType(mode));
}
}
function end(event) {
if (event.button === MAIN_MOUSE_BUTTON) {
shouldDraw = false;
}
}
function move(event) {
if (shouldDraw) {
let elementRect = event.target.getBoundingClientRect();
theContext.lineTo(event.clientX - elementRect.left, event.clientY - elementRect.top);
theContext.stroke()
}
}
//TOUCH EVENTS
function startT(event) {
event.preventDefault();
shouldDraw = true;
setLineProperties(theContext);
theContext.beginPath();
let elementRect = event.target.getBoundingClientRect();
theContext.moveTo(event.clientX - elementRect.left, event.clientY - elementRect.top);
console.log(PenType(mode));
}
function endT(event) {
if (event.touches.length == 1) {
event.preventDefault();
shouldDraw = false;
}
}
function moveT(event) {
if (shouldDraw) {
event.preventDefault();
let elementRect = event.target.getBoundingClientRect();
theContext.lineTo(event.clientX - elementRect.left, event.clientY - elementRect.top);
theContext.stroke()
}
}
While the mouse event is fully functional and allow drawing on the canvas. The touch events has only the a small space near the left and top border of the canvas that can be drawn on, and it is only when u tap on the border, just a dot. It should have worked like the mouse event
Since touch event can handle multiple touch points, the x and y of the fingers are not described by event.clientX and event.clientY like for mouse. Instead you got event.touches which is an array of coordinates. So in your code, everytime you want to handle touch event, just replace event.clientX by event.touches[0].clientX and event.clientY by event.touches[0].clientY (considering you only want to handle one finger of course)

Disable swiping after first swipe, then reset once done?

I have the following code which allows me to swipe an element, and the element will move, revealing the element underneath. I'd like to be able to swipe once, have the function run, have the div reset it's position, and allow me to swipe once again. Basically, disable the swiping while the function is running, then enable it once the function is over.
Here's my code:
var threshold = {
x: 30,
y: 10
}
var originalCoord = {
x: 0,
y: 0
}
var finalCoord = {
x: 0,
y: 0
}
function touchMove(event) {
finalCoord.x = event.targetTouches[0].pageX
changeX = originalCoord.x - finalCoord.x
var changeY = originalCoord.y - finalCoord.y
if (changeY < threshold.y && changeY > (threshold.y * -1)) {
changeX = originalCoord.x - finalCoord.x
if (changeX > threshold.x) {
// My function which runs when you swipe left
}
}
}
function touchEnd(event) {
}
function touchStart(event) {
originalCoord.x = event.targetTouches[0].pageX
finalCoord.x = originalCoord.x
}
window.addEventListener("touchstart", touchStart, false);
window.addEventListener("touchmove", touchMove, false);
window.addEventListener("touchend", touchEnd, false);
I figured I could use event.preventDefault() or return false to disable dragging once the function runs, but it still ends up allowing me to drag during it.
Pretty hard to figure out what do you want, but to disable the swiping just add helper variable:
var _swipeDisabled = false;
then in touchmove check if swiping is disabled, and if so just return false:
function touchMove(event) {
if (_swipeDisabled) return false; // this line is crucial
finalCoord.x = event.targetTouches[0].pageX
changeX = originalCoord.x - finalCoord.x
var changeY = originalCoord.y - finalCoord.y
if (changeY < threshold.y && changeY > (threshold.y * -1)) {
changeX = originalCoord.x - finalCoord.x
if (changeX > threshold.x) {
_swipeDisabled = true; // add this before calling your function
// My function which runs when you swipe left
}
}
}
And in your function you'll have to enable the swiping again, so just do:
_swipeDisabled = false;
in the function you call there. Simpliest solutions are usually the best, remember!
I was able to solve this by removing then adding back in the EventListener:
if (changeX > threshold.x) {
window.removeEventListener('touchmove', touchMove, false);
// Function
setTimeout(function () {
window.addEventListener('touchmove', touchMove, false);
}, 800)
}

Handling swipe in touch devices

I have this horizontal carousel component that I want to make it work for both Mouse and Swipe events.
Everything is working fine, except for one bit: in touch devices, I don't want the carousel to scroll horizontally if the user is trying to swipe vertically to scroll through the whole page.
What I am doing is,
on mousedown/touchstart - I stop the event from propagating to avoid page scroll, item selects, etc...
on the first move event, on the carousel, I set a 50ms timeout to determine if the user is moving vertically or horizontally.
If deltaX < deltaY, I stop my horizontal scrolling, manually fire the touchstart event, with a flag indicating that i fired it manually
on my mousedown/touchstart handler, I read that "manually" flag and, if it's true, I return true from my function so all the default browser events, like the page vertical scrolling, continue to work.
This is not working, everything I'm doing responds correctly but the browser doesn't pick up and scroll the page. I hope I am explaining myself correctly enough so you guys can help me... I don't have an online example because this is a "secret" project for my company...
I was trying to do the same thing as you (were?). The key is to check on touchmove if the current touch and the last touch is more vertical than horizontal. If the touch was more left to right or right to left, prevent the event's default, otherwise ignore it. Here's what I ended up writing. Hopefully it works for you!
var gestures = function() {
var self = this,
coords = {
startX: null,
startY: null,
endX: null,
endY: null
};
self.$el.on('touchstart', function(e) {
coords.startX = e.originalEvent.targetTouches[0].clientX;
coords.startY = e.originalEvent.targetTouches[0].clientY;
coords.endX = coords.startX;
coords.endY = coords.startY;
});
self.$el.on('touchmove', function(e) {
var newX = e.originalEvent.targetTouches[0].clientX,
newY = e.originalEvent.targetTouches[0].clientY,
absX = Math.abs(coords.endX - newX),
absY = Math.abs(coords.endY - newY);
// If we've moved more Y than X, we're scrolling vertically
if (absX < absY) {
return;
}
// Prevents the page from scrolling left/right
e.preventDefault();
coords.endX = newX;
coords.endY = newY;
});
self.$el.on('touchend', function(e) {
var swipe = {},
deltaX = coords.startX - coords.endX,
deltaY = coords.startY - coords.endY,
absX = Math.abs(deltaX),
absY = Math.abs(deltaY);
swipe.distance = (absX > absY) ? absX : absY;
swipe.direction = (absX < absY) ?
(deltaY < 0 ? 'down' : 'up') :
(deltaX < 0 ? 'right' : 'left');
// console.log(swipe.direction + ' ' + swipe.distance + 'px');
// If we have a swipe of > 50px, let's use it!
if (swipe.distance > 50) {
if (swipe.direction === 'left') {
self.advance();
} else if (swipe.direction === 'right') {
self.retreat();
}
}
});
};
this is my slider object and $el is the container element.

Categories