Diagrama Anotado
Diagrama visual com anotações textuais conectadas por setas ou linhas. Explica componentes, relações e fluxos de forma integrada entre imagem e texto.
Experimente
Anatomia de uma Planta
Flor
Estrutura reprodutiva da planta — atrai polinizadores e, após a fecundação, dá origem aos frutos e sementes.
Folha
Realiza a fotossíntese, convertendo luz solar, água e CO₂ em energia química e liberando oxigênio.
Caule
Sustenta a planta e transporta água e nutrientes entre a raiz e as folhas através de tecidos especializados.
Raiz
Fixa a planta ao solo e absorve água e minerais, além de armazenar reservas de energia em algumas espécies.
Código-fonte
Dados de exemplo
Cada ponto tem a posição (x/y em porcentagem da imagem), o rótulo curto e a explicação detalhada. "deslocamento" é opcional — só usado quando o rótulo em cima do próprio ponto atrapalharia a leitura do desenho.
| 1 |
<?php
|
| 2 |
$pontos = [
|
| 3 |
['x' => 50, 'y' => 15, 'rotulo' => 'Guidão', 'explicacao' => 'Controla a direção da bicicleta e serve de apoio pras mãos — a altura e o ângulo influenciam diretamente a postura de quem pedala.'],
|
| 4 |
['x' => 78, 'y' => 45, 'rotulo' => 'Selim', 'explicacao' => 'Banco onde o ciclista se senta — a altura correta evita sobrecarga nos joelhos ao pedalar.'],
|
| 5 |
['x' => 50, 'y' => 65, 'deslocamento' => 'direita', 'rotulo' => 'Pedal', 'explicacao' => 'Ponto de contato com os pés — converte a força das pernas em rotação, transmitida à roda pela corrente.'],
|
| 6 |
['x' => 20, 'y' => 85, 'rotulo' => 'Roda', 'explicacao' => 'Converte a rotação em deslocamento — o raio e a pressão do pneu afetam o conforto e a eficiência do pedalar.'],
|
| 7 |
];
|
| 8 |
?>
|
Estrutura do diagrama
A imagem fica numa caixa quadrada; cada ponto é um "wrapper" posicionado por x/y — dentro dele, ou o rótulo fica centralizado direto no ponto (padrão), ou usa marcador + linha quando "deslocamento" está definido.
| 1 |
<div class="diagrama" data-tipo="diagrama-anotado">
|
| 2 |
<div class="imagem-area">
|
| 3 |
<img src="diagrama.jpg" alt="">
|
| 4 |
<?php foreach ($pontos as $i => $ponto): $desloc = $ponto['deslocamento'] ?? null; ?>
|
| 5 |
<div class="ponto" data-ponto="<?= $i ?>" style="left: <?= $ponto['x'] ?>%; top: <?= $ponto['y'] ?>%;">
|
| 6 |
<?php if ($desloc === 'direita'): ?>
|
| 7 |
<span class="marcador" aria-hidden="true"></span>
|
| 8 |
<span class="linha linha-direita" aria-hidden="true"></span>
|
| 9 |
<span class="rotulo rotulo-direita"><?= htmlspecialchars($ponto['rotulo']) ?></span>
|
| 10 |
<?php else: ?>
|
| 11 |
<span class="rotulo rotulo-centro"><?= htmlspecialchars($ponto['rotulo']) ?></span>
|
| 12 |
<?php endif; ?>
|
| 13 |
</div>
|
| 14 |
<?php endforeach; ?>
|
| 15 |
</div>
|
Detalhamento
Uma explicação completa por ponto, sempre visível — não é revelada por clique. Liga com o ponto correspondente na imagem pelo mesmo data-ponto, que o JS usa pra destacar os dois juntos.
| 1 |
<div class="detalhes">
|
| 2 |
<?php foreach ($pontos as $i => $ponto): ?>
|
| 3 |
<div class="detalhe" data-ponto="<?= $i ?>">
|
| 4 |
<p class="detalhe-titulo"><?= htmlspecialchars($ponto['rotulo']) ?></p>
|
| 5 |
<p class="detalhe-texto"><?= htmlspecialchars($ponto['explicacao']) ?></p>
|
| 6 |
</div>
|
| 7 |
<?php endforeach; ?>
|
| 8 |
</div>
|
| 9 |
</div>
|
Área da imagem
Caixa quadrada — a imagem cobre o espaço inteiro (object-fit: cover), os pontos ficam por cima dela.
| 1 |
.imagem-area {
|
| 2 |
position: relative;
|
| 3 |
aspect-ratio: 1 / 1;
|
| 4 |
border-radius: 12px;
|
| 5 |
overflow: hidden;
|
| 6 |
background: #f1f5f9;
|
| 7 |
}
|
| 8 |
.imagem-area img {
|
| 9 |
position: absolute;
|
| 10 |
inset: 0;
|
| 11 |
width: 100%;
|
| 12 |
height: 100%;
|
| 13 |
object-fit: cover;
|
| 14 |
}
|
Rótulo centralizado
O padrão — o rótulo fica exatamente em cima do ponto que descreve, sem precisar de marcador. Bom pra regiões grandes e claras da imagem.
| 1 |
.ponto {
|
| 2 |
position: absolute;
|
| 3 |
}
|
| 4 |
.rotulo {
|
| 5 |
display: inline-block;
|
| 6 |
max-width: 9rem;
|
| 7 |
padding: 4px 10px;
|
| 8 |
border-radius: 999px;
|
| 9 |
background: rgba(255, 255, 255, .9);
|
| 10 |
border: 1px solid rgba(99, 102, 241, .5);
|
| 11 |
font-size: 12px;
|
| 12 |
font-weight: 600;
|
| 13 |
color: #4338ca;
|
| 14 |
text-align: center;
|
| 15 |
line-height: 1.3;
|
| 16 |
}
|
| 17 |
.rotulo-centro {
|
| 18 |
position: absolute;
|
| 19 |
left: 0;
|
| 20 |
top: 0;
|
| 21 |
transform: translate(-50%, -50%);
|
| 22 |
}
|
Marcador + linha
Usado quando o rótulo em cima do próprio ponto atrapalharia a leitura do desenho (ex.: um rótulo largo sobre um traço fino). O marcador fica exatamente no ponto; a linha liga até o rótulo, deslocado pro lado.
| 1 |
.marcador {
|
| 2 |
position: absolute;
|
| 3 |
left: 0;
|
| 4 |
top: 0;
|
| 5 |
width: 10px;
|
| 6 |
height: 10px;
|
| 7 |
transform: translate(-50%, -50%);
|
| 8 |
border-radius: 999px;
|
| 9 |
background: #6366f1;
|
| 10 |
border: 2px solid #fff;
|
| 11 |
z-index: 2;
|
| 12 |
}
|
| 13 |
.linha {
|
| 14 |
position: absolute;
|
| 15 |
top: -1px;
|
| 16 |
height: 2px;
|
| 17 |
background: #6366f1;
|
| 18 |
opacity: .55;
|
| 19 |
z-index: 1;
|
| 20 |
}
|
| 21 |
.linha-direita {
|
| 22 |
left: 0;
|
| 23 |
width: 26px;
|
| 24 |
}
|
| 25 |
.rotulo-direita {
|
| 26 |
position: absolute;
|
| 27 |
left: 32px;
|
| 28 |
top: 0;
|
| 29 |
transform: translateY(-50%);
|
| 30 |
z-index: 3;
|
| 31 |
}
|
Detalhamento
Uma explicação por ponto, sempre visível — quem quiser só a visão geral já tem tudo no diagrama; quem quiser mais detalhe lê aqui.
| 1 |
.detalhes {
|
| 2 |
margin-top: 16px;
|
| 3 |
display: flex;
|
| 4 |
flex-direction: column;
|
| 5 |
gap: 12px;
|
| 6 |
}
|
| 7 |
.detalhe {
|
| 8 |
padding: 6px 8px;
|
| 9 |
margin: 0 -8px;
|
| 10 |
border-radius: 8px;
|
| 11 |
transition: background-color .15s ease;
|
| 12 |
}
|
| 13 |
.detalhe-titulo {
|
| 14 |
margin: 0;
|
| 15 |
font-weight: 600;
|
| 16 |
font-size: 14px;
|
| 17 |
color: #1e293b;
|
| 18 |
}
|
| 19 |
.detalhe-texto {
|
| 20 |
margin: 4px 0 0;
|
| 21 |
font-size: 13px;
|
| 22 |
line-height: 1.5;
|
| 23 |
color: #64748b;
|
| 24 |
}
|
Destaque cruzado
Ao passar o mouse (ou focar) num ponto da imagem ou no bloco de detalhe correspondente, os dois acendem juntos — nenhum dos dois fica escondido, só reforçados visualmente.
| 1 |
.ponto.destaque .rotulo {
|
| 2 |
border-color: #6366f1;
|
| 3 |
box-shadow: 0 0 0 3px rgba(99, 102, 241, .25);
|
| 4 |
}
|
| 5 |
.detalhe.destaque {
|
| 6 |
background: rgba(99, 102, 241, .07);
|
| 7 |
}
|
Ligar imagem e detalhamento
Cada ponto da imagem e seu bloco de detalhe compartilham o mesmo data-ponto — passar o mouse (ou focar) num dos dois destaca o outro, sem esconder nenhum dos dois.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
document.querySelectorAll('.diagrama').forEach(function (diagrama) {
|
| 3 |
function destacar(indice, ligado) {
|
| 4 |
var ponto = diagrama.querySelector('.ponto[data-ponto="' + indice + '"]');
|
| 5 |
var detalhe = diagrama.querySelector('.detalhe[data-ponto="' + indice + '"]');
|
| 6 |
if (ponto) ponto.classList.toggle('destaque', ligado);
|
| 7 |
if (detalhe) detalhe.classList.toggle('destaque', ligado);
|
| 8 |
}
|
| 9 |
|
| 10 |
diagrama.querySelectorAll('.ponto, .detalhe').forEach(function (item) {
|
| 11 |
var indice = item.dataset.ponto;
|
| 12 |
item.addEventListener('mouseenter', function () { destacar(indice, true); });
|
| 13 |
item.addEventListener('mouseleave', function () { destacar(indice, false); });
|
| 14 |
});
|
| 15 |
});
|
| 16 |
});
|