Moving images with MouseWheel - javascript

I am trying to move an image from side to side using the mousewheel. The image by default is set to absolute position and left=100px. It is not allowing for the scroll to move the image with the parseInt but if I take that out it moves immediately to left=0px. I want to be able to move it a few pixels for each wheel click.
window.onload = function() {
if (document.body.addEventListener) {
document.body.addEventListener("mousewheel", MouseWheelHandler, false);
document.body.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
}
else document.body.attachEvent("onmousewheel", MouseWheelHandler);
function MouseWheelHandler(e){
// cross-browser wheel delta
var e = window.event || e; // old IE support
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
img1.style.left = Math.max(0, Math.min(1100, parseInt(img1.style.left) + (delta))) + "px";
return false;
}
};

Don't use that event! It's not well supported and could give you headaches.
https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/mousewheel

Related

Slide content based on the speed of the mouse

I have this carousel type item:
http://codepen.io/r3plica/pen/xOpzqK?editors=1111
What I am trying to do now, is change it's behaviour. I would like the drag to know the speed of the mouse and try to mimic the scroll to that speed. When I let go of the mouse I want the slider to continue sliding but slow down over a period of time.
My first step was trying to get the actual speed of the mouse, so I did this:
var eventHandler = function (e) {
var event = _options.event;
var timestamp = new Date().getTime();
var touches = event.touches = e.originalEvent !== undefined ? e.originalEvent.touches : null;
if (e.type === 'mousedown') {
// Assign the timer to our event
event.timer = $timeout(function () {
// If we have not already enabled the event
if (!event.enabled) {
// Set our startX and the time
event.startX = touches ? touches[0].pageX : e.clientX;
event.timestamp = timestamp;
//console.log(event);
// Enable our drag
event.enabled = true;
}
}, 100);
}
if (e.type === 'mousemove' && event.enabled) {
// Get our old position
var x = event.currentX;
//console.log(timestamp);
//console.log(event.timestamp);
//console.log('calc', timestamp - event.timestamp);
// Update our current position and speed
event.currentX = touches ? touches[0].pageX : e.clientX;
event.distance = event.currentX - (x || event.startX);
event.time = timestamp - event.timestamp;
event.timestamp = timestamp;
event.speed = (event.distance / event.time) * $window.innerWidth;
//console.log('distance', event.distance);
//console.log('time in seconds', event.time);
//console.log('speed', event.speed);
//console.log('------');
// Work out our offset
var offset = event.currentX / $window.innerWidth;
console.log(offset);
// If we have not started
if (!event.started) {
// Set our initial start position
event.xOffset = offset;
// Initial our position
event.oldX = event.pageX;
// Set to started
event.started = true;
}
// Udpate our position
event.pageX = (offset - event.xOffset) + event.oldX;
// Set our new offset
event.xOffset = offset;
// Update our element
_updateDragElement(_options.element, event);
// Update our old position
event.oldX = event.pageX;
}
if (['mouseup', 'mouseout'].indexOf(e.type) > -1) {
// Clear our timer
$timeout.cancel(event.timer);
//console.log(event);
// If our data is set
if (event.enabled) {
// Unset it
event.enabled = false;
}
// Stop the drag
event.start = false;
}
}
I will break this down into the events
Mouse down
As you can see from the eventHandler when the mousedown event is triggered, a start position startX is recorded along with the current timestamp.
Mouse move
When the mousemove event is triggered I check to see if we are already moving by getting the value in currentX. I then set currentX, the distance travelled (current position minus the last position OR the start position if there is no current position.) Then I work out the time and record the current timestamp and finally I work out the speed.
I then get the xOffset by dividing currentX by the width of the window.
If the animation has not started I set the xOffset and set the oldX to the current pageX and then I start the animation.
The pageX is worked out by xOffset minus the current xOffset plus the oldX, then I update the new xOffset.
Then I update the element with the new transform and finally set my oldX to the current pageX.
Mouse up
For this I just disable and stop the animation.
Problem
The problem I have is that the speed is very low, so the animation doesn't work well.
I decided to multiple the speed by the window width but the animation is no better because it just jerks around.
I think I am doing my calculations incorrectly so I was hoping someone could take a look and give me some advice.
I checked your codepen, your calculation looks fine. Only transition property seems to be missing for the scrolling element, try giving transition property to .pk-slider-base class.
.pk-slider .pk-slider-base {
-webkit-transition: all 2s ease;
transition: all 2s ease;
}
You can also try adding transition using Javascript in your updateView().
Please see below:
function updateView() {
"use strict";
finalX = pageX * mySpeed;
console.log('X', pageX);
console.log('speed', mySpeed);
yourTrans = 'translateX(' + finalX + 'px)';
yourElement.style.transform = yourTrans;
/*Adding transition*/
yourElement.style.WebkitTransition = "all 2s";
yourElement.style.transition = "all 2s";
}

Use mouse movement for change level/window in AMI Medical Imaging (AMI) JS ToolKit

I'm playing a bit with AMI Medical Imaging (AMI) JS ToolKit. Is there a way to move the windowing to a mouse event like right click & move?
I know that it's possible to change window/level with the menus on the examples, but I would like to change the controller to do it moving the mouse.
Thanks!
To control the window/level by moving the mouse you will have to listen to the mousemouve event then update the stackHelper -> slice -> windowWidth/Center as you wish.
You could enable window/level if the user press shift:
var drag = {
x: null,
y: null
}
var shiftDown = false;
function onKeyPressed(event){
shiftDown = event.shiftKey;
if(!shiftDown){
drag.x = null;
drag.y = null;
}
}
container.addEventListener('keydown', onKeyPressed);
container.addEventListener('keyup', onKeyPressed);
Then update the window/level on mouse move:
function onMouseMove(event){
if(!shiftDown || !stack || !stackHelper){
return;
}
if(drag.x === null){
drag.x = event.offsetX;
drag.y = event.offsetY;
}
var threshold = 15;
var dynamicRange = stack.minMax[1] - stack.minMax[0];
dynamicRange /= container.clientWidth;
if(Math.abs(event.offsetX - drag.x) > threshold){
// window width
stackHelper.slice.windowWidth += dynamicRange * (event.offsetX - drag.x);
drag.x = event.offsetX;
}
if(Math.abs(event.offsetY - drag.y) > threshold){
// window center
stackHelper.slice.windowCenter -= dynamicRange * (event.offsetY - drag.y);
drag.y = event.offsetY;
}
}
container.addEventListener('mousemove', onMouseMove);
See a live demo at (shift + mouse move to control the window level):
http://jsfiddle.net/vabL3qo0/41/

Only execute a function if body class exists

I have a body class like this:
<body class="horizontal">
I try to target with the following code:
'use strict';
// Horizontal scrolling
// http://www.dte.web.id/2013/02/event-mouse-wheel.html
(function() {
if(document.body.className === 'horizontal') {
alert('It exists');
function scrollHorizontally(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
// Scroll to the left or right in `document.documentElement` and `document.body`
document.documentElement.scrollLeft -= (delta * 75); // Multiplied by 75
document.body.scrollLeft -= (delta * 75); // Multiplied by 75
e.preventDefault();
}
if (window.addEventListener) {
window.addEventListener('mousewheel', scrollHorizontally, false); // IE9, Chrome, Safari, Opera
window.addEventListener('DOMMouseScroll', scrollHorizontally, false); // Firefox
} else {
window.attachEvent('onmousewheel', scrollHorizontally); // IE 6/7/8
}
};
})();
But this is just not working. The alert not popping up. I would like to prefer a pure javascript solution, to not include Jquery because of this.
EDIT: I uncommented the horizontal scroller function, then it's working. So the script is causing the issue.
The entire script is called at the bottom of the body.
just remove "'use strict';" and it will work see this

How to Recreate the Android Facebook app's view swiping UX?

I'm looking to make something exactly like Facebook's Android app's UX for swiping between News Feed, Friend Requests, Messages, and Notifications. You should be able to "peek" at the next view by panning to the right of left, and it should snap to the next page when released if some threshold has been passed or when swiped.
Every scroll snap solution I've seen only snaps after the scrolling stops, whereas I only ever want to scroll one page at a time.
EDIT: Here's what I have so far. It seems to work fine when emulating an Android device in Google Chrome, but doesn't work when I run it on my Galaxy S4 running 4.4.2. Looking into it a bit more, it looks like touchcancel is being fired right after the first touchmove event which seems like a bug. Is there any way to get around this?
var width = parseInt($(document.body).width());
var panThreshold = 0.15;
var currentViewPage = 0;
$('.listContent').on('touchstart', function(e) {
console.log("touchstart");
currentViewPage = Math.round(this.scrollLeft / width);
});
$('.listContent').on('touchend', function(e) {
console.log("touchend");
var delta = currentViewPage * width - this.scrollLeft;
if (Math.abs(delta) > width * panThreshold) {
if (delta < 0) {
currentViewPage++;
} else {
currentViewPage--;
}
}
$(this).animate({
scrollLeft: currentViewPage * width
}, 100);
});
In case anyone wants to do this in the future, the only way I found to actually do this was to manually control all touch events and then re-implement the normally-native vertical scrolling.
It might not be the prettiest, but here's a fiddle to what I ended up doing (edited to use mouse events instead of touch events): http://jsfiddle.net/xtwzcjhL/
$(function () {
var width = parseInt($(document.body).width());
var panThreshold = 0.15;
var currentViewPage = 0;
var start; // Screen position of touchstart event
var isHorizontalScroll = false; // Locks the scrolling as horizontal
var target; // Target of the first touch event
var isFirst; // Is the first touchmove event
var beginScrollTop; // Beginning scrollTop of ul
var atanFactor = 0.6; // atan(0.6) = ~31 degrees (or less) from horizontal to be considered a horizontal scroll
var isMove = false;
$('body').on('mousedown', '.listContent', function (e) {
isMove = true;
isFirst = true;
isHorizontalScroll = false;
target = $(this);
currentViewPage = Math.round(target.scrollLeft() / width);
beginScrollTop = target.closest('ul').scrollTop();
start = {
x: e.originalEvent.screenX,
y: e.originalEvent.screenY
}
}).on('mousemove', '.listContent', function (e) {
if (!isMove) {
return false;
}
e.preventDefault();
var delta = {
x: start.x - e.originalEvent.screenX,
y: start.y - e.originalEvent.screenY
}
// If already horizontally scrolling or the first touchmove is within the atanFactor, horizontally scroll, otherwise it's a vertical scroll of the ul
if (isHorizontalScroll || (isFirst && Math.abs(delta.x * atanFactor) > Math.abs(delta.y))) {
isHorizontalScroll = true;
target.scrollLeft(currentViewPage * width + delta.x);
} else {
target.closest('ul').scrollTop(beginScrollTop + delta.y);
}
isFirst = false;
}).on('mouseup mouseout', '.listContent', function (e) {
isMove = false;
isFirst = false;
if (isHorizontalScroll) {
var delta = currentViewPage * width - target.scrollLeft();
if (Math.abs(delta) > width * panThreshold) {
if (delta < 0) {
currentViewPage++;
} else {
currentViewPage--;
}
}
$(this).animate({
scrollLeft: currentViewPage * width
}, 100);
}
});
});

Google maps api V3 - zoom on mouse wheel only if ALT key is pressed

I use google map api v3 in my website: the map is width 100% and height 450px. So, when you scroll the page, it will automatically stop on the map because of the mousewheel event to zoom the map. I don't want to disable it because it's kind of a cool feature so I was looking for a way to zoom on mouse wheel only if ALT key is pressed. First, I did it with jQuery like this:
<div id="my_map" class="Scrollable"
onmouseover="hover_div['my_map']=true;" onmouseout="hover_div['my_map']=false;">
"hover_div" is a global array defined in the head, "map" is a global variable (with "scrollwheel" set to false)
$('.Scrollable').on('DOMMouseScroll mousewheel', function(ev) {
if(ev.altKey && hover_div['my_map']){
var $this = $(this),
scrollTop = this.scrollTop,
scrollHeight = this.scrollHeight,
height = $this.height(),
delta = (ev.type == 'DOMMouseScroll' ?
ev.originalEvent.detail * -40 :
ev.originalEvent.wheelDelta),
up = delta > 0;
var prevent = function() {
ev.stopPropagation();
ev.preventDefault();
ev.returnValue = false;
return false;
}
if (!up && -delta > scrollHeight - height - scrollTop) {
$this.scrollTop(scrollHeight);
var mapZoom = parseFloat(map.getZoom());
if(mapZoom > 0){
mapZoom = mapZoom - 1;
map.setZoom(mapZoom);
}
return prevent();
} else if (up && delta > scrollTop) {
$this.scrollTop(0);
var mapZoom = parseFloat(map.getZoom());
if(mapZoom < 21){
mapZoom = mapZoom + 1;
map.setZoom(mapZoom);
}
return prevent();
}
}
});
It's working, but it zoom from the center without considering the mouse position as the default event does.
I found this fiddle who trigger the Google Maps mouse wheel event: maybe there's a way to launch the default event only if the ALT key is pressed, but I haven't figured it out yet.

Categories

Resources