PDA

View Full Version : Scroll Support to Script in FireFox



sirluck
03-10-2012, 03:51 AM
This script works perfectly in Internet Explorer. It causes a pair of eyes to follow and draw close to your cursor. It works in Firefox until you scroll (no matter the method), then it begins staying the distance you scrolled away from your cursor.
It can be viewed in action at http://www.kingofspaders.com/paranoia.htm.
Obviously, the scrolling isn't being handled correctly. Does someone know how to fix this?


<script>
var brOK = true, mie = false;
//if (document.layers || document.all) brOK = true;
if (document.all) mie = true;
var ex = 0, ey = 0;
var ae, le, re, x0, y0, tid, realx, realy;
function navMove(e) {
ex = e.clientX;
ey = e.clientY;
moveeye()
return routeEvent(e);
}
function mieMove() {
ex = document.body.scrollLeft + event.x;
ey = document.body.scrollTop + event.y;
moveeye();
}
function moveeye() {
dy = ey - y0 - 20;
dx1 = ex - x0 - 20;
dx2 = ex - x0 - 60;
r = Math.sqrt(dx1 * dx1 + dy * dy);
if (r < 20) r = 20;
dx1 = dx1 * 10 / r + x0 + 10;
dy1 = dy * 10 / r + y0 + 10;
r = Math.sqrt(dx2 * dx2 + dy * dy);
if (r < 20) r = 20;
dx2 = dx2 * 10 / r + x0 + 50;
if(!mie){
ae.style.left = x0;
ae.style.top = y0;
le.style.left = dx1;
le.style.top = dy1;
re.style.left = dx2;
re.style.top = dy1;
} else {
ae.left = x0;
ae.top = y0;
le.left = dx1;
le.top = dy1;
re.left = dx2;
re.top = dy1;
}
}
function setHandlers() {
if (!mie) {
y0 = 100;
x0 = 200;
ae = document.getElementById("eyeballs");
le = document.getElementById("lefteye");
re = document.getElementById("righteye");
window.addEventListener('mousemove', navMove, false);
//window.onMouseMove = navMove;
}
else {
y0 = document.all.eyeballs.style.pixelTop;
x0 = document.all.eyeballs.style.pixelLeft;
ae = document.all.eyeballs.style;
le = document.all.lefteye.style;
re = document.all.righteye.style;
window.document.onmousemove = mieMove;
}
realx = x0 + 0.1;
realy = y0 + 0.1;
moveall();
}
function moveall() {
rx = realx + 40;
ry = realy + 40;
rx += (ex - rx) * 0.1;
ry += (ey - ry) * 0.1;
realx = rx - 40;
realy = ry - 40;
x0 = Math.round(realx);
y0 = Math.round(realy);
moveeye();
tid = setTimeout('moveall()', 100);
}
function placeeyes(x, y) {
if (brOK) {
ex = x + 40;
ey = y + 40;
s = '<DIV ID ="dummy" STYLE="position:absolute; ' +
'top:'+y+'; left:'+x+'; width:10; height:10;"> </DIV>';
s += '<DIV ID="eyeballs" STYLE="position:absolute; ' +
'top:'+y+'; left:'+x+'; width:80; height:40;"><IMG SRC=' +
'"http://www.parrfunding.com/kingofspaders/images/new/whites.gif" border=0></DIV>';
s += '<DIV ID="lefteye" STYLE="position:absolute; ' +
'top:'+(y+10)+'; left:'+(x+10)+'; width:20; height:20;">' +
'<IMG SRC="http://www.parrfunding.com/kingofspaders/images/new/pupil.gif" border=0></DIV>';
s += '<DIV ID="righteye" STYLE="position:absolute; ' +
'top:'+(y+10)+'; left:'+(x+50)+'; width:20; height:20;">' +
'<IMG SRC="http://www.parrfunding.com/kingofspaders/images/new/pupil.gif" border=0></DIV>';

//document.writeln(s);
var eyeContainer = document.createElement("div");
eyeContainer.setAttribute('id', 'eyeContainer');
document.body.appendChild(eyeContainer);
document.getElementById('eyeContainer').innerHTML = s;
}
}
function clearEyes() {
if (tid) clearTimeout(tid);
}
// End -->
</script>
</head>
<body>


<script>
placeeyes(200, 100);
window.onload = setHandlers;
window.onunload = clearEyes;
</script>

jscheuer1
03-10-2012, 07:02 AM
As this version had problems, I've removed it. See the finished version (post #5 in this thread).

sirluck
03-10-2012, 03:45 PM
Thanks for that massive re-write! Did you happen to test it? If you test it on a long page and then scroll, it still has the problem of moving further and further from the cursor.

sirluck
03-10-2012, 04:17 PM
Does it need "DOMMouseScroll" commands? (not that I know how to do that)

jscheuer1
03-10-2012, 05:34 PM
It could, but that gets complicated as it's not just Firefox that's affected and that event isn't cross browser compatible and there are other ways to scroll the page than with the mouse. Getting Firefox and other non-IE browsers to follow the page scroll when calculating the mouse position is relatively easy. The tricky part was getting those others to follow the page scroll when the mouse wasn't changing position. IE can do this natively as it's scroll event returns x and y coords. But those others do not, so we have to 'do the math' for them.

This seems pretty good, try it:


<!DOCTYPE html>
<html>
<head>
<title>Googly Eyes - Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- The following googly eyes script was updated to make it cross browser compatible by makh5gsv at freelancer.com -->
<!-- Original: demigod@psxexchange.com -->
<!-- Web Site: http://www.psxexchange.com -->
<!-- currently hosted at javascriptsource.com -->
<!-- Updated Mar/10/2012 by jscheuer1 see: http://www.dynamicdrive.com/forums/showthread.php?t=67914 -->
<script>
;(function(){
var whites = 'whites.gif'; // set path to whites of the eyes image
var pupil = 'pupil.gif'; // set path to pupil image
var lastex = 200; // set iniital coords (lastex = horizontal, lastey = vertical)
var lastey = 100;

var ieEvent = typeof event !== 'undefined' && !window.opera, eyeContainer, addEvent, ex = 0, ey = 0,
ae, le, re, x0, y0, tid, realx, realy, s, r, dy1, dy2, dx1, dx2, rx, ry;

function ieCompatMode(){
return document.compatMode && document.compatMode === 'CSS1Compat'? document.documentElement : document.body;
}

function navMove(e){
eyeContainer.style.visibility = '';
e = window.event || e;
if(e.type === 'mouseover' && window.removeEventListener){setTimeout(function(){removeEventListener('mouseover', navMove);}, 0);}
if(e.type === 'scroll' && typeof e.pageX !== 'number' && typeof e.clientX !== 'number'){
lastex = ex = lastex + pageXOffset;
lastey = ey = lastey + pageYOffset;
} else {
lastex = ex = typeof e.pageX === 'number'? e.pageX : e.clientX + ieCompatMode().scrollLeft;
lastey = ey = typeof e.pageY === 'number'? e.pageY : e.clientY + ieCompatMode().scrollTop;
}
lastex -= window.pageXOffset || 0;
lastey -= window.pageYOffset || 0;
moveEyes();
}

function moveEyes(){
dy1 = ey - y0 - 20;
dx1 = ex - x0 - 20;
dx2 = ex - x0 - 60;
r = Math.sqrt(dx1 * dx1 + dy1 * dy1);
if (r < 20) {r = 20;}
dx1 = dx1 * 10 / r + x0 + 10;
dy2 = dy1 * 10 / r + y0 + 10;
r = Math.sqrt(dx2 * dx2 + dy1 * dy1);
if (r < 20) {r = 20;}
dx2 = dx2 * 10 / r + x0 + 50;
ae.left = x0 + 'px';
ae.top = y0 + 'px';
le.left = dx1 + 'px';
le.top = dy2 + 'px';
re.left = dx2 + 'px';
re.top = dy2 + 'px';
}

function setHandlers(){
var divs = eyeContainer.getElementsByTagName('div');
y0 = 100;
x0 = 200;
ae = divs[0].style;
le = divs[1].style;
re = divs[2].style;
addEvent(document, 'mousemove', navMove);
addEvent(window, 'scroll', navMove);
if(!ieEvent){
addEvent(window, 'mouseover', navMove);
setTimeout(function(){window.scrollBy(1, 1); window.scrollBy(-1, -1);}, 0);
}
realx = x0 + 0.1;
realy = y0 + 0.1;
moveAll();
}

function moveAll(){
rx = realx + 40;
ry = realy + 40;
rx += (ex - rx) * 0.1;
ry += (ey - ry) * 0.1;
realx = rx - 40;
realy = ry - 40;
x0 = Math.round(realx);
y0 = Math.round(realy);
moveEyes();
tid = setTimeout(moveAll, 100);
}

function placeEyes(e){
var x = lastex, y = lastey;
ex = x + 40;
ey = y + 40;
s = '<div style="position: absolute;' +
'top: ' + y + 'px; left: ' + x + 'px;"><img style="display: block;" alt="" src=' +
'"' + whites + '"></div>';
s += '<div style="position: absolute; ' +
'top: ' + (y + 10) + 'px; left: ' + (x + 10) + 'px;">' +
'<img style="display: block;" alt="" src="' + pupil + '"></div>';
s += '<div style="position: absolute; ' +
'top: ' + (y + 10) + 'px; left: ' + (x + 50) + 'px;">' +
'<img style="display: block;" alt="" src="' + pupil + '"></div>';
eyeContainer = document.createElement("div");
if(ieEvent){eyeContainer.style.visibility = 'hidden';}
document.body.appendChild(eyeContainer);
eyeContainer.innerHTML = s;
setHandlers();
}

function clearEyes(){tid && clearTimeout(tid);}

addEvent = (function(){
return ieEvent && window.attachEvent? function(el, ev, f){
el.attachEvent('on' + ev, f);
} : window.addEventListener? function(el, ev, f){
el.addEventListener(ev, f, false);
} : function(){return;};
})();
addEvent(window, 'load', placeEyes);
addEvent(window, 'unload', clearEyes);
})();
</script>
</head>
<body>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>

There's one subtle difference between IE and the others, but it's hard to notice and not very material. Can you tell what it is?

sirluck
03-10-2012, 07:57 PM
No, I can't spot the difference. It's perfect for my needs. Many Thanks! Donation Sent.

jscheuer1
03-11-2012, 12:01 AM
Thanks! I had actually found an event (mouseover) for Firefox to use onload to allow it to respond immediately the way IE does. So there's virtually no difference in it and IE. But other browsers don't fire onmouseover until the mouse is moved, so for them it starts out with the eyes just hanging there (well I got them to move around a little initially) at first instead of following the mouse right away if it's on the page.

I updated the code in the post but left the question because it was still valid, just even more subtle in Firefox.

I've also discovered a way to eliminate browser sniffing and make the initial positioning more easily configured. I'm updating the code from my previous post with that now.