We help IT Professionals succeed at work.

Help with displaying sprite images

Hello all experts.

I have created a sprite image that is made up of three images (pic attached).

The main image is of a car, the second image the same car with the color of the bumper in red and the third image is of the same car with the color of the front grill in red.

I have this CSS that goes with this sprite.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Sprites</title>
  <style type="text/css">
    div {
        background: url('result.png');
    }
  </style>
</head>
<body>
  
  
<br /><br /><div style="background-position: -0px -0px; width: 264px; height: 214px">&nbsp;</div>
<br /><br /><div style="background-position: -0px -224px; width: 264px; height: 214px">&nbsp;</div>
<br /><br /><div style="background-position: -0px -448px; width: 264px; height: 214px">&nbsp;</div>
 
 
</body>
</html>

Open in new window



But I have no idea how to implement this.

All I want is when the mouse goes over the bumper of the first main image of the car, it will turn red.  And if the mouse goes over the front-grill of the first main image it will turn red.

Any help will be greatly appreciated.

--d.

Car Sprite
Comment
Watch Question

Anuradha GoliSystems Development / Support Specialist

Commented:
You should check out this plugin:

http://plugins.jquery.com/project/maphilight

and the demo:

http://davidlynch.org/js/maphilight/docs/demo_usa.html

if anything, you might be able to borrow some code from it to fix yours.

Author

Commented:
Thanx for the response but I am not using an imagemap.

My programming skills are not deft enough to figure out and customize other quasi-related code.

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Awsome question. Try this - you can refine the co-ords by using the first image in the sprite and finding positions on the image using image editor.

Arrays are x values and y values so create your pairs and modify.

I put the image in an images subfolder relative to main page

The pnpoly function I got here (http://www.electrictoolbox.com/jquery-mouse-co-ordinates-mouseover-click-within-element/).

It takes 5 params
npol - number of points in the arrays
xp => array of xpoints
yp => array of ypoints
x => x of point you are testing for
y => y of point you are testing for
function returns true / false if point is in specified poly.

<!doctype html> 
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Sprites</title>
  <script type="text/javascript" src="js/jquery.js"></script>
  <style type="text/css">
    div {
      background: url('images/result.png') no-repeat;
      width: 264px;
      height: 215px;
    }
  </style>
<script type="text/javascript">
var bumperx = [29,29,231,231,227,227,183,167,93,80,39,34];
var bumpery = [104,165,165,103,103,124,131,150,150,131,125,102];
var grillx = [74,94,165,187];
var grilly = [106,145,145,106];
$(function() {
  $('div').mousemove(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
    if (result) {
      $(this).css({backgroundPosition: '0 -224px'});
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        $(this).css({backgroundPosition: '0 -448px'});
      }
      else {
        $(this).css({backgroundPosition: '0 0'});
      }
    }
  });
});
function pnpoly(npol,xp,yp,x,y)
{
  var i, j, c = 0;
  
  for (i = 0, j = npol-1; i < npol; j = i++) {
    if ((((yp[i] <= y) && (y < yp[j])) ||
      ((yp[j] <= y) && (y < yp[i]))) &&
      (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
    c =!c;
  }
  
  return c;
}
</script>
</head>
<body>
  
<div>&nbsp;</div>
 
 
</body>
</html>

Open in new window

Author

Commented:
Thanx for the response julianH.  You have obviously put some work into this.

But the mouseon effect is not working.

I copied your code to a file and only the main image of the car is showing up.  No matter where I place my cursor on the car, the color is not changing to red.

Best,

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Probably because you don't have the JQuery library loaded

Replace the
<script src="js/jquery.js"></script>

Open in new window

With this
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

Open in new window

See demo here
http://www.marcorpsa.com/ee/t12.html (this is a temporary URL - it will be removed after the question is closed)

Author

Commented:
Yes, that was it.  Nice job.  Thank you.

One follow-up question:

Would you please change your code to reflect a div that shows up next to the highlighted section with some text in it....??

For example:

Cost to replace: $40.

Thank you again.

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Do you mean a different div for bumpers and grills i.e. hover over bumpers a div shows with cost for the bumper, if you hover over grill then different div shows with cost?

basically add the two div's and hide them

<div id="bumpercost" class="costdiv">Cost to replace $40</div>
<div id="grillcost" class="costdiv">Cost to replace $50</div>

In the javascript for each of the conditions testing for bumper grill simply add

$(function() {
  $('div').mousemove(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
    if (result) {
      $(this).css({backgroundPosition: '0 -224px'});
      $('#bumpercost').show(); // If this is a bumper hover - show the cost div for bumper
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        $(this).css({backgroundPosition: '0 -448px'});
        $('#grillcost').show(); // if this is a grill hover show the cost div for grill
      }
      else {
        $(this).css({backgroundPosition: '0 0'});
        $('.costdiv').hide(); // if no hover on either hide the cost div
      }
    }
  });
});

Open in new window


Stype the div's to appear how and where you want them to be - you did not specify so I have not coded them.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Here is a full listing of a tooltip type of implementation

<!doctype html> 
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Sprites</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
  <style type="text/css">
    div {
      background: url('images/result.png') no-repeat;
      width: 264px;
      height: 215px;
    position: relative;
    }
    .costdiv {
      display: none;
      background: #ffffaa;
      color: #333;
      position: absolute;
      top: 0;
      left: 0;
      border: 1px solid #333;
      height: auto;
      width: auto;
      min-width: 135px !important;
    }
  </style>
<script type="text/javascript">
var bumperx = [29,29,231,231,227,227,183,167,93,80,39,34];
var bumpery = [104,165,165,103,103,124,131,150,150,131,125,102];
var grillx = [74,94,165,187];
var grilly = [106,145,145,106];
$(function() {
  $('div').mousemove(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
    if (result) {
      $(this).css({backgroundPosition: '0 -224px'});
    $('#bumpercost').show().css({left: (x+5)+'px', top: (y-10)+'px'});
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        $(this).css({backgroundPosition: '0 -448px'});
    $('#grillcost').show().css({left: (x+5)+'px', top: (y-10)+'px'});
      }
      else {
        $(this).css({backgroundPosition: '0 0'});
    $('.costdiv').hide();
      }
    }
  });
});
function pnpoly(npol,xp,yp,x,y)
{
  var i, j, c = 0;
  
  for (i = 0, j = npol-1; i < npol; j = i++) {
    if ((((yp[i] <= y) && (y < yp[j])) ||
      ((yp[j] <= y) && (y < yp[i]))) &&
      (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
    c =!c;
  }
  
  return c;
}
</script>
</head>
<body>
  
<div>
  <div id="bumpercost" class="costdiv">Cost to replace $40</div>
  <div id="grillcost" class="costdiv">Cost to replace $50</div>
</div>
  
</body>
</html>

Open in new window

Author

Commented:
julianH, you are a genius.

That was exactly what I was looking for.

One last question, I promise:  Is there any way to make the highlighted section clickable to a different page in a separate window..??

I want to show them the cost via the tooptip and then click the damaged section of the car and take them to the page which has the form that they use to send me the details.

Indebted to you.

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Yes you can.

Add this to your $(function() { }); declaration
$(function() {
  ...
    $('div').click(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
    if (result) {
      window.location='bumper.html';
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        window.location="grid.html";
      }
    }
  });

Open in new window

Author

Commented:
This is almost working.

Now, if my mouse goes on the high-lighted section, it automatically takes me to the referenced page.  I want it to be clicked before it makes that transition.  Also, can it open in a new window??

This is the total code as of now:

<!doctype html> 
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Sprites</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
  <style type="text/css">
    div {
      background: url('result.png') no-repeat;
      width: 264px;
      height: 215px;
    position: relative;
    }
    .costdiv {
      display: none;
      background: #ffffaa;
      color: #333;
      position: absolute;
      top: 0;
      left: 0;
      border: 1px solid #333;
      height: auto;
      width: auto;
      min-width: 135px !important;
    }
  </style>
<script type="text/javascript">
var bumperx = [29,29,231,231,227,227,183,167,93,80,39,34];
var bumpery = [104,165,165,103,103,124,131,150,150,131,125,102];
var grillx = [74,94,165,187];
var grilly = [106,145,145,106];
$(function() {
  $('div').mousemove(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
	
	    if (result) {
      window.location='bumper.html';
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        window.location="grid.html";
      }
    }

	
    if (result) {
      $(this).css({backgroundPosition: '0 -224px'});
    $('#bumpercost').show().css({left: (x+5)+'px', top: (y-10)+'px'});
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        $(this).css({backgroundPosition: '0 -448px'});
    $('#grillcost').show().css({left: (x+5)+'px', top: (y-10)+'px'});
      }
      else {
        $(this).css({backgroundPosition: '0 0'});
    $('.costdiv').hide();
      }
    }
  });
});
function pnpoly(npol,xp,yp,x,y)
{
  var i, j, c = 0;
  
  for (i = 0, j = npol-1; i < npol; j = i++) {
    if ((((yp[i] <= y) && (y < yp[j])) ||
      ((yp[j] <= y) && (y < yp[i]))) &&
      (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
    c =!c;
  }
  
  return c;
}
</script>
</head>
<body>
  
<div>
  <div id="bumpercost" class="costdiv">Cost to replace $40</div>
  <div id="grillcost" class="costdiv">Cost to replace $50</div>
</div>
  
</body>
</html>

Open in new window


Thanx julianH.

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
Ok you added the code incorrectly your javascript should look like this (the .click is spearate from the mouseover)

I have changed to make it open in new window.

In theory you can do all of this with an image map and a lot less Javascript code - but this works.
<script type="text/javascript">
var bumperx = [29,29,231,231,227,227,183,167,93,80,39,34];
var bumpery = [104,165,165,103,103,124,131,150,150,131,125,102];
var grillx = [74,94,165,187];
var grilly = [106,145,145,106];
$(function() {
  $('div').mousemove(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
    if (result) {
      $(this).css({backgroundPosition: '0 -224px'});
    $('#bumpercost').show().css({left: (x+5)+'px', top: (y-10)+'px'});
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        $(this).css({backgroundPosition: '0 -448px'});
    $('#grillcost').show().css({left: (x+5)+'px', top: (y-10)+'px'});
      }
      else {
        $(this).css({backgroundPosition: '0 0'});
    $('.costdiv').hide();
      }
    }
  });

// Note: completely separate event handler.

  $('div').click(function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    result = pnpoly(12, bumperx, bumpery, x, y);
    if (result) {

      // Open in new window

      window.open("bumper.html", "_blank");
    }
    else {
      result = pnpoly(4, grillx, grilly, x, y);
      if (result) {
        window.open("grid.html", "_blank");
      }
    }
  });
});
function pnpoly(npol,xp,yp,x,y)
{
  var i, j, c = 0;
  
  for (i = 0, j = npol-1; i < npol; j = i++) {
    if ((((yp[i] <= y) && (y < yp[j])) ||
      ((yp[j] <= y) && (y < yp[i]))) &&
      (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
    c =!c;
  }
  
  return c;
}
</script>

Open in new window

Author

Commented:
Perfect.  Thank you so much.

I had thought about doing this all using imagemaps, but I was unsure how to change the highlight..??  So do I have create three separate image maps (original and the 2 highlighted ones) and then the mouseonover routine calls the appropriate one...???

My ignorance is getting in my way again.

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
There is a way of using image maps but that is a whole different exercise because you have to either manipulate images (rather than backgrounds) or put the imagemap on a transparent image and manipulate backgrounds based on that.

I started working on a solution but have not finished it.

Author

Commented:
Thank you so much for your time.

You deserve all the points and more....[:0)

Will let you know if I make another post about using image maps.

Regards,

--d.

Author

Commented:
julianH is a true Expert.  There is nothing this Expert cannot cook up if you ask nicely....[:0)

Author

Commented:
julianH, how did you get those co-ordinates:

var bumperx = [29,29,231,231,227,227,183,167,93,80,39,34];
var bumpery = [104,165,165,103,103,124,131,150,150,131,125,102];
var grillx = [74,94,165,187];
var grilly = [106,145,145,106];

Open in new window


Will you please show me how??  I do not have any of the expensive imaging programs like Photoshop or Illustrator.

Is there a free program that I can use...??  And what are those numbers exactly...??  You were so exact in getting the borders of the red parts right.  And how in the world do you know which are X and which are Y co-ordinates...???

Thanx as always,

--d.
SILVER EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Thanks for the points and the comments - appreciate it.

Re the image co-ords:

I opened the image in Gimp used the select tool and clicked out a path around the bumper and grill making a note of the x / y offset for each click.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.