SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Enthusiast
    Join Date
    Sep 2002
    Location
    Melbourne, Australia
    Posts
    82
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Place targets on an image for submission?

    I need to write a script to enable a user to place targets on an image.

    My idea is that I use javascript to overlay target images over my base image. The javascript can have an array to record the target locations and every time this is updated just write that to a hidden form input for submission. The idea is that you simply click to add and remove. So if there is no target within x distance of the users click it will add one, if there is it will grow the targets coverage till it reaches max size (prob 2 or 3 steps) and then any subsequent clicks will remove the target. So I guess there are a few things here that I'll need to know.

    For the moment I'm wondering if anyone knows of any out of the box type things floating around that might be good or at least form a good starting point. I have looked around but come up with nothing, but its hard to find good js sites.

    Otherwise I guess I'll need to work out how to get co-ords of where the user clicks, not too hard. What I have been pondering and have no idea how to do is how to find if there is a target in the array near the user's click co-ords. Yeah I'm not a math wizz!

    I don't want to use flash or java either.
    sigy

  2. #2
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Jixor,

    I couldn't help but play around with your idea a little. Here's the online demo and the source follows. I'm using my Js library, but it should be easy to replace those function calls with whatever library you normally use.

    I had fun playing with it
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>TargetMap Demo</title>
    <style type='text/css'>
    #idMap {
      position: relative;
      overflow: hidden;
      width: 500px;
      height: 400px;
      padding: 0;
      background-color: #ccc;
      border: 1px solid #000;
    }
    .clsTarget {
      position: absolute;
      overflow: hidden;
      width: 20px; /* initial size of target */
      height: 20px;
      padding: 0;
      background-color: #eee;
      border: 1px dotted #900;
    }
    </style>
    <script type='text/javascript' src='../x_core.js'></script>
    <script type='text/javascript' src='../x_event.js'></script>
    <script type='text/javascript'>
    
    var tm1 = new TargetMap('idMap', 'clsTarget', 20, 80);
    
    window.onload = function()
    {
      tm1.onload();
    }
    window.onunload = function()
    {
      tm1.onunload();
      tm1 = null;
    }
    
    // TargetMap Object Prototype
    
    function TargetMap(mapId, tgtCls, tgtInc, tgtMax)
    {
      // Private Properties
    
      var targets = [];
      var zIdx = 0;
    
      // Public Methods
    
      this.onload = function()
      {
        xAddEventListener(mapId, 'click', mapOnClick, false);
      }
      this.onunload = function()
      {
        xRemoveEventListener(mapId, 'click', mapOnClick, false);
        for (var i = 0; i < targets.length; ++i) {
          targets[i] = null;
        }
      }
    
      // Private Event Listener
    
      function mapOnClick(e)
      {
        var i, t, s;
        e = new xEvent(e);
        //alert('page: ' + e.pageX + ', ' + e.pageY + '\noffset: ' + e.offsetX + ', ' + e.offsetY);
        t = e.target;
        if (t && t.className == tgtCls) { // resize or remove target
          s = xWidth(t); // get target size
          if (s + tgtInc <= tgtMax) {
            s += tgtInc;
            xResizeTo(t, s, s); // increase size of target
            xMoveTo(t, xLeft(t) - tgtInc/2, xTop(t) - tgtInc/2);
            xZIndex(t, ++zIdx);
          }
          else { // remove target
            for (i = 0; i < targets.length; ++i) {
              if (targets[i] == t) break;
            }
            if (i < targets.length) {
              targets.splice(i, 1);
              t.parentNode.removeChild(t);
            }
          }
          return;
        }
        else { // add new target
          t = document.createElement('div');
          t.className = tgtCls;
          t = document.getElementById(mapId).appendChild(t);
          targets[targets.length] = t;
          xZIndex(t, ++zIdx);
          s = xWidth(t) / 2;
          xMoveTo(t, e.offsetX - s, e.offsetY - s);
        }
      }
    
    } // end TargetMap
    
    </script>
    </head>
    <body>
    
    <h1>TargetMap Demo</h1>
    
    <div id='idMap'> </div>
    
    </body>
    </html>
    Last edited by MikeFoster; Nov 22, 2006 at 23:39. Reason: bug fix ;)

  3. #3
    SitePoint Enthusiast
    Join Date
    Sep 2002
    Location
    Melbourne, Australia
    Posts
    82
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That is very kewl, thank you very much for that!!

    I'll prob make a couple of little changes, I was thinking it would be more user friendly if you didn't have to click exactly on the target but just near, however I see now that the easiest way to do that is to make the target bigger than what it appears to be. So I'll just place a graphic inside the target and make the target background transparent. I'll also add a line to write the target array out to an input so that you can send the targets to the server, easy.

    Cheers.
    sigy

  4. #4
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great ideas, Jixor.

    Have fun

  5. #5
    SitePoint Enthusiast
    Join Date
    Sep 2002
    Location
    Melbourne, Australia
    Posts
    82
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have made a few additions to the script so that it can load in pre defined targets and such. The only problem is that I'm not sure (because I haven't worked with arrays in JS much) how to correct the problem with removing targets. Currently in your script it removes the elements from the html no worries but it doesn't remove the entry from the array correctly. It just takes off the first entry. "i" is not defined, explaining said behaviour, and I'm not sure what the best way is to go about fixing this. For a start when you use splice() does it rekey the array because if it doesn't that would explain why my method was unsuccessful.
    sigy

  6. #6
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oops! I changed my implementation but forgot about the "i".
    Here's a change - don't have time to test it - be back later
    Code:
          else { // remove target
            for (i = 0; i < targets.length; ++i) {
              if (targets[i] == t) break;
            }
            if (i < targets.length) {
              targets.splice(i, 1);
              t.parentNode.removeChild(t);
            }
          }

  7. #7
    SitePoint Enthusiast
    Join Date
    Sep 2002
    Location
    Melbourne, Australia
    Posts
    82
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yep, that sorted it out no worries, not at all how I was trying to do it.

    Do you know of any good places to find detailed information on dealing with arrays and objects in javascript because really especially coming from php(and asp/vb in the old days... ewwww) I seem to be encountering numerous problems.

    I have to say that without seeing this I would have never thought of storing referances to the elements themselfes in an array. Certainly didn't even know it could be done. But thats fantastic because of course when you modify one of the html elements there is no need to update the array. Very kewl, I think I have underestimated javascript.

    One problem that I was having, that was driving me mad, was that I couldn't get the targets to be saved in the correct location... After about 10 mins of going increasingly mad I realised that I had accidently swapped around the x and y coords.
    sigy

  8. #8
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There's alot of info on Js arrays and objects in this forum, just do some searches. And of course there's so much of it on the web that I don't even know where to start

    Also, there's some great people who hang out in this forum. Feel free to start another thread and ask anything you want.

    Yes, every html element is represented by a Js object as a node in the DOM tree.

    My little demo illustrates many different Js topics: basic array usage, OOP, private properties, and even "closures". Feel free to ask any questions about it.

    Note that the demo uses functions from my Js library. It is fairly easy to replace those function calls with functions from any other library you would like to use.

    All the Best to ya, Jixor


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •