Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 05-23-2011, 11:27 AM   PM User | #1
agkn0001
New to the CF scene

 
Join Date: May 2011
Posts: 3
Thanks: 2
Thanked 0 Times in 0 Posts
agkn0001 is an unknown quantity at this point
best way to create an interactive map with javascript

I need to create an interactive map similar to the one on this site:
http://viewers-guide.hbo.com/game-of-thrones/#!/map/

It is a map of a fictional area ( a real area but there are fictional
buildings and characters on it) so I don't think google maps plugins
are suitable.

I don't want to reinvent the wheel, so if anybody has a good
suggestion of a good jquery/javascript solution for interactive maps,
please refer me to the relevant information.

In other words, I need a map where by clicking the objects on the map,
a popup window pops up with additional information about the 'scene'
or a 'character'.
In addition, the map will be dark from the beginning and more and more
sites and characters will be revealed on it every week.
Thanks for any tips!
agkn0001 is offline   Reply With Quote
Old 05-23-2011, 12:30 PM   PM User | #2
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Here is a straight-forward example which uses HTML image maps and a little bit of JavaScript with this code:
Code:
<img src="image.gif" alt="Image" width="367" height="106" border="0" usemap="#mapname"><br>
<br>
<form name="myform">
<input type="text" name="display" size="20">
</form>
</div>

<script language="javascript">
function showtext(place){
    document.myform.display.value = place
}
</script>

<map name="mapname">
<area shape="polygon" onMouseOver="showtext('Cash_Register')" onMouseOut="showtext('')" alt="Cash" coords="94,10,95,25" href="file1.html">
<area shape="polygon" onMouseOver="showtext('Cellular_Phone')" onMouseOut="showtext('')" alt="Cell Phone" coords="206,2,209,19" href="file2.html">
<area shape="polygon" onMouseOver="showtext('Toy_Box')" onMouseOut="showtext('')" alt="box" coords="356,25,359,75" href="file3.html">
<area shape="default" nohref>
</map>
This could be modified to also use 'onClick' to produce popup windows or tooltips.

I noticed a number of JS/jQuery plug-ins when searching but the basis for them still seems to be HTML image maps.
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Users who have thanked AndrewGSW for this post:
agkn0001 (05-23-2011)
Old 05-23-2011, 01:04 PM   PM User | #3
agkn0001
New to the CF scene

 
Join Date: May 2011
Posts: 3
Thanks: 2
Thanked 0 Times in 0 Posts
agkn0001 is an unknown quantity at this point
image maps

thanks.
I still haven't decided whether I want to develop my own plugin for this specific task, or use an existing more generic solution, such as jmapping, or openlayers, or something like this: /www.gethifi.com/blog/a-jquery-plugin-for-zoomable-interactive-maps#zip.
i guess I will have to start with deciding on all the functionalities I need first but image maps seem like a good option.
agkn0001 is offline   Reply With Quote
Old 05-23-2011, 05:42 PM   PM User | #4
vwphillips
Senior Coder

 
Join Date: Mar 2005
Location: Portsmouth UK
Posts: 4,353
Thanks: 3
Thanked 457 Times in 444 Posts
vwphillips is a jewel in the roughvwphillips is a jewel in the roughvwphillips is a jewel in the rough
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title></title>
<style type="text/css">
/*<![CDATA[*/

#tst {
  position:absolute;overflow:hidden;left:100px;top:100px;width:600px;height:500px;border:solid red 1px;
}

.img {
  position:absolute;left:-600px;top:-100px;width:2800px;height:3076px;border:solid red 1px;
}

.img IMG {
  float:left;
}

#nav {
  position:absolute;z-Index:2;left:0px;top:308px;width:175px;height:192px;border:solid red 1px;background-Image:url(http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map-navigator.jpg);
}

.nav {
  border:solid red 1px;
}

.m1 {
  position:absolute;width:80px;height:20px;border:solid red 1px;background-Color:#FFFFCC;
}

.m2 {
  position:absolute;width:80px;height:20px;border:solid red 1px;background-Color:#FF3366;
}

.pop {
  position:absolute;visibility:hidden;width:200px;height:120px;border:solid red 1px;background-Color:#FFFFCC;
}

/*]]>*/
</style>


</head>

<body>
 <div id="tst" >
  <div class="img" >
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-1.png" />
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-2.png"/>
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-3.png" />
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-4.png" />
   <div id="pop1" class="pop" >Pop 1</div>
   <div id="pop2" class="pop" >Pop 2</div>
  </div>
  <div id="nav" >
   <div class="nav" ></div>
  </div>
 </div>

<script type="text/javascript">
/*<![CDATA[*/
// MapNavigator (23-May-2011) DRAFT
// by Vic Phillips http://www.vicsjavascripts.org.uk

function zxcMapNavigator(o){
 var pobj=document.getElementById(o.ID),img=pobj.getElementsByTagName('DIV')[0],nav=document.getElementById(o.NavID),nobj=nav.getElementsByTagName('DIV')[0],r=img.offsetWidth/nav.offsetWidth,marks=o.Markers,mark,pop,z0=0;
 img.style.position='absolute';
 nobj.style.position='absolute';
 nobj.style.width=pobj.offsetWidth/r+'px';
 nobj.style.height=pobj.offsetHeight/r+'px';
 for (;z0<marks.length;z0++){
  mark=document.createElement('DIV');
  mark.className=marks[z0][0];
  img.appendChild(mark);
  mark.style.left=marks[z0][1]-mark.offsetWidth/2+'px';
  mark.style.top=marks[z0][2]-mark.offsetHeight/2+'px';
  pop=document.getElementById(marks[z0][3]);
  if (pop){
   pop.style.left=marks[z0][1]-pop.offsetWidth/2+'px';
   pop.style.top=marks[z0][2]+marks[z0][4]+'px';
   this.addevt(pop,'mouseup','popclose');
  }
  this.addevt(mark,'mouseup','markpos',[mark,pop]);
 }
 this.lst=false;
 this.img=img;
 this.pobj=pobj;
 this.nav=nav;
 this.nobj=nobj;
 this.r=r;
 this.navpos();
 this.drag=false;
 this.addevt(nobj,'mousedown','ndown');
 this.addevt(img,'mousedown','down');
 this.addevt(document,'mousemove','move');
 this.addevt(document,'mousemove','nmove');
 this.addevt(document,'mouseup','up');
}

zxcMapNavigator.prototype={

 markpos:function(e,mark){
  this.popclose();
  var img=this.img,pobj=this.pobj,m=mark[0],lft=-m.offsetLeft-m.offsetWidth/2+pobj.offsetWidth/2,top=-m.offsetTop+100;
  img.style.left=-m.offsetLeft-m.offsetWidth/2+pobj.offsetWidth/2+'px';
  img.style.top=-m.offsetTop-m.offsetHeight/2+100+'px';
  if (mark[1]){
   mark[1].style.visibility='visible';
   this.lst=mark[1];
  }
  this.navpos();
 },

 popclose:function(){
  if (this.lst){
   this.lst.style.visibility='hidden';
  }
 },

 navpos:function(){
  var img=this.img,nobj=this.nobj,r=this.r;
  nobj.style.left=-img.offsetLeft/r+'px';
  nobj.style.top=-img.offsetTop/r+'px';
 },

 imgpos:function(){
  var img=this.img,nobj=this.nobj,r=this.r;
  img.style.left=-nobj.offsetLeft*r+'px';
  img.style.top=-nobj.offsetTop*r+'px';
 },

 addevt:function(o,t,f,p){
  var oop=this;
  if (o.addEventListener) o.addEventListener(t,function(e){ return oop[f](e,p);}, false);
  else if (o.attachEvent) o.attachEvent('on'+t,function(e){ return oop[f](e,p); });
 },

 mse:function(e){
  if (window.event){
   var docs=[document.body.scrollLeft,document.body.scrollTop];
   if (!document.body.scrollTop){
    docs=[document.documentElement.scrollLeft,document.documentElement.scrollTop];
   }
   return [e.clientX+docs[0],e.clientY+docs[1]];
  }
  return [e.pageX,e.pageY];
 },

 style:function(obj,p){
  if (obj.currentStyle){
   return parseInt(obj.currentStyle[p.replace(/-/g,'')]);
  }
  return parseInt(document.defaultView.getComputedStyle(obj,null).getPropertyValue(p));
 },


 down:function(e){
  document.onselectstart=function(event){
   window.event.returnValue=false;
  }
  this.minX=-this.img.offsetWidth+this.pobj.offsetWidth;
  this.minY=-this.img.offsetHeight+this.pobj.offsetHeight;
  this.lastXY=[e.clientX,e.clientY];
  this.drag=true;
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 move:function(e){
  if (this.drag){
   var mse=[e.clientX,e.clientY],lft=this.style(this.img,'left')+mse[0]-this.lastXY[0],top=this.style(this.img,'top')+mse[1]-this.lastXY[1];
   this.img.style.left=Math.max(Math.min(lft,0),this.minX)+'px';
   this.img.style.top=Math.max(Math.min(top,0),this.minY)+'px';
   this.lastXY=mse;
   this.navpos();
  }
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 ndown:function(e){
  document.onselectstart=function(event){
   window.event.returnValue=false;
  }
  this.maxX=this.nav.offsetWidth-this.nobj.offsetWidth;
  this.maxY=this.nav.offsetHeight-this.nobj.offsetHeight;
  this.lastXY=[e.clientX,e.clientY];
  this.ndrag=true;
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 nmove:function(e){
  if (this.ndrag){
   var mse=[e.clientX,e.clientY],lft=this.style(this.nobj,'left')+mse[0]-this.lastXY[0],top=this.style(this.nobj,'top')+mse[1]-this.lastXY[1];
   this.nobj.style.left=Math.max(Math.min(lft,this.maxX),0)+'px';
   this.nobj.style.top=Math.max(Math.min(top,this.maxY),0)+'px';
   this.lastXY=mse;
   this.imgpos();
  }
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 up:function(e){
  if (this.drag||this.ndrag){
   this.drag=false;
   this.ndrag=false;
   document.onselectstart=null;
  }
 }

}

new zxcMapNavigator({
 ID:'tst',
 NavID:'nav',
 Markers:[
  ['m1',1200,290,'pop1',50],
  ['m2',1200,1290,'pop2',50]
 ]
});
/*]]>*/
</script>


</body>

</html>
the animation and resizing should be easy to add
__________________
Vic

God Loves You and will never love you less.

http://www.vicsjavascripts.org.uk/

If my post has been useful please donate to http://www.operationsmile.org.uk/
vwphillips is offline   Reply With Quote
Users who have thanked vwphillips for this post:
agkn0001 (05-25-2011)
Old 05-25-2011, 04:01 PM   PM User | #5
agkn0001
New to the CF scene

 
Join Date: May 2011
Posts: 3
Thanks: 2
Thanked 0 Times in 0 Posts
agkn0001 is an unknown quantity at this point
Quote:
Originally Posted by vwphillips View Post
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title></title>
<style type="text/css">
/*<![CDATA[*/

#tst {
  position:absolute;overflow:hidden;left:100px;top:100px;width:600px;height:500px;border:solid red 1px;
}

.img {
  position:absolute;left:-600px;top:-100px;width:2800px;height:3076px;border:solid red 1px;
}

.img IMG {
  float:left;
}

#nav {
  position:absolute;z-Index:2;left:0px;top:308px;width:175px;height:192px;border:solid red 1px;background-Image:url(http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map-navigator.jpg);
}

.nav {
  border:solid red 1px;
}

.m1 {
  position:absolute;width:80px;height:20px;border:solid red 1px;background-Color:#FFFFCC;
}

.m2 {
  position:absolute;width:80px;height:20px;border:solid red 1px;background-Color:#FF3366;
}

.pop {
  position:absolute;visibility:hidden;width:200px;height:120px;border:solid red 1px;background-Color:#FFFFCC;
}

/*]]>*/
</style>


</head>

<body>
 <div id="tst" >
  <div class="img" >
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-1.png" />
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-2.png"/>
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-3.png" />
   <img src="http://i.cdn.hbo.com/custom-assets/enrichments/series/game-of-thrones/images/map/x2-images-3-4.png" />
   <div id="pop1" class="pop" >Pop 1</div>
   <div id="pop2" class="pop" >Pop 2</div>
  </div>
  <div id="nav" >
   <div class="nav" ></div>
  </div>
 </div>

<script type="text/javascript">
/*<![CDATA[*/
// MapNavigator (23-May-2011) DRAFT
// by Vic Phillips http://www.vicsjavascripts.org.uk

function zxcMapNavigator(o){
 var pobj=document.getElementById(o.ID),img=pobj.getElementsByTagName('DIV')[0],nav=document.getElementById(o.NavID),nobj=nav.getElementsByTagName('DIV')[0],r=img.offsetWidth/nav.offsetWidth,marks=o.Markers,mark,pop,z0=0;
 img.style.position='absolute';
 nobj.style.position='absolute';
 nobj.style.width=pobj.offsetWidth/r+'px';
 nobj.style.height=pobj.offsetHeight/r+'px';
 for (;z0<marks.length;z0++){
  mark=document.createElement('DIV');
  mark.className=marks[z0][0];
  img.appendChild(mark);
  mark.style.left=marks[z0][1]-mark.offsetWidth/2+'px';
  mark.style.top=marks[z0][2]-mark.offsetHeight/2+'px';
  pop=document.getElementById(marks[z0][3]);
  if (pop){
   pop.style.left=marks[z0][1]-pop.offsetWidth/2+'px';
   pop.style.top=marks[z0][2]+marks[z0][4]+'px';
   this.addevt(pop,'mouseup','popclose');
  }
  this.addevt(mark,'mouseup','markpos',[mark,pop]);
 }
 this.lst=false;
 this.img=img;
 this.pobj=pobj;
 this.nav=nav;
 this.nobj=nobj;
 this.r=r;
 this.navpos();
 this.drag=false;
 this.addevt(nobj,'mousedown','ndown');
 this.addevt(img,'mousedown','down');
 this.addevt(document,'mousemove','move');
 this.addevt(document,'mousemove','nmove');
 this.addevt(document,'mouseup','up');
}

zxcMapNavigator.prototype={

 markpos:function(e,mark){
  this.popclose();
  var img=this.img,pobj=this.pobj,m=mark[0],lft=-m.offsetLeft-m.offsetWidth/2+pobj.offsetWidth/2,top=-m.offsetTop+100;
  img.style.left=-m.offsetLeft-m.offsetWidth/2+pobj.offsetWidth/2+'px';
  img.style.top=-m.offsetTop-m.offsetHeight/2+100+'px';
  if (mark[1]){
   mark[1].style.visibility='visible';
   this.lst=mark[1];
  }
  this.navpos();
 },

 popclose:function(){
  if (this.lst){
   this.lst.style.visibility='hidden';
  }
 },

 navpos:function(){
  var img=this.img,nobj=this.nobj,r=this.r;
  nobj.style.left=-img.offsetLeft/r+'px';
  nobj.style.top=-img.offsetTop/r+'px';
 },

 imgpos:function(){
  var img=this.img,nobj=this.nobj,r=this.r;
  img.style.left=-nobj.offsetLeft*r+'px';
  img.style.top=-nobj.offsetTop*r+'px';
 },

 addevt:function(o,t,f,p){
  var oop=this;
  if (o.addEventListener) o.addEventListener(t,function(e){ return oop[f](e,p);}, false);
  else if (o.attachEvent) o.attachEvent('on'+t,function(e){ return oop[f](e,p); });
 },

 mse:function(e){
  if (window.event){
   var docs=[document.body.scrollLeft,document.body.scrollTop];
   if (!document.body.scrollTop){
    docs=[document.documentElement.scrollLeft,document.documentElement.scrollTop];
   }
   return [e.clientX+docs[0],e.clientY+docs[1]];
  }
  return [e.pageX,e.pageY];
 },

 style:function(obj,p){
  if (obj.currentStyle){
   return parseInt(obj.currentStyle[p.replace(/-/g,'')]);
  }
  return parseInt(document.defaultView.getComputedStyle(obj,null).getPropertyValue(p));
 },


 down:function(e){
  document.onselectstart=function(event){
   window.event.returnValue=false;
  }
  this.minX=-this.img.offsetWidth+this.pobj.offsetWidth;
  this.minY=-this.img.offsetHeight+this.pobj.offsetHeight;
  this.lastXY=[e.clientX,e.clientY];
  this.drag=true;
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 move:function(e){
  if (this.drag){
   var mse=[e.clientX,e.clientY],lft=this.style(this.img,'left')+mse[0]-this.lastXY[0],top=this.style(this.img,'top')+mse[1]-this.lastXY[1];
   this.img.style.left=Math.max(Math.min(lft,0),this.minX)+'px';
   this.img.style.top=Math.max(Math.min(top,0),this.minY)+'px';
   this.lastXY=mse;
   this.navpos();
  }
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 ndown:function(e){
  document.onselectstart=function(event){
   window.event.returnValue=false;
  }
  this.maxX=this.nav.offsetWidth-this.nobj.offsetWidth;
  this.maxY=this.nav.offsetHeight-this.nobj.offsetHeight;
  this.lastXY=[e.clientX,e.clientY];
  this.ndrag=true;
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 nmove:function(e){
  if (this.ndrag){
   var mse=[e.clientX,e.clientY],lft=this.style(this.nobj,'left')+mse[0]-this.lastXY[0],top=this.style(this.nobj,'top')+mse[1]-this.lastXY[1];
   this.nobj.style.left=Math.max(Math.min(lft,this.maxX),0)+'px';
   this.nobj.style.top=Math.max(Math.min(top,this.maxY),0)+'px';
   this.lastXY=mse;
   this.imgpos();
  }
  if (!window.event){
   e.preventDefault();
  }
  return false;
 },

 up:function(e){
  if (this.drag||this.ndrag){
   this.drag=false;
   this.ndrag=false;
   document.onselectstart=null;
  }
 }

}

new zxcMapNavigator({
 ID:'tst',
 NavID:'nav',
 Markers:[
  ['m1',1200,290,'pop1',50],
  ['m2',1200,1290,'pop2',50]
 ]
});
/*]]>*/
</script>


</body>

</html>
the animation and resizing should be easy to add


wow Thank you for all the work you put into this! - it is a great way to solve this problem.
my map will have a few more functionalities, such that we will add more details and more info weekly to the map - or more precisely we will display more and more elements on the map --
so I have to give some more thought to my requirements and functionalities, but your help saved me a lot of time with this thinking process.
thanks again
agkn0001 is offline   Reply With Quote
Reply

Bookmarks

Tags
interactive, javascript, map

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:51 AM.


Advertisement
Log in to turn off these ads.