Help modifying a JavaScript script - javascript

I have found a script that adds mouse trail on Opera's mouse gesture. Very nice done but with one problem. It detects when the mouse button is down and starts to draw a line BUT it doesn't detect when the mouse button is released. The trail is displayed for an amount of time (1 second). Can the script be updated so that the trail is present on screen as long as the button mouse is pressed ?
The script was found in http://extendopera.org/userjs/content/gesture-tails
var GestureTrail={
//options:
opacity:1,
color:'#f27',
canvas:null,
_2d:null,
start:null,
cur:null,
isdown:false,
init:function(){
/* create a transparent canvas element the size of
the full window and insert it into the document */
var canvas=document.createElement('canvas');
canvas.height=window.innerHeight;
canvas.width=window.innerWidth;
document.body.appendChild(canvas);
canvas.style="position:fixed;top:0;display:none;z-index:-999;left:0;opacity:"+this.opacity+";";
this.canvas=canvas;
/* grab the 2d methods for the canvas element */
this._2d=this.canvas.getContext('2d');
window.addEventListener("mousemove",function(e){GestureTrail.draw(e);},0);
window.addEventListener("mouseup",function(e){GestureTrail.release();},0);
},
click:function(e){
if(e.button!=2){return true;} // if not rightclick
this.start={x:e.clientX,y:e.clientY}; // set the line start-point to the mouse position
this._2d.strokeStyle=this.color;
this.isdown=true;
setTimeout(function(){GestureTrail.release();},1000); // thanks to Somh for thinking of this
},
draw:function(e){
if(!this.isdown){return;} // if the mouse isn't down
this.canvas.style.zIndex="999"; // bring the canvas element to the top
this.canvas.style.display="block"; /* (must be done on move - if done on mousedown
it obscures text selection (HotClick) context menu) */
this.cur={x:e.clientX,y:e.clientY}; // set point to begin drawing from
this._2d.beginPath();
this._2d.moveTo(this.start.x,this.start.y);
this._2d.lineTo(this.cur.x,this.cur.y);
this._2d.stroke();
this.start=this.cur; /* sets the startpoint for the next mousemove to the
current point, otherwise the line constantly restarts
from the first point and you get a kind of fan-like pattern */
},
release:function(){
this._2d.clearRect(0,0,window.innerWidth,window.innerHeight); // wipe the trails from the entire window
this.isdown=false;
this.canvas.style.zIndex="-999"; // send the canvas element back down below the page
}
};
window.opera.addEventListener("BeforeEvent.mousedown",function(e){GestureTrail.click(e.event);},0);
window.addEventListener('DOMContentLoaded',function(){GestureTrail.init();},0);

remove:
setTimeout(function(){GestureTrail.release();},1000); // thanks to Somh for thinking of this
thats at the end of the click function. that should be all
but that is a site for real programming questions, not for customers to look for programms to do their work without payment

Related

javascript addEventListener "wheel" for element still scrolls window

I have the following javascript code, which triggers when a user wants to view a large image:
var divOverlay = document.getElementById ("overlay");
divOverlay.style.visibility = "visible";
divOverlay.addEventListener ("wheel", zoom); // respond to mouse wheel
The function zoom() is working fine. It handles events from the mouse wheel and zooms in or out for the image, contained in "overlay".
The problem is that the mouse wheel events are also causing scrolling of the whole browser window. I want the mouse wheel events to go only to "overlay".
I have tried adding this:
origOnWheel = window.onwheel;
window.onwheel = function() { return false; }
followed, later, with restoring window.onWheel when the user is done. That partially works: it prevents the window from scrolling then the user is zooming "overlay". However, when the user finishes (and window.onWheel is restored), the main browser window no longer scrolls with the mouse wheel.
It will be a bit hard to give a complete (working) example without a working jsfiddle, but here are the guidelines:
Inside the zoom function - when you want to prevent the regular scroll of the page - you should use event.preventDefault()
You will need to decide if you want to disable the default scroll - basically this will be based on the height of the image vs. the height of the window (window.innerHeight). In case the height of the image is larger - you should not use the event.preventDefault() or do the prevent default and set the window.scrollTo(x, y) where the y should be the height of image - the height of the window (this will scroll to the bottom of the image).

Dragging elements

Im just wondering whether its possible to drag images/elements (whether inside a div or not) where the image/element is dragged to the far left and comes in from the right side of the screen - therefore dragging the image/element left to get the same result, or vice versa.
Similar to the google maps (on zoom level 1) the user can continuously drag the image left or right, and those images are on a continuous loop.
If so, what languages would you recommend using? javascript?
I hope this makes sense.
Many thanks
This is certainly possible using Javascript. Just have two copies of the image, and as you slide the images left, move the second copy to the right side. (Or vice versa if sliding right).
You can add event handlers to any element, including your images, that execute code while dragging. I apologize for not providing a complete working solution, I am pressed for time, I hope this helps as a starting point
var myGlobals = {
state: {
dragging: false;
}
};
$('.carouselImg').on('mousedown', function(e){
myGlobals.state.dragging = true;
});
$(window).on('mouseup', function(e){
// stop movement even if mouseup happens somewhere outside the carousel
myGlobals.state.dragging = false;
});
$(window).on('mousemove', function(e){
// allow user to drag beyond confines of the carousel
if(myGlobals.state.dragging == true){
recalculateCarouselPosition(e);
}
});
function recalculateCarouselPosition(e){
// These fun bits are left as an exercise for the reader
// the event variable `e` gives you the pixel coordinates where the mouse is
// You will have to do some math to determine what you need to do after this drag.
// You may want to store the coordinates of the initial click in
// `myGlobals.dragStart.x, .y` or similar so you can easily compare them
// You will probably set a negative CSS margin-left property on some element
// of your carousel.
// The carousel will probably have overflow:hidden.
// You will also have to manipulate the DOM, by adding a duplicate image to the
// opposite end and deleting the duplicates once they have scrolled out of view
};

Raphael JS - Start/Continue animating during mouseover. Pause animation on mouseout

Using Raphael JS, is there a way to make a circle move to the right (or any direction) during mouseover, and then pause/stop the movement when the cursor is no longer on the circle.
I've tried few different methods, but they have bugs. One of the main issues is: if the mouse cursor doesn't move after entering the circle, "mouseout" will not be triggered once the circle moves to a location where the mouse cursor is no longer over top of the circle.
You'll see what I mean in these different attempts:
1) Animate with pause / resume:
jsfiddle.net/fKKNt/
But the animation is jerky and unreliable. If you hover over the object, as the object moves outside of where the mouse cursor is, it doesn't trigger the "mouseout" listener.
2) Repositioning with mouseover & .attr("cx"):
jsfiddle.net/c4BFt/
But we want the animation to continue while the cursor is in the circle too.
3) Using setInterval (as suggested in:
An "if mouseover" or a "do while mouseover" in JavaScript/jQuery):
jsfiddle.net/9bBcm/
But "mouseout" is not called as the circle moves outside of where the cursor lies. I.e. the circle move to a location where "mouseout" should be called, but it is not called.
The same thing happens with "hover":
jsfiddle.net/STruB/
I'm sure there's a much more elegant way to do this, but off the top of my head, you could try something like this: http://jsfiddle.net/D6Ps4/2/
In case that disappears for some reason, I've included the code below. The solution simply initiates the animation, then checks to see if the mouse cursor (note the e.offsetX/e.offsetY) is within the bounding box of your Raphael Object (Element.getBBox()) at some set interval. If it is, do nothing and use setTimeout to check again in some time, if it's not, pause the animation.
var paper = Raphael("holder");
var animObject = Raphael.animation({cx: 400}, 5000);
circle = paper.circle(90, 90, 45).attr({fill: "#0E4"});
var timer;
circle.mouseover(function(e) {
var anim = function(shouldAnim) {
if (shouldAnim) {
circle.animate(animObject);
}
if (!mouseInsideCircle(e, circle)) {
circle.pause();
return;
} else {
timer = setTimeout(function() {anim(false)}, 20);
}
}
anim(true);
});
circle.mouseout(function() {
this.pause();
clearTimeout(timer);
});
var mouseInsideCircle = function(e, c) {
var bb = c.getBBox();
if (e.offsetX > bb.x && e.offsetY > bb.y) {
return true;
}
return false;
}
I'm sure the solution is flawed (it's checking the boundBox, not the circle itself; it also assumes the circle is moving right) and perhaps not ideal, but it seems to work reasonably smoothly and hopefully gets you on the right path.

Drag mouse events jittery - onmousemove

Working on a scrub bar for a chromeless player through youtube. I have the functionality working pretty much as Id like BUT when I click to drag the blue "seeker" button and drag it, it jumps back to its original position until I release the mouse click. Once I release, it starts the video at the appropriate position and draws the progress bar at the appropriate position too. code is here: http://jsfiddle.net/VysBU/1/
I also logged the position of the mouse and width of the progress bar (which is the part that jumps around) and the width values move consistently upward or downward on drag which doesn't make sense because visually, it jumps back and forth. Odd.
Any help is appreciated...if you need me to clarify something, let me know.
NOTE: just remembered...it tends to jump on vertical mouse movements only. ie, if i move the mouse horizontally without changing its vertical position at all, it 'animates' fine. if the vertical position does move, the 'animations' are erratic.
Check this out http://jsfiddle.net/sz4FF/
you need to stop the interval of
setInterval(animateProgress, 100);
when you begin seeking, and continue it when the seeking stops. The reason why it makes that jump is simply because animateProgress is called and sets the width of the playedBar and seeker.
I hastily added it to a global function (window.TEST_INTERVAL) just to check if it would work, and it does.
(how to initialize and clear the interval)
clearInterval(TEST_INTERVAL);
TEST_INTERVAL = setInterval(animateProgress, 100);
within seeking
function seeking(e){
clearInterval(TEST_INTERVAL);
within doneSeeking
function doneSeeking(e){
TEST_INTERVAL = setInterval(animateBuffer, 250);
UPDATE: IE8 and below problem
mousePos = e==undefined ? event.clientX : e.pageX;
//get the position of the mouse
//mousePos = e.pageX;
the event returned by onmousemove is "undefined" in ie7 and 8, that way we are checking for window.event.clientX, which shows the mouse position relative to the window. It seems to work fine but I believe that in a normal environment some minor tweaks might be needed

Custom cursor outside of browser window

I have a element on my website which is freely resizable. This is done by 4 handles on the edges. On hovering these handles and while resizing the element I want to show the respective resize arrows.
Currently I implemented this behavior by setting the css cursor style of the body/root to these arrows. The problem about it is the limit to the client area of the browser window. It would be visually more consistent and less confusing, if the arrow cursor would be visible everywhere while the mouse is hold down.
Google Maps is doing the same thing with their hand cursor while moving the map. So my question is how to achive this effect on my own.
My current (relevant) source:
function startObjectScaling(e){
e.stopPropagation();
e.preventDefault();
document.documentElement.style.cursor = this.style.cursor;
window.addEventListener("mouseup", stopObjectScaling, false);
}
function stopObjectScaling(e){
e.stopPropagation();
document.documentElement.style.cursor = '';
window.removeEventListener("mouseup", stopObjectScaling);
}
[...]
var tg = document.getElementById("transformGadget");
var handle = tg.firstChild.nextSibling;
for(var i=0;i<4;i++){
handle.addEventListener("mousedown", startObjectScaling, false);
handle = handle.nextSibling;
}
There is a special function implemented in the more modern browsers for this purpose. The name is setCapture(). It redirects all mouse input to the object the method was called on. Now a simple css cursor definition on that element is enough to archive the desired effect. After mouse release this effect stops (for security for sure). It can also be stopped manually by calling releaseCapture
example:
<style type="text/css">
#testObj {
/* this cursor will also stay outside the window.
could be set by the script at the mousedown event as well */
cursor: hand;
}
</style>
[...]
document.getElementById('testObj').onmousedown = function(e){
// these 2 might be useful in this context as well
//e.stopPropagation();
//e.preventDefault();
// here is the magic
e.target.setCapture();
}
if the arrow cursor would be visible everywhere while the mouse is hold down.
You're relying on a potential OS quirk to create your behavior. This is not something you can ASSUME will always hold true. However, once you start a mousedown, the cursor at that point will normally stay the same, no matter where you move the mouse to, UNTIL something else (another window that you may mouse over? the desktop? a system-interrupt?) changes the cursor.
In other words, don't rely on this behavior. Find something else that will work for you. If you must do this, re-examine your business requirements.

Categories