Capturing client-side image coordinates

T

Tony Gahlinger

I'm using my browser (Mozilla/5.0 Linux i686 Gecko/20031007 Firebird/0.7)
to do some client-side image processing. I want to capture the sequence of
coordinates a user clicks on in xxx.jpg in the following html

<a href="#"><IMG SRC="xxx.jpg" ISMAP></a>

and save these to a file for later handling. The coordinates appear on
the bottom left of the window as I move the mouse, so I know they're
being passed around somehow, but I haven't figured out how to 'catch'
them. (My apologies if this is a frequent Q. but a web search has led
to an answer). Help much appreciated.

--Tony
 
T

Tony Gahlinger

Tony said:
I'm using my browser (Mozilla/5.0 Linux i686 Gecko/20031007 Firebird/0.7)
to do some client-side image processing. I want to capture the sequence of
coordinates a user clicks on in xxx.jpg in the following html

<a href="#"><IMG SRC="xxx.jpg" ISMAP></a>

and save these to a file for later handling. The coordinates appear on
the bottom left of the window as I move the mouse, so I know they're
being passed around somehow, but I haven't figured out how to 'catch'
them. (My apologies if this is a frequent Q. but a web search has led
to an answer). Help much appreciated.
^^no^^

Oops! (If it led to an answer it was a null one!).

Any suggestions on how to capture/store clicked coordinates? Thanks.

--Tony
 
T

Tony Gahlinger

mscir said:
This uses some mouse tracking code I got from a website, it is used here
as an example, I would recommend looking for a better mouse-tracking
approach, maybe someone here will post a method that doesn't rely upon
browser detection. This works in my IE6, Netscape 7.1, Firefox 0.8 but I
have no idea what other browsers will do, esp. Opera.

What I did here was: track the mouse position, when the image is clicked
send the current mouse coordinates to a function that subtracts the
image position on the page (left, top) to get the image (x, y) position
of the mouse, store those numbers in an array.
...
Good Luck,
Mike

Thanks Mike. That's the part I was looking for.

--Tony
 
D

DU

mscir said:
This uses some mouse tracking code I got from a website, it is used here
as an example, I would recommend looking for a better mouse-tracking
approach, maybe someone here will post a method that doesn't rely upon
browser detection. This works in my IE6, Netscape 7.1, Firefox 0.8 but I
have no idea what other browsers will do, esp. Opera.

What I did here was: track the mouse position, when the image is clicked
send the current mouse coordinates to a function that subtracts the
image position on the page (left, top) to get the image (x, y) position
of the mouse, store those numbers in an array.

I have no idea how to save the array contents to a file, sorry.


<script type="text/javascript">
//TRACK MOUSE BEGIN
// Detect if the browser is IE or not.
// If it is not IE, we assume that the browser is NS.
var IE = document.all?true:false

// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE)

// Set-up to use getMouseXY function onMouseMove
document.onmousemove = getMouseXY;

// Temporary variables to hold mouse x-y pos.s
var tempX = 0
var tempY = 0

// Main function to retrieve mouse x-y pos.s

function getMouseXY(e) {
if (IE) { // grab the x-y pos.s if browser is IE
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else { // grab the x-y pos.s if browser is NS
tempX = e.pageX
tempY = e.pageY
}
// catch possible negative values in NS4
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
// show the position values in the form named Show
// in the text fields named MouseX and MouseY
//document.Show.MouseX.value = tempX
//document.Show.MouseY.value = tempY
return true
}
//TRACK MOUSE END

//array to store mouse coord's
var coords=new Array();

//store mouse coord's in array after normalizing to img top, left

function storepoint(x,y, target){
//alert(x+', '+y+'\nTop '+target.offsetTop+' Left '+target.offsetLeft);
alert((x-target.offsetLeft)+', '+(y-target.offsetTop));
//alert(target.offsetTop);
//alert(document.getElementById('img1').left);
coords[coords.length]=[x-target.offsetLeft,y-target.offsetTop];
}

function showarr(){
var s1='';
for (var i=0; i<coords.length; i++)
s1+='\n'+coords[0]+', '+coords[1];
alert(s1);
}

<img name="img1" id="img1" src="iamges/logo.gif" width="543"
height="113" onmousedown="storepoint(tempX, tempY, this)">
</p>
<p>
<input type="button" value="Show Contents of Array (click coordinates)"
onclick="showarr()">

Good Luck,
Mike


That's awful! With MSIE, all you need to get is the offsetX and offsetY
event properties. That's all: no need for complex equations.
With Opera 7.x, you need to substract the border width from
event.offsetX/Y because there is a bug related to this (bug 123306).

With Mozilla, you need to cumulate the offsetLeft of elements in the
containment hierarchy of the image and then substract from the
evt.pageX/Y because there is no other way to do this in Mozilla.

DU
 
D

DU

Tony said:
I'm using my browser (Mozilla/5.0 Linux i686 Gecko/20031007 Firebird/0.7)
to do some client-side image processing. I want to capture the sequence of
coordinates a user clicks on in xxx.jpg in the following html

<a href="#"><IMG SRC="xxx.jpg" ISMAP></a>

and save these to a file for later handling. The coordinates appear on
the bottom left of the window as I move the mouse, so I know they're
being passed around somehow, but I haven't figured out how to 'catch'
them. (My apologies if this is a frequent Q. but a web search has led
to an answer). Help much appreciated.

--Tony


You first need to set an event listener for the image, like this:

function init()
{
if(document.addEventListener)
{
document.getElementById("idImageToMonitor").addEventListener("mousemove",
TrackCoordinatesInImage, false);
}
else if(window.event && document.getElementById)
{
document.getElementById("idImageToMonitor").onmousemove =
TrackCoordinatesInImage;
};
}

function TrackCoordinatesInImage(evt)
{
var Coordinate_X_InImage, Coordinate_Y_InImage;
Coordinate_X_InImage = Coordinate_Y_InImage = 0;
if(window.event && !window.opera && typeof event.offsetX == "number")
/* MSIE 5+ */
{
var Coordinate_X_InImage = event.offsetX;
var Coordinate_Y_InImage = event.offsetY;
}
else if(document.addEventListener && evt && typeof evt.pageX == "number")
/* Mozilla-based browsers */
{
var Element = evt.target;
var CalculatedTotalOffsetLeft, CalculatedTotalOffsetTop;
CalculatedTotalOffsetLeft = CalculatedTotalOffsetTop = 0;
while (Element.offsetParent)
{
CalculatedTotalOffsetLeft += Element.offsetLeft ;
CalculatedTotalOffsetTop += Element.offsetTop ;
Element = Element.offsetParent ;
};
Coordinate_X_InImage = evt.pageX - CalculatedTotalOffsetLeft ;
Coordinate_Y_InImage = evt.pageY - CalculatedTotalOffsetTop ;
};
}

In your html:

<body onload="init();" ...>

I have pages which uses+explains this code, also for Opera 6.x and Opera
7.x.

DU
 
D

DU

mscir said:
DU wrote:
<snip>

I tried your code, it looks a lot cleaner than the approach I posted,
and it works great in my (Win98 SE) IE6, but not in my Netscape 7.1 or
Firefox 0.8.

innerText is not a W3C DOM 2 attribute nor a DOM 2 CharacterData
attribute. nodeValue though is and it is supported by MSIE 6!

Here's what I did:
function init(){
if(document.addEventListener) {
document.getElementById("idImageToMonitor").addEventListener("mousemove",
TrackCoordinatesInImage, false);
} else if(window.event && document.getElementById) {
document.getElementById("idImageToMonitor").onmousemove =
TrackCoordinatesInImage;
}
}

function TrackCoordinatesInImage(evt){
var Coordinate_X_InImage;
var Coordinate_Y_InImage;
Coordinate_X_InImage = Coordinate_Y_InImage = 0;
if(window.event && !window.opera && typeof event.offsetX == "number") {
// IE 5+
var Coordinate_X_InImage = event.offsetX;
var Coordinate_Y_InImage = event.offsetY;
} else if(document.addEventListener && evt && typeof evt.pageX ==
"number"){
// Mozilla-based browsers
var Element = evt.target;
var CalculatedTotalOffsetLeft, CalculatedTotalOffsetTop;
CalculatedTotalOffsetLeft = CalculatedTotalOffsetTop = 0;
while (Element.offsetParent) {
CalculatedTotalOffsetLeft += Element.offsetLeft ;
CalculatedTotalOffsetTop += Element.offsetTop ;
Element = Element.offsetParent ;
}
Coordinate_X_InImage = evt.pageX - CalculatedTotalOffsetLeft ;
Coordinate_Y_InImage = evt.pageY - CalculatedTotalOffsetTop ;
}
document.getElementById('div1').innerText = "X:
"+Coordinate_X_InImage+" Y: "+Coordinate_Y_InImage;


Change that above line to this:

if(document.getElementById('div1').childNodes[0] &&
document.getElementById('div1').childNodes[0].nodeType == 3)
{
document.getElementById('div1').childNodes[0].nodeValue = "X:
" + Coordinate_X_InImage + " Y: " + Coordinate_Y_InImage;
}

and make sure that div1 is without blank spaces (or is truly the first
text node), like this:
<div id="div1">&nbsp;</div>

and this should work without a problem on all W3C DOM 2 CharacterData
conforming agent (that includes MSIE 6).

Demos:
Performance comparison between innerHTML attribute and DOM's nodeValue
when modifying the text data of a node of type TEXT_NODE
http://www10.brinkster.com/doctorunclear/HTMLJavascriptCSS/innerHTMLvsNodeValue.html

Interactive DOM level 2 CharacterData Interface attributes and methods
tests:
http://www10.brinkster.com/doctorunclear/HTMLJavascriptCSS/DOM2CharacterData.html
}



Would you post the URL with code explanations so I can read up on this?

Thanks,
Mike

Here's a few:

(use MSIE 6 for this link)
http://www10.brinkster.com/doctorunclear/HTMLJavascriptCSS/DUWindowsMSIE6.html


(use a Mozilla-based browser for this link)
http://www10.brinkster.com/doctorunclear/HTMLJavascriptCSS/DUWindowsNS6.html#windowInnerWidthHeight
In the code of that page, I commented the part like this in function
MovesInNS6(evt)

/*
var elem = evt.target ;
var CalculatedTotalOffsetLeft = CalculatedTotalOffsetTop = 0;
while (elem.offsetParent)
{
CalculatedTotalOffsetLeft += elem.offsetLeft;
CalculatedTotalOffsetTop += elem.offsetTop;
elem = elem.offsetParent;
}
*/

and I explained it around the area of the anchor #windowInnerWidthHeight

(use Opera 7 for this link)
http://www10.brinkster.com/doctorunclear/HTMLJavascriptCSS/DUWindowsO7.html

(use Opera 6 for this link)
http://www10.brinkster.com/doctorunclear/HTMLJavascriptCSS/DUWindowsO6.html

(use Opera 7 for this link)
http://www10.brinkster.com/doctorunclear/BrowserBugsSection/Opera7Bugs/Opera7Bugs.html
and go+click item #11- event.offsetX and event.offsetY coordinate
values... for the demo:
http://www10.brinkster.com/doctorunclear/BrowserBugsSection/Opera7Bugs/Opera7BugOffsetXY.html

DU
 
T

Tony Gahlinger

mscir said:
DU wrote:
<snip>

I tried your code, it looks a lot cleaner than the approach I posted,
and it works great in my (Win98 SE) IE6, but not in my Netscape 7.1 or
Firefox 0.8. Here's what I did:

<snip>

Would you post the URL with code explanation so I can read up on this?

Thanks,
Mike

Hmm .. you guys are leaving me in the dust. Do I replace mscir's first code set
entirely with DU's, or do I still need pieces of it? In particular, what would
come after DU's '...' below:
In your html:

<body onload="init();" ...>

Do I still need mscir's storepoint or showarr functions?

I'd also be much interested in DU's code/explanations. Appreciate both your
efforts. Thanks.

--Tony
 
T

Tony Gahlinger

mscir said:
<snip>

Here's one way to use his code, but you still have the problem of
storing the data in a file. Will the web page you want to save the file
from be loaded from a local hard drive, network, or a web site?

Mike
<snip>

Cool! That works great.

Ultimately, the web page will be loaded from a web site, but for testing,
the coordinates are needed by a local C program, so I thought I'd just
dump them to a file.

Thanks a lot for your help.

--Tony
 
D

DU

mscir said:
<snip>

Here's one way to use his code, but you still have the problem of
storing the data in a file. Will the web page you want to save the file
from be loaded from a local hard drive, network, or a web site?

Mike

//global variables
var Coordinate_X_InImage;
var Coordinate_Y_InImage;

function init(){
if(document.addEventListener) {
document.getElementById("idImageToMonitor").addEventListener("mousemove",
TrackCoordinatesInImage, false);
} else if(window.event && document.getElementById) {
document.getElementById("idImageToMonitor").onmousemove =
TrackCoordinatesInImage;
}
}

function TrackCoordinatesInImage(evt){
Coordinate_X_InImage = Coordinate_Y_InImage = 0;
if(window.event && !window.opera && typeof event.offsetX == "number") {
// IE 5+
Coordinate_X_InImage = event.offsetX;
Coordinate_Y_InImage = event.offsetY;
} else if(document.addEventListener && evt && typeof evt.pageX ==
"number"){
// Mozilla-based browsers
var Element = evt.target;
var CalculatedTotalOffsetLeft, CalculatedTotalOffsetTop;
CalculatedTotalOffsetLeft = CalculatedTotalOffsetTop = 0;
while (Element.offsetParent) {
CalculatedTotalOffsetLeft += Element.offsetLeft ;
CalculatedTotalOffsetTop += Element.offsetTop ;
Element = Element.offsetParent ;
}
Coordinate_X_InImage = evt.pageX - CalculatedTotalOffsetLeft ;
Coordinate_Y_InImage = evt.pageY - CalculatedTotalOffsetTop ;
}
document.getElementById('div1').innerHTML = "X:
"+Coordinate_X_InImage+" Y: "+Coordinate_Y_InImage;

If we knew how Tony's HTML code is, then I would suggest to use input
type="text" for these coordinate values. The problem with Mozilla-based
browsers is that you need to do quite a lot of calculations for
determining the offsetTop and offsetLeft values within the containment
hierarchy and since this is a mousemove event, then there is some real
chances of making users with modest system resources crash because of
this. That's why I commented out this code in the NS6.html page. But no
problem like that with Opera 7 and MSIE 6 pages since offsetX and
offsetY can be accessed directly.
Note that I personally don't like innerHTML when entirely W3C compliant
alternatives are available... and in fact more performant too.
}

// array to store mouse click coordinates
var coords=new Array();

function storepoint(x,y){
//uncomment the next line to see each image click's coordinates
//alert(x+', '+y);
coords[coords.length]=[x,y];
}

function showarr(){
var s1='';
for (var i=0; i<coords.length; i++)
s1+='\n'+coords[0]+', '+coords[1];
alert(s1);
}

<body onload="init()" bgcolor="#000000">

<img name="idImageToMonitor" id="idImageToMonitor" src="logo.gif"
width="543" height="113" onmousedown="storepoint(Coordinate_X_InImage,
Coordinate_Y_InImage)">


There is a significant difference (performance and stability
consequences) if the code should work on a mousedown instead of a
mousemove event. This is important to understand. Right now, poorly
coded and non-optimized DHTML mouse trail effects will make NS 6.x, NS
7.x and Mozilla-based browser users more prone to application crashes.

DU
 
T

Tony Gahlinger

mscir said:
I just used this to read and write a local text file with Netscape 7.1.
The browser does popup a window asking permission for each operation,
but it also lets me tell it to remember each decision if I don't want to
see the dialog again.

Mike
---------------------

Captain's Mozilla XUL LOG - read local files and write local files:

Here is a nice example of Mozilla's XUL including reading and writing
from/to local files.

http://www.captain.at/programming/xul/

Great, I'll give it a whirl. This should work better than my current
'..document.write' to an html file and using mouse capture to a disk
file. Thanks Mike.

--Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top