Tue. January 5, 9:00:12 PM
Looks good. Can be useful thanks for sharing.
In this article I'll show you how to create a Facebook-like photo tagging feature. If you're like me you're probably more interested in a live example than digging through this entire article so here is a live demo of the above example.
As with all my examples using jQuery, I link to Google's hosted version. If a user already has the file in their browser cache, it cuts down on another HTTP request thus saving your users time.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
Below is all the HTML needed for my image tagging example. I dynamically insert much of the other needed HTML via jQuery. Originally I planned to make this a jQuery plugin. This could still easily be accomplished by taking the code within $(document).ready & adding it into a standard plugin code block.
<img src="image.jpg" style="width: 604px; height: 423px;">
Unlike many of my other articles, there is a lot more code needed to achieve the desired effect. Because of this I probably won't walk you through line-by-line. Instead I'll give a brief description for some of the main elements in the DOM.
#tag-wrapper - This is wrapped around the IMG element and is given a relative position. This allows us to position other elements absolute.
#tag-target - This is a DIV which boxes in the target which a user has clicked on within the photo.
#tag-input - This is a DIV which contains a label, input box & submit/reset buttons. It is attached to the #tag-target DIV.
.hotspot - Finally after a tag has been assigned, a .hotspot DIV is created and positioned over the desired location on the image.
html, body { margin: 0px; padding: 0px; }
body
{
color: #666;
font-size: 12px;
font-family: Arial, Helvetica, sans-serif;
}
#tag-wrapper
{
border: 1px solid #ccc;
box-shadow: 0px 0px 10px #bbb;
-webkit-box-shadow: 0px 0px 10px #bbb;
-moz-box-shadow: 0px 0px 10px #bbb;
display: block;
padding: 10px;
position: relative;
}
#tag-target, #tag-wrapper img { cursor: crosshair; }
#tag-wrapper img { position: absolute; }
#tag-target
{
display: none;
border: 4px solid #fff;
box-shadow: 0px 0px 20px #000;
-webkit-box-shadow: 0px 0px 20px #000;
-moz-box-shadow: 0px 0px 20px #000;
height: 100px;
width: 100px;
position: absolute;
top: 0px;
left: 0px;
z-index: 2;
}
#tag-input
{
background: #fff;
display: none;
padding: 5px;
position: absolute;
top: 0px;
left: 0px;
width: 137px;
z-index: 2;
}
#tag-input label
{
display: block;
font-weight: bold;
}
#tag-input input
{
border: 1px solid #ccc;
color: #888;
display: block;
margin: 5px 0px;
outline: 0px;
padding: 3px;
width: 124px;
}
.hotspot
{
border-width: 0px;
box-shadow: 0px 0px 0px #000;
-webkit-box-shadow: 0px 0px 0px #000;
-moz-box-shadow: 0px 0px 0px #000;
height: 100px;
width: 100px;
position: absolute;
}
.hotspot:hover, .hotspothover
{
border: 4px solid #fff;
box-shadow: 0px 0px 20px #000;
-webkit-box-shadow: 0px 0px 20px #000;
-moz-box-shadow: 0px 0px 20px #000;
z-index: 1;
}
.hotspot span { display: none; }
.hotspot:hover span, .hotspothover span
{
background: #fff;
display: block;
font-weight: bold;
padding: 3px 0px;
text-align: center;
}
.remove { color: #748950; cursor: pointer; text-decoration: underline; }
Below are the global Javascript variables used. targetX & targetY plot coordinates for where the user clicks on the image. tagCounter is used to give each of the tags a unique ID
//Placed outside .ready for scoping
var targetX, targetY;
var tagCounter = 0;
In the main code block I've liberally added comments to explain each line of code:
$(document).ready(function(){
//Dynamically wrap image
$("img").wrap('<div id="tag-wrapper"></div>');
//Dynamically size wrapper div based on image dimensions
$("#tag-wrapper").css({width: $("img").outerWidth(), height: $("img").outerHeight()});
//Append #tag-target content and #tag-input content
$("#tag-wrapper").append('<div id="tag-target"></div><div id="tag-input"><label for="tag-name">Person\'s Name:</label><input type="text" id="tag-name"><button type="submit">Submit</button><button type="reset">Cancel</button></div>');
//$("#tag-wrapper").click(function(e){
$("img").click(function(e){
//Determine area within element that mouse was clicked
mouseX = e.pageX - $("#tag-wrapper").offset().left;
mouseY = e.pageY - $("#tag-wrapper").offset().top;
//Get height and width of #tag-target
targetWidth = $("#tag-target").outerWidth();
targetHeight = $("#tag-target").outerHeight();
//Determine position for #tag-target
targetX = mouseX-targetWidth/2;
targetY = mouseY-targetHeight/2;
//Determine position for #tag-input
inputX = mouseX+targetWidth/2;
inputY = mouseY-targetHeight/2;
//Animate if second click, else position and fade in for first click
if($("#tag-target").css("display")=="block")
{
$("#tag-target").animate({left: targetX, top: targetY}, 500);
$("#tag-input").animate({left: inputX, top: inputY}, 500);
} else {
$("#tag-target").css({left: targetX, top: targetY}).fadeIn();
$("#tag-input").css({left: inputX, top: inputY}).fadeIn();
}
//Give input focus
$("#tag-name").focus();
});
//If cancel button is clicked
$('button[type="reset"]').click(function(){
closeTagInput();
});
//If enter button is clicked within #tag-input
$("#tag-name").keyup(function(e) {
if(e.keyCode == 13) submitTag();
});
//If submit button is clicked
$('button[type="submit"]').click(function(){
submitTag();
});
}); //$(document).ready
Finally, here is a few functions I use for adding/removing tags:
function submitTag()
{
tagValue = $("#tag-name").val();
//Adds a new list item below image. Also adds events inline since they are dynamically created after page load
$("#tag-wrapper").after('<p id="hotspot-item-' + tagCounter + '">' + tagValue + ' <span class="remove" onclick="removeTag(' + tagCounter + ')" onmouseover="showTag(' + tagCounter + ')" onmouseout="hideTag(' + tagCounter + ')">(Remove)</span></p>');
//Adds a new hotspot to image
$("#tag-wrapper").append('<div id="hotspot-' + tagCounter + '" class="hotspot" style="left:' + targetX + 'px; top:' + targetY + 'px;"><span>' + tagValue + '</span></div>');
tagCounter++;
closeTagInput();
}
function closeTagInput()
{
$("#tag-target").fadeOut();
$("#tag-input").fadeOut();
$("#tag-name").val("");
}
function removeTag(i)
{
$("#hotspot-item-"+i).fadeOut();
$("#hotspot-"+i).fadeOut();
}
function showTag(i)
{
$("#hotspot-"+i).addClass("hotspothover");
}
function hideTag(i)
{
$("#hotspot-"+i).removeClass("hotspothover");
}
I did add a few effects that Facebook does not have. For instance I added fading effects on pretty much everything I could. I often find that adding a fade or slide effect gives applications a more "polished look". I also added an animation if you click a new location for the target tag. Once again, here's a link to the finished product >>
Looks good. Can be useful thanks for sharing.
Nice. It would be really usefull for adding description to a products picture. Is there any way to add a visual sign to where a tag exist (let's say a '+' character). Then you know where to look for a tag.
Walter, you could style the .hotspot class so that it contains a background image or something to that effect. I know that if you hover over the area a popup would appear. If you modified it so that the popup always appeared this would give you the desired effect.
Hi... Thanks for great tuto.. I will try to implement it in my future social network... Demo looks greaaaaaaaaaaaat
how can I load autocomple in textbox ? I want after user keyup in textbox it will load a list users from database .it mean like tag friend on facebook with autocomple when you type name of friend (it will load list a friend like the name you has just enter ) .
Looks really great.
By the way, is there any way we could store the data in database dynamically?
This is awesome dude!!!! Thanks for releasing this.
Juset superb man pasete the code and its ready
Juset superb man pasete the code and its ready
How about if you have list of friends to be tagged? How can it be done. I need your advise man.
Regards,
Katy Perry <3
checked demo in IE7. It does not work properly in IE. I tried to add tags. Tags added successfully but they do not show if we move mouse on photo.
Any solutions please?
Thanks
@Mastert, You may have some conflicting on your page. I have IE7 on my machine and it works fine.
The demo doesn't work in IE 8.0.7 other than that this is great. I used jqueryui to add resizing and dragging. I just had to add targetHeight, targetWidth and set those vars on 'stop' event of drag and resize, then use those vars in $("#tag-wrapper").append
Thanks.
Site Coded And Designed By Neal Grosskopf Using No Crappy CMS Or Themes