Over the past few days, I’ve been hard at work on SpryMap. SpryMap is a super lightweight (2.8 KB), dependency free Javascript widget that turns any HTML element into a Google Maps-like click and drag window. I’ve taken the theory behind my jQuery click and drag map here and souped it up, making it better in every way. Let’s look more in depth at the changes made:
- Removed the jQuery dependency – Sure, I know, lots of people love it, but the fact is we sometimes sacrifice a bit of performance for convenience when using jQuery. Considering that the things for which I plan to use SpryMap are core page features, it’s important to me that it’s ultra-quick and always responsive .
- Added features - When using this script, you’re given full control over how you want the map to act. What coordinates do you want it to start at? Do you want it to animate to a stop, or stop immediately when the user releases the mouse? Do you want the dragging to stop when an edge is hit? Would you like soup or salad with that? SpryMap aims to give you full control over how it acts.
- Gave it an easy to use interface - No, really, it’s pretty darn easy. See the code below to see how to use it.
// Instantiate the widget when you want it to turned into a map,
// probably in the window.onload or $(document).ready() function.
// Default parameters are listed as the parameters below
var map = new SpryMap({
// The ID of the element being transformed into a map
id : "",
// The width of the map (in px)
width: 800,
// The height of the map (in px)
height: 800,
// The X value of the starting map position
startX: 0,
// The Y value of the starting map position
startY: 0,
// Boolean true if the map should animate to a stop
scrolling: true,
// The time (in ms) that the above scrolling lasts
scrollTime: 300,
// Boolean true if the map disallows moving past its edges
lockEdges: true,
// The CSS class attached to the wrapping map div
cssClass: ""
});
Note: In order for the closed hand cursor to correctly load after the mouse is clicked, the images/ directory containing closedhand.cur must be located at the same level as the HTML page using the script. Otherwise, the closed hand cursor will fail to load!
I’m releasing SpryMap under the creative commons license – essentially you’re free to use it and adapt it for any personal or commercial purposes so long as you don’t take credit for writing it yourself.
Let me know if you have any questions on how to use it or suggestions for future features – I’m always looking for ways to improve it!
Enjoy!
Charlie


Ric Werme
said...
Cute. Javascript is on the list of languages to learn that I may never get to.
Are you going to release a nicely formatted version of the source?
I’d be interested in using this as a photo viewer if you added something for zooming in and out – I could display a photo in a window with less than full resolution then between zooming in and scrolling I could look at details at full resolution.
Is that as easy to add as scrolling appears to be? (just setting a.map.style.left & top?)
October 31, 2010 @ 5:06 pm
Charlie
said...
It’s an incredibly easy language to pick up for anyone that’s familiar with C syntax. The only thing that makes it somewhat difficult is the object model, which uses prototypes rather than classical inheritance.
And yes – I’d definitely be happy to release a nicely formatted version of the source! To be honest, I contemplated it originally but decided I didn’t want to confuse anyone by releasing two equivalent scripts – a “pretty” one and an ugly, compressed, smaller one. Unfortunately, I seem to have torched the pretty, formatted version of the code somehow during the zipping process – I’ll let you know when I have it back.
With the zooming in and out, I think that may be significantly more difficult than scrolling – it wouldn’t be terribly difficult to set up something like this, where the you have a small version of the image, an overlay for the area that is currently zoomed in on, and a picture of the zoomed in area. But what I think you meant is more of a Google Maps type scroll-wheel zoom in and out. I’ve looked into that some, and it looks like the only way that they’re able to achieve the effect is to have different images saved for each zoom level and the images are stitched together at each level. That would be pretty tough to implement, and the script would be fairly difficult to use as well (you’d have to break the image apart into different sized tiles depending on the zoom level). Sorry – I wish I had a more hopeful answer than that.
October 31, 2010 @ 6:50 pm
Ric Werme
said...
It’s certainly no problem to learn Javascript, the issue is more with libraries and time. One reason I picked Python several years back was because it was usable in so many arenas. And I figured I wouldn’t need to learn Perl, and Java at the time was too politicized and “computer sciency” (Java seems to expect people to design things “just so” and Python is more of a “get it done now” language.)
I don’t mean a Google maps “load the next layer images,” I want to keep looking at the same image, just zoomed in. e.g. my camera’s default image size is 2048×1536, my display is less, and I hardly ever use it full screen for web pages.
I’ll usually scale down images to fit on web pages, but it would be nice to have some full sized photos in a single window, and then zoom in and scroll around within that single image. Like the magnifying glass tools you linked to, but dispensing with the magnifying glass window. Well, more like dispense with the fixed view and have only the magnified view. Actually, combine the two and instead of thinking Google-zoom, think scale factor.
October 31, 2010 @ 7:32 pm
Charlie
said...
Ahh, I see what you mean. So you’re saying some ability to have the full image on the screen initially (scaled so that it’s not at full resolution), click on the image or have some way to signal that you want to start the zoom, then be able to navigate the image by clicking and dragging after that? I think that that would certainly be possible – I’d never thought of that as an application for this.
November 1, 2010 @ 6:05 pm
Philippe
said...
This is a great script, and I certainly plan on using it. I have a few comments, however:
1) It is slightly annoying to require the script to be executed in the onload section of the page, as this is usually quite busy, especially because your script is directly linked to a map and could be executed in the onload event of the image itself (). I have modified it this way and it sort of works, although there is an annoying side effect about the scrolling that sometimes rubber-bands for some reasons. Is there any way for you to correct this and to make it a bit more “well-behaved” in terms of loading properly from the image itself ?
2) The restriction about the hand cursor is annoying, because I am calling the script from within a wiki, which has a well-structured directory implementation, and where I cannot leave files “lying about” at the same level as the execution of sprymap. Any way to make this better ?
3) Last, is there a way to implement a “zoom” feature of some sort ? That would be fairly nice as well…
But these are minor, comparing to the great job of outputting the script in the first place.
Finally, great job choosing the map from Pathfinder…
November 10, 2010 @ 6:27 am
Beben Koben
said...
hohoho…i’m enjoy it
thanks^^
November 10, 2010 @ 1:54 pm
Olaf
said...
Hi Charlie,
this looks very nice, a small feature that might work well with this would be a double click to center, so that when you double click a section of the map/image that would scroll to the center of the view automatically without having to drag it.
Anyways, thanks for sharing.
Cheers,
olaf
November 10, 2010 @ 2:37 pm
tonyb
said...
Does this support tiled maps? or is it just one big image? Im looking for something like this that supports tiling, so I can display a real large blueprint on screen.
How is this different than just cessting up an
November 10, 2010 @ 3:27 pm
Philippe
said...
ALso another small comment, the css is not extremly well divided. By default, it adds the style.css, which contains modification to standard styles like h1, h2, etc. This might be necessary for your site, but it has side-effects when included on other sites. You might want to split the .css, dividing it into what is required for your site and what is required for the maps, which is almost nothing (I do not even use the mappy style included, for example).
November 11, 2010 @ 7:45 am
Anonymous
said...
hi
your zip file contain duplicated file!!
—
Is it possible to add “lazy loading” to image?
Is it possible to use splitted image map?
(it is useful for big image)
November 12, 2010 @ 3:51 am
Stephan Sokolow
said...
While there’s nothing wrong with the CC-BY (unlike the CC-BY-SA which is GPL-incompatible and lacks the GPL’s requirement that people ShareAlike the original source, not compiled or obfuscated source), I’m curious why you didn’t use a BSD/MIT/X11 license.
They’re functionally equivalent to (and mutually compatible with) the CC-BY but much more common among and familiar to software developers.
November 12, 2010 @ 3:44 pm
Charlie
said...
I apologize for the slow reply – I’m afraid that school’s had me a bit swamped over the past week or so.
@philippe I do see what you mean about onload() often getting cluttered in javascript. I guess that my question though is where would you like to call it from? I think if I knew the answer to that I would have a better understanding of how exactly you’d like the script to bend, and hopefully I could help you out.
Also, as for your second comment about the CSS not being well divided, that was a misunderstanding that was my fault. In the .zip file I posted, I included the whole example program that I uploaded to my site. The index.php, map.jpg, style.css, and readme (obviously) aren’t intended for use with the general script, only for the demo – I think that I’m going to change it so that only the script and the cursor image are in the .zip file. That way there’s a little less confusion. I’m still getting the hang of how to best post the source. Also, would it satisfy your needs if you could specify the URL to load the cursor image from as one of the constructor parameters? I think that may be the right way to go about solving the cursor problem, which I admit is a flaw in the script.
Lastly, could you describe a bit more by what you mean by “zoom”? What’s the exact functionality you’re after?
@beben I’m glad that you like it!
@olaf I agree – that would be a very cool feature! However, I also think that’s a bit specialized to warrant including a feature just for that. However, between you and me, I’m planning on including a “slide to” animation in the next version where you’re able to slide to the specified map coordinates. Once this is implemented, I promise that it’ll be incredibly easy to write your own function to slide to the center upon a double click.
@tonyb When you say does it support tiling, do you mean a repeated background, for example? Or do you mean multiple images placed next to each other? I think that I may need a little clarification in order to best answer your question. Also, if your last comment is asking what the advantage is of using this over typical scrollbars in a frame, then the answer is that this may or may not be the right tool, depending on the job. I think that this offers more precision for getting exactly the view that you want, whereas scrollbars tend to move over large areas more effectively. Like anything else, all this offers is a tool for a situation.
@anonymous Ah, so you’re right! I’m sorry for that – I’m not exactly sure what happened. I could of sworn that I double checked that it was pretty before uploading it. I now have a clean version up.
@stephan I actually looked into both the CC-BY and MIT licenses for the script and, to be honest, just picked one after being unable to discern any significant differences between the two. I think that you may be right though that it would be wise to use the MIT license if that’s what the majority of software developers are more familiar with.
November 15, 2010 @ 1:18 pm
Nathan J. Brauer
said...
Hey there!
Thanks for making this
I have a solution for your cursor issue — my solution allows you to get rid of the cursor file completely! Simply replace url(images/closedhand.cur) with this:
url(data:image/x-win-bitmap;base64,AAACAAEAICACAAcABQAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAEAAAAAAAAAAAAAAgAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAfwAAAP+AAAH/gAAB/8AAAH/AAAB/wAAA/0AAANsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////////////////////////////////////gH///4B///8Af//+AD///AA///wAH//+AB///wAf//4AH//+AD///yT/////////////////////////////8=)
This will embed the image directly into the code!
November 15, 2010 @ 6:58 pm
Nathan J. Brauer
said...
(I’m working on getting a sample of this up and running on http://HanoiChurch.com/soft/contact/ )
November 15, 2010 @ 6:59 pm
Charlie
said...
@nathan Great idea! Nice, creative solution to the problem. Saves the extra HTTP request, too.
November 15, 2010 @ 8:10 pm
Nathan J. Brauer
said...
One request I’d like to see is an effective open-hand cursor on hover. I tried adding one via CSS but it ends up overriding the closed hand cursor. Ideas?
November 16, 2010 @ 12:55 am
Nathan J. Brauer
said...
Alrighty, I found the perfect cursor for the job and embedded it. Here’s my all-in-one-file version:
http://hanoichurch.com/soft/wp-content/themes/church-theme/js/spryMap.js
And here it is in action:
http://HanoiChurch.com/about/
http://HanoiChurch.com/contact/
November 16, 2010 @ 4:28 am
Nathan J. Brauer
said...
Whoops. sorry, I forgot that the site isn’t live yet. Until it’s live, here are the temporary action links:
http://HanoiChurch.com/soft/about/
http://HanoiChurch.com/soft/contact/
November 16, 2010 @ 4:29 am
SocialEstates.com
said...
SpryMap is awesome! I can totally see being a great way to display floor plans on Real Estate apps. Thank you! Great job!
November 16, 2010 @ 8:05 pm
Charlie
said...
@nathan Hey! I love the site. Great use for it – your site looks like it is turning out great as well.
@socialestates.com I’m glad that you think that it’s useful! Hopefully it’s able to help you out. Also, I appreciate the compliment – I thought it would be useful for me, and I’m glad that I was able to help out some others as well.
November 20, 2010 @ 12:57 am
mike
said...
This is nice, but you have missed one of the most important features of google maps – having the map broken into small tiled images.
If you think about how Google maps works, (imagine the size of the world map) it would not be possible to load it all as one image like you are doing here.
This is what tonyb is referring too
November 20, 2010 @ 6:18 am
yuyun
said...
could you adopted it in mapserver??
it is webgis open source.
November 22, 2010 @ 2:09 am
MMO-STR
said...
hi,
i search system of map like this for my game…. but with content dynamicaly load when scrool in a directon… did somebody have this in stock ? ;o)
thanks.
November 30, 2010 @ 3:58 am
Stephen
said...
nicely formatted sprymap.js: https://gist.github.com/728782
December 4, 2010 @ 11:17 pm
Rene
said...
How about adding markers to it? Would that be possible in the future?
December 7, 2010 @ 10:46 am
Iouri Goussev
said...
Frodo and Sam should have bought ipad + your map ont the way to Mordor
December 14, 2010 @ 2:52 pm
Throrin
said...
Hy, it’s a verry good script but your script bug in IE7 on click to drag&drop
December 20, 2010 @ 11:25 am
RK
said...
SpryMap doesn’t work on the iPad.
I guess this is due to the fact there is no cursor/mouse thus javascript has no correct input.
I’m a designer so I need to ask you Charlie if this is an easy fix.
December 30, 2010 @ 12:45 pm
Kevin Andrews
said...
Charlie,
This is a brillent piece of code, only problem i have with it is that after each mouse down an error appears down the bottom left of internet explorer 8. Not sure if this is the same on other browsers.
I would like to use this on a project called Tribal Tools (www.tribaltools.co.uk) for the map application on a village using php, but i would like to get rid of this error first, any clue what would be causing it?
January 10, 2011 @ 8:31 am
Kevin Andrews
said...
Just a little fix for firefox, when you click and drag on the image in firefox it tries to drag away a preview of the image (useful to preview by dragging to the top tab bar). If you add onmousedown=”event.preventDefault()” to your tag it stops this from happening.
January 11, 2011 @ 9:00 am
Shaikamjad
said...
Thanks a lot. It’s really great, can u pls add a feature so that we place a pin (Like in Google maps), it stays @ particular point all the time relative to this map.
January 12, 2011 @ 6:50 am
Alexandra
said...
hei…can you please show us a full example ?
February 9, 2011 @ 3:07 am
AD
said...
Hei.
Can anyone please help me with a function that scrolls the map to a certain point? It would help me a lot.
Thanks
February 10, 2011 @ 6:56 am
Dan
said...
Is there a way to get this to work multiple times on the same page? My gut tells me that I should just be able to add the next image id to –> var map = new SpryMap({id : “image_one”, “image_two”, etc. but that doesnt seem to be the case, unless I am missing something obvious which I more than likely am. Any help or suggestions from ANYONE would be greatly appreciated! Totally new to js and css btw, but thanks so much for this, its really cool!
February 10, 2011 @ 11:23 pm
RM
said...
Hei,
Did anyone solve the Explorer problem? If yes, How ? Please help…
Thanks
February 11, 2011 @ 3:34 am
Ishtiaque
said...
greate work, please check web designing company website.
February 15, 2011 @ 5:14 pm
Kevin Scheidt
said...
1) I’m looking for something very close to this. However, as the question previous was related to tiling, I have a similiar or the same question.
Let’s say i’m displaying a map in the middle. I don’t want the 8million x 8 million pixel map pulled up at once, so I want to break it down to smaller maps. Much like google maps has like 100×100 or something pixel maps, and as you scroll left, right, up or down it loads those new maps.
Is it easy to adapt yours to pull these tiled maps?
2) I need to add a custom right click menu option, any pointers where to look? I need it to be the same or different based on the tile i’m on or area of the map/div/grid, etc
March 7, 2011 @ 9:57 am
Tadalafil
said...
Tell me how to contact the author of this article?
Thanks in advance!
April 30, 2011 @ 2:23 pm
ronin
said...
hi,why i can’t download the sprymap.zip?
May 3, 2011 @ 9:17 am
Craig
said...
This would be awesome, does anyone know of any other tools or libraries that allow this? Seems the author has abandoned this blog.
>> This is nice, but you have missed one of the most important features of google maps – having the map broken into small tiled images.
If you think about how Google maps works, (imagine the size of the world map) it would not be possible to load it all as one image like you are doing here.
This is what tonyb is referring too<<
May 18, 2011 @ 7:14 am
egoblock
said...
Hi,
Thank you.
This function is really good.
By the way,
could you correct the sample code of this page.
“var map = new spryMap”
-> “var map = new SpryMap”
“S” is capital.
May 19, 2011 @ 11:56 pm
Dan
said...
Hi,
thanks for your work. I am using it for a tile mapped game and ran into some problems. I have a table in the viewbox with dynamic size (expands as needed when the user gets to certain regions). When I insert a new column in the front the view box jumps directly to the newly added column. Is there anything I’m missing ?
May 31, 2011 @ 5:56 pm
Larry
said...
I was searching the web looking for a click and drag image like this. Very Nice! I also wanted to be able to have links on the image. Is this possible?
August 14, 2011 @ 9:44 am
Bob
said...
Hey, I have made several useful modifications for you script. I can email it to you if you want or post it on github if you set up a page for this.
August 29, 2011 @ 12:55 am
stahlmanDesign
said...
I figured out how to put multiple images on top of each other. make your map a instead of and put the images inside. Then with a range slider you can change the opacity of the top image by getting its ID and changing opacity to reveal the 2nd image.
{id : “map”,
height: 800,
width: 650,
startX: 0,
startY: 0,
cssClass: “mappy”});
November 4, 2011 @ 6:04 pm
stahlmanDesign
said...
Last comment cut off my code… just showing to make map a div
images here…
November 4, 2011 @ 6:05 pm
Online Marketing München
said...
Is it possible, that i can track the coordinates on mouse click?
November 10, 2011 @ 2:55 pm
Philipp
said...
Sadly not usable, since it absolutely doesn’t work in IE7, IE8 nor IE9. You get these kind of errors:
Webpage error details
User Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Timestamp: Tue, 15 Nov 2011 10:22:34 UTC
Message: Object doesn’t support property or method ‘preventDefault’
Line: 181
Char: 9
Code: 0
URI: http://candrews.net/sandbox/spryMap/scripts/spryMap-2.js
November 15, 2011 @ 5:24 am
adam blood
said...
how do i begin to use this code?
i want to make a draggable map, but don’t know where to begin.
also would this work on a wiki page show a game map?
March 22, 2012 @ 6:11 pm
Slavomir
said...
Hi All,
I fixed this script, and now is working under IE7+ Source code can be found here: https://github.com/slav123/SpryMap
April 1, 2012 @ 9:45 pm
masCh
said...
Is there any javascript plugin like SpryMap or JQuery that can work on a mobile browser?
May 5, 2012 @ 3:21 pm
Skeener
said...
Hi,
How can I center the image ? (when I’ll click on a button for example)
Thanks…
June 20, 2012 @ 4:40 am
Art
said...
Hey!
how can i use it with canvas?
April 12, 2013 @ 12:19 am
http://www.lakesidehobbies.com/groups/samsung-galaxy-s4-initially-impressions-of-the-new-galaxy-handset
said...
When someone writes an paragraph he/she keeps the idea of a user in his/her brain that how a user
can know it. Thus that’s why this article is perfect. Thanks!
May 6, 2013 @ 12:13 am