Here We Are Again
Welcome back friends. This is the third season of You Are Here (with Safari on iPhone) and this series doesn’t look like it’s letting up any time soon. :)
Since our last installment in February 2010, it seems that the Google Maps API has shifted yet again and bricked our demo. No worries. Thanks to some great detective work by @Chris, we can get the old code up-and-running again by adding “optimized:false” to our Maps API Marker options. This will prevent Google from optimizing (encoding) the Marker image and allow the Marker to be rendered as an image tag as it did in our first demo. Therefore we can revert to our original CSS selector and call it a day.
But why leave it at that? Let’s take this to the next level and tweak that pulsating marker so it looks even more realistic.
Blue dot special
First off, let’s start with a fresh new marker—one that just encompasses that blue aqua icon at the center of the pulsating ring. I basically just recreated the blue iPhone Maps location icon in Fireworks and exported it as a PNG with alpha transparency. After uploading the image to the server, I also updated the Marker options to reflect the new file name and image size (17px square).
Great rings of Neptune, Batman!
Next up, the pulsating ring. Back in April 2010, Zachary Johnson posted a piece on Pure CSS Map Markers that inspired me to go 100% CSS on the rings. It just took me this long to get around to it.
To start, we’ll make a circle out of a square div by adding mega border-radius to it. In our case, we’ll have a 51px square (three times the blue icon’s height/width) with border-radius set to 51px as well. Now that we have our circle, let’s style it to look more like that iPhone Maps ring. Look closely at that ring and notice that its not a blue ring but a white ring with blue blurring the edges. We can achieve that effect by adding a 1px solid white border to our circle and then—and here’s the magic—applying multiple layers of blue inner and outer box-shadows in the same CSS declaration.
box-shadow: inset 0 0 5px #06f, inset 0 0 5px #06f, inset 0 0 5px #06f, 0 0 5px #06f, 0 0 5px #06f, 0 0 5px #06f;
Who knew you could do such a thing? I didn’t, until I tried it. The ability to use standard drop shadows and inset shadows in the same declaration is amazing enough, but that you can layer them to achieve deeper color (as you would in Photoshop with multiply layers) is astonishing. And we’ll need this color depth when we animate our ring. Without this color depth, the blue would appear too faint as its opacity drops to zero.
So, all that remains in our styling exercise is to animate our awesome ring. Going back to our keyframes, let’s start from an initial scale of 25% and opacity of 100%. Then let’s progress at the 95% mark to 130% scaling and 0% opacity. And lastly, let’s return to scale of 25% with the 0% opacity to reset everything for the next iteration. That’s pretty much it—aside from some refactoring to take advantage of animation shorthand and the addition of Mozilla’s CSS prefix,
Okidoki. So we have our new blue icon marker and we have a new pulsating ring, but they’re not connected. We need to dig into the Google Maps DOM and grab our marker’s wrapper element to apply the ring styling (so that the ring will pulsate out from the marker image). Fortunately, there’s a div that surrounds our marker image that meets our needs. Curiously, there are actually two almost identical div/marker-img combos to play with. We can actually sacrifice one for our sneaky purposes. The second combo has a div with the Marker title we added in the options so we can conveniently use that as our ring’s CSS selector. Yay! But since that div is scaling up and down, the inner bluedot.png img tag scales up and down too, which isn’t what we want. No problemo! Display:none that image and let the first set’s bluedot image shine through.
Add a few more margin tweaks for high DPI devices and we’re done styling our realistic pulsating marker. Check it out on the demo page.
Am I really here?
Commenter @John also mentioned some issues with geolocation accuracy thay @Ziyad was kind enough to address. Since we’re already under the hood, let’s roll those modifications into our code as well.
navigator.geolocation.watchPosition( displayLocation, handleError, { enableHighAccuracy: true, maximumAge: 30000, timeout: 27000 } );
Wait, what version is this?
This demo has had a history of API version issues so it comes as some relief to find Google providing support for versioning. I’m not sure if this is a recent development, but you can actually specify the Maps API version that your code works with. So now when our code breaks, just go back and request the API script version that was running back when things were good.
http://maps.googleapis.com/maps/api/js?v=3.4&sensor=true_or_false
Git it while it’s hot!
Speaking of versioning, the code for this demo is now up on GitHub. Go grab it from there, fork it, enjoy.
November 8th, 2011 at 2:41 pm
HI Steve,
FYI, the blue dot is not centered within the rings of saturn, at least not on my iPad. The dot appears down and to the right.
My Main question is, can you combine your ‘you are here’ with a custom map? I have created a custom map with 23 markers that load from an xml file.
Can I have this map, as well as the blue dot? (I’m creating a walking tour for a local museum)
Thanks!
November 9th, 2011 at 8:34 am
@Tony thanks for catching the off-center rings in iPad. I fixed that bug with an additional media query on line 60.
Regarding the custom map, it looks like you can customize the tile overlays and I bet you can loop though a list of additional markers (just make sure they don’t share the same title as the pulsating marker).
November 11th, 2011 at 7:30 am
Hi Steve,
Love this code snippet – spent a long time searching for how to achieve this effect.
One question though did you create ‘bluedot.png’ yourself or did you download it from somewhere?
I am only asking as I need a version twice the size so that I can serve it up and scale it down using Google Maps API so that it remains nice and sharp on retina devices.
Something like this: http://samcroft.co.uk/2011/google-maps-marker-icons-for-iphone-retina-display/
This might be a nice improvement to your code overall as if you have gone to the trouble of fixing the pulse for retina devices, so might as well fix the icon. If you could provide the image I do not mind implementing it and sharing the code? Any help you could provide would be awesome.
Again thanks
Shaun
November 12th, 2011 at 5:38 pm
@Shaun glad you found the snippet helpful!
To answer your question about the bluedot image: yes, I created that PNG in Fireworks. Your point about doubling its size for Retina Display is well taken and I’ll take a shot at doing just that when I can. Also, after reading Sam Croft’s article on high-res markers, I can see that I’ll need to make a few changes to my code. Thanks for the link!
In the meantime, I uploaded my original Fireworks source file to GitHub (under the source directory). If you want to take a swing at updating the image (and the JavaScript) for Retina Display, by all means fork that repo and shoot me a pull request. I’d sincerely appreciate it! –Thanks!
November 13th, 2011 at 12:41 am
@Shaun, I found a spare moment and updated the Marker and JavaScript code per Sam’s article. Thanks again for noticing that Retina Display issue and proposing a solution. It worked!
And thank you Sam Croft, where ever you are.
November 14th, 2011 at 4:21 am
Thank you for looking into this Steve.
I wasn’t expecting you to implement it as well.
Thanks again
Shaun
December 2nd, 2011 at 2:45 pm
I had good luck with this on Chrome but I cannot get it to work on my iPhone. Instead of #map_canvas I am using Sencha Touch so I tried setting it up with .x-map which I thought would work and still only works on Chrome but not iPhone.
January 5th, 2012 at 6:25 am
@steve I’m here! You’re welcome :)
This is a great technique, very clever and creative.
- Sam
January 30th, 2012 at 7:09 pm
Really cool snippet. I’ve tried it on my iPhone 4GS and in my browser and it works as expected. On a 3GS, the ring is offset upwards and to the left though. :-(
February 3rd, 2012 at 12:31 pm
@Steve
We’re doing some testing now that we’ve reconciled your ‘blue dot’ map with our custom embedded map.
The geolocation accuracy script helped quite a bit.
But we’ve run into an issue where the dot doesn’t follow you around in real time. You have to update the page each time to see where you are. This is in Safari on iPad.
Do you know if it’s possible to have the dot follow you around in real time like it does in the ‘Maps’ app? Or does it necessitate a page refresh each time?
March 1st, 2012 at 11:31 am
Changing the mobile-specific part at the end of the CSS from “#map_canvas …” to “#map …” solves the off-center blue dot problem. Thanks for this code Steve.
May 19th, 2012 at 3:47 am
[...] plebeosaur.us ”Here We Are Again” [...]
July 18th, 2012 at 4:49 am
@Steve : Thanks for your code !
@Todd : i had the same problem with a 3GS. I used snippet code found here and now all is ok on a 4S and 3GS http://css-tricks.com/snippets/css/media-queries-for-standard-devices/
October 25th, 2012 at 11:28 am
Thanks for doing this! If you git checkout -b gh-pages ; git push -u origin gh-pages from your master branch, you’ll get an automatically github-hosted result of the second branch like http://johan.github.com/GeoLocateMe/ (but for your github user name’s). You can even drop master and only have the latter, for ease of updates.
The blue marker image could use a little smoother alpha channel transition from transparent to its outer rim; it looks a little pixely-jagged at the moment.
January 2nd, 2013 at 1:57 pm
Great tutorial. I’m trying to recreate this on Bing Maps but I can’t figure out how to get the blue dot to appear. The rings appear and pulsate fine, just no blue dot.
I’m guessing it has to do with the way Bing uses its Icon Image. Any ideas?
March 3rd, 2013 at 9:24 am
Thank-you for this! Now I’ve gotta sleep on it for a day or so, and play with it a while, but if I want to change the size of the outer rings to reflect the “accuracy” of the geolocation (where available), I presume I can modify the style in the DOM in the watchPosition handler. Maybe if I want to get really fance I can couple the scale of the pulsar with the accuracy of the geolocation *and* the scale of the map as the user zooms in or out.
I’ve just gotta study it to figure out what to modify … unless you’ve got a quick answer …
April 11th, 2013 at 3:24 am
That example is so good! Thank you for sharing it. It took me a bit of time to figure out why it was not working at first and it turned out to be the CSS selector issue using the “I might be here” title. I was using a different dynamic one.
Is there another way to still select the right element to style when a dynamic custom title is used with possibly multiple markers. What it seems to be is that there has to be a static way to select it (or them if i have many markers).
Thanks for reading!
May 13th, 2013 at 2:18 pm
Because you’re just the kind of people that I like to thank, for your work that still work two years after, and is robust, clear and easy to use.
Thank you
November 7th, 2013 at 4:52 am
Really awesome! This made my map application from good to perfect!