Habilitando tags em fotos com jQuery
Aprenda a desenvolver uma interface para permitir que usuários apliquem tags/marcações nas fotos do seu aplicativo.
Marcar seus amigos nas fotos publicadas é um dos recursos mais populares do Facebook. Neste artigo você confere como implementar uma interface semelhante utilizando o plugin imgAreaSelect. Veremos apenas a parte client-side, sem armazenar as informações das tags, portanto, sem nenhuma programação server-side.
Nosso HTML/CSS
O primeiro passo é criar um HTML com a foto de exemplo. Começamos adicionando ao head chamadas para os scripts e as folhas de estilo.
[cce lang="html"]
<script type=”text/javascript” src=”js/jquery.min.js”>
<script type=”text/javascript” src=”js/jquery-ui-1.8.13.custom.min.js”>
<script type=”text/javascript” src=”js/jquery.imgareaselect-0.9.6/scripts/jquery.imgareaselect.min.js”>
<link href=”css/ui-lightness/jquery-ui-1.8.13.custom.css” rel=”stylesheet” />
<link href=”js/jquery.imgareaselect-0.9.6/css/imgareaselect-default.css” rel=”stylesheet” />
[/cce]
Além do imgAreaSelect, também utilizamos a biblioteca de componentes para interface jQueryUI. Ela será responsável por mover (draggable) e redimensionar (resizable) as tags nas fotos.
A marcação HTML é bem simples, apenas com a imagem e um link para exibir/ocultar as tags. O formulário para adicionar uma tag será adicionado on the fly, após selecionarmos uma área. E como o formulário terá posição absoluta, é importante definir, no CSS, o atributo “position:relative” para o container da imagem, no nosso caso o elemento p.
[cce lang="html"]

[/cce]
[cce lang="css"]
p{
position:relative
}
div.form-tag{
position:absolute;
top:0;
left:0;
z-index:1000;
}
span.tag{
position:absolute;
border:1px solid #df0d32;
background-color:rgba(255, 255, 255, 0.2);
display:inline-block;
color:#df0d32;
}
[/cce]
Selecionando áreas na foto
Passo a passo, esse será o fluxo da nossa interação:
- Com o mouse, o usuário seleciona uma área da foto para marcação;
- Feita a seleção, o script exibe uma caixa de texto para digitação do conteúdo da tag;
- Ao pressionar a tecla enter, o script cria, visualmente, a tag.
Abaixo temos a chamada para o plugin imgAreaSelect. Precisamos armazená-lo em uma variável global, chamada aqui de “ias”, porque posteriormente vamos alterar/limpar áreas de seleções de acordo com a interação do usuário (pressionado a tecla ESC). Por isso também utilizamos a opção “instance: true”.
[cce lang="jquery"]
ias = $(‘img#foto’).imgAreaSelect({
handles: true,
instance: true,
onSelectEnd: formTag,
onSelectStart: function(){
$(‘.form-tag’).remove();
}
});
[/cce]
O evento “onSelectEnd” representa o momento em que o usuário termina de marcar uma área – e é nele que executamos a função “formTag” para exibir o campo de texto para preenchimento. Já o “onSelectStart” representa o início do movimento de seleção e, nesse caso, precisamos eliminar qualquer outro form presente para evitar confusão.
Salvando as tags
Ok, hora de exibir o formulário para o usuário adicionar uma tag. Qualquer função no evento “onSelectEnd” pode (e deve) receber dois parâmetros: img e selection. O primeiro é um objeto que representa a imagem onde foi aplicada a seleção e o segundo contém todas as informações de tamanho e posicionamento. Os vértices X e Y, necessários para posicionar o formulário logo abaixo da marcação, são representados por selection.x1 e selection.y1, respectivamente.
[cce lang="jquery"]
var formTag = function(img, selection){
$(‘.form-tag’).remove();
if(selection.width > 0 && selection.height > 0){
$(‘
‘).insertAfter(img);
$(‘.form-tag’)
.css({
top : (selection.y1 + selection.height),
left : selection.x1
})
.find(‘input.tag-name’)
.focus()
.data(‘selection’, selection);
}
};
[/cce]
Notem que, antes de exibir o formulário verificamos com [ccei lang="jquery"]if(selection.width > 0 && selection.height > 0)[/ccei] se de fato a seleção existe ou se o usuário apenas clicou na área da foto (acredito ser uma falha do plugin, já que nenhuma seleção foi criada). E, ao adicionar o formulário, jogamos o foco do cursor para o campo de texto e armazenamos as posições, para usarmos mais tarde, no atributo data do input.
Agora precisamos identificar quando o usuário pressionar enter ou ESC no input. Pressionando enter, nosso script deve salvar e exibir a tag na foto, enquanto a tecla ESC representa o cancelamento da ação, ou seja, remove o formulário. Utilizamos o evento keyup no input com uma função recebendo o parâmetro “e” (o próprio evento keyup). Os atributos “keyCode” e “which” equivalem à tecla pressionada pelo usuário, onde 13 é o enter e 27 ESC. Precisamos utilizar ambos porque alguns navegadores utilizam keyCode e outros which.
[cce lang="jquery"]
$(‘input.tag-name’).live(‘keyup’, function(e){
if(e.keyCode == 13 || e.which == 13){ // enter
if($(this).val() != “”){
var selection = $(this).data(‘selection’);
$(‘‘+$(this).val()+’‘).appendTo($(this).parent().parent());
$(‘.tag:last’)
.css({
height: selection.height,
width: selection.width,
top: selection.y1,
left:selection.x1
})
.draggable({ containment: ‘#foto’ })
.resizable({ containment: ‘#foto’, ghost: true });
limpaFormTag();
}
}else if(e.keyCode == 27 || e.which == 27){ // esc
limpaFormTag();
}
});
[/cce]
Primeiro validamos o conteúdo do input – não pode ser vazio. Caso o usuário tenha informado o conteúdo da tag, adicionamos o elemento span com a classe tag ao parágrafo da imagem. Com a tag recém adicionada, buscamos as dimensões e posicionamento armazenadas no atributo data-selection do input e definimos o css do span. Para dar um toque especial à nossa interface, conforme mencionado anteriormente, a tag ainda recebe os efeitos draggable e resizable, da jQueryUI, permitindo assim mover ou alterar seu tamanho depois de criada.
A função “limpaFormTag” esconde o formulário e atualiza nossa instânce do plugin imgAreaSelect, removendo qualquer seleção em andamento.
[cce lang="jquery"]
var limpaFormTag = function(){
$(‘.form-tag’).remove();
ias.setOptions({hide:true});
ias.update();
};
[/cce]
Com tudo pronto, falta definir a ação do link que exibe/oculta as tags. O método “toggle” automaticamente identifica se o seletor, nossas tags, estão visíveis ou não e executa a ação (exibir/ocultar) de acordo com o estado atual do elemento.
[cce lang="jquery"]
$(‘.toggle-tags’).click(function(e){
$(‘.tag’).toggle();
if($(‘.tag:visible’).length > 0)
$(this).text(‘ocultar tags’);
else
$(this).text(‘exibir tags’);
e.preventDefault();
});
[/cce]
E agora, para onde ir?
É claro que, para essa interface de fato funcionar, seria necessário armazenar as informações das tags em banco de dados. No nosso exemplo, ao atualizar a página, todas as essas informações serão perdidas. Logo, um dos próximos passos seria um script server-side executado quando o usuário pressionar a tecla enter no input.
Também seria legal desenvolver opções para edição do conteúdo e exclusão das tags.
E que tal transformar tudo em um plugin? Só não esqueça de compartilhá-lo com a gente!
Downloads & referências
- jQuery UI
- plugin imgAreaSelect
- Visualizar exemplo
- Download do código fonte
- Tabela com KeyCodes para JavaScript
Pingback: Javascript agora é no Tableless « Leonardowesleidiniz's Blog