Skip to content

Commit a57979e

Browse files
committed
Versão 1.4 - Adição do Changelog, exportações reformuladas e interface mobile melhorada
1 parent db06fe1 commit a57979e

5 files changed

Lines changed: 539 additions & 351 deletions

File tree

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
Todas as mudanças notáveis no projeto InvMap serão documentadas neste arquivo.
4+
5+
## [v1.4] - 09/01/2026
6+
### ✔Adicionado
7+
- **Changelog:** Adicionado arquivo de changelog para documentar todas as mudanças notáveis no projeto InvMap.
8+
- **Interface Mobile Melhorada:** Novo sistema de menu "hambúrguer" para dispositivos móveis. Os botões agora ficam organizados em uma coluna flutuante com rolagem, melhorando a área de visualização do mapa.
9+
10+
### ⚙ Corrigido
11+
- **Motor de Exportação:** Substituição do método antigo pela biblioteca `html-to-image`. Agora:
12+
- Imagens dentro dos nós são renderizadas corretamente.
13+
- Textos digitados em `inputs` e `textareas` aparecem na exportação.
14+
- Ícones e estilos CSS são preservados.
15+
- **Exportação SVG:** Agora gera um arquivo vetorial híbrido (com foreignObject) que mantém a editabilidade e a fidelidade visual.
16+
- **Correção de Bugs:** Corrigido varios bugs que afetavam negativamente a experiência do mapa.
17+
18+
### 🖊 Alterado
19+
- Reorganização visual da barra de ferramentas (agora utiliza um wrapper flutuante para melhor posicionamento).

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<p align="center">
1414
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
15-
<img src="https://img.shields.io/badge/version-1.1-brightgreen" alt="Version">
15+
<img src="https://img.shields.io/badge/version-1.4-orange" alt="Version">
1616
<img src="https://img.shields.io/badge/status-ativo-success" alt="Status">
1717
</p>
1818

@@ -36,6 +36,10 @@ Acesse a ferramenta diretamente no seu navegador:
3636

3737
Não há necessidade de instalação ou cadastro. Para um guia detalhado de todas as funcionalidades e atalhos, consulte nosso [artigo](https://sniff.wolfsecurity.com.br/invmap-intro) na wiki do Projeto Sniff.
3838

39+
## 📝 Histórico de Versões
40+
41+
Para ver todas as mudanças e atualizações, consulte o [CHANGELOG](CHANGELOG.md).
42+
3943
### 🛠️ Desenvolvimento Local
4044

4145
Para executar o InvMap localmente, basta clonar este repositório e abrir o arquivo `index.html` em qualquer navegador.

css/style.css

Lines changed: 137 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ body {
7272
opacity: 0.7;
7373
}
7474

75-
/* Container principal do mapa */
75+
/* =================================================== */
76+
/* || ESTILOS PARA OS ELEMENTOS DO MAPA || */
77+
/* =================================================== */
78+
79+
/* --- Container principal do mapa --- */
7680
#svg-container {
7781
flex-grow: 1;
7882
background-color: #1a1a1f;
@@ -85,30 +89,58 @@ body {
8589
stroke-width: 1px;
8690
}
8791

88-
/* Container flutuante */
89-
#controls-container {
92+
/* --- Container flutuante --- */
93+
#main-controls-wrapper {
9094
position: absolute;
91-
top: 20px;
92-
left: 20px;
93-
z-index: 5;
94-
background-color: rgba(41, 41, 48, 0.1);
95-
padding: 8px;
96-
border-radius: 25px;
95+
top: 10px;
96+
left: 10px;
97+
z-index: 100;
98+
display: flex;
99+
flex-direction: column;
100+
align-items: flex-start;
101+
gap: 10px;
102+
pointer-events: none;
103+
}
104+
105+
#main-controls-wrapper > * {
106+
pointer-events: auto;
107+
}
108+
109+
#mobile-menu-toggle {
110+
display: none;
111+
width: 40px;
112+
height: 40px;
113+
background-color: var(--sniff-bg-widget);
114+
color: var(--sniff-text-primary);
97115
border: 1px solid var(--sniff-border-color);
98-
backdrop-filter: blur(1px);
116+
border-radius: 15px;
117+
cursor: pointer;
118+
font-size: 1.1rem;
119+
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
120+
transition: all 0.2s;
121+
justify-content: center;
122+
align-items: center;
123+
}
124+
125+
#controls-container {
126+
background-color: rgba(41, 41, 48, 0.45);
127+
backdrop-filter: blur(5px);
128+
border: 1px solid var(--sniff-border-color);
129+
border-radius: 20px;
130+
padding: 5px;
131+
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
99132
}
100133

101134
#controls {
102135
display: flex;
136+
flex-direction: row;
103137
align-items: center;
104138
gap: 8px;
105139
}
106140

107-
/* Botões de ícone */
108-
#controls button,
109-
#controls label,
110-
#export-map-btn,
111-
#add-visuals-btn {
141+
#controls-container button,
142+
#controls-container label,
143+
.control-btn {
112144
width: 36px;
113145
height: 36px;
114146
border: none;
@@ -123,94 +155,104 @@ body {
123155
align-items: center;
124156
}
125157

126-
#controls button:hover,
127-
#controls label:hover,
128-
#export-map-btn:hover,
129-
#add-visuals-btn:hover {
158+
#controls-container button:hover,
159+
#controls-container label:hover,
160+
.control-btn:hover {
130161
background-color: rgba(255, 255, 255, 0.1);
131162
color: var(--sniff-text-primary);
132163
}
133164

134-
.btn-primary { /* Botão de Salvar */
135-
background-color: var(--sniff-accent);
136-
color: white;
137-
}
138-
.btn-primary:hover {
139-
background-color: #e84627;
140-
color: white;
141-
}
142-
143-
.separator { /* Linha separadora */
165+
.separator {
144166
width: 1px;
145167
height: 20px;
146168
background-color: var(--sniff-border-color);
147169
margin: 0 4px;
148170
}
149171

150-
#svg-container:active { cursor: grabbing; }
172+
@media (max-width: 768px) {
173+
#mobile-menu-toggle {
174+
display: flex;
175+
}
176+
177+
#controls-container {
178+
display: none;
179+
width: 50px;
180+
max-height: 60vh;
181+
overflow-y: auto;
182+
overflow-x: hidden;
183+
border-radius: 20px;
184+
padding: 10px 5px;
185+
background-color: rgba(41, 41, 48, 0.45);
186+
backdrop-filter: blur(5px);
187+
}
188+
189+
#controls {
190+
flex-direction: column;
191+
gap: 12px;
192+
}
193+
194+
#controls-container.show {
195+
display: block;
196+
animation: slideDown 0.3s ease;
197+
}
198+
199+
.separator { display: none; }
200+
}
201+
202+
@keyframes slideDown {
203+
from { opacity: 0; transform: translateY(-10px); }
204+
to { opacity: 1; transform: translateY(0); }
205+
}
151206

152207
/* =================================================== */
153208
/* || ESTILOS PARA OS ELEMENTOS DO MAPA || */
154209
/* =================================================== */
155210

156-
/* Estilo para o grupo do nó (retângulo + texto) */
157211
.node-group {
158212
cursor: pointer;
159213
}
160-
161-
/* Estilo para o corpo do nó (o retângulo) */
162214
.node-rect {
163215
fill: #25252c;
164216
stroke: #2a2a30;
165217
stroke-width: 2px;
166-
rx: 8px; /* Cantos arredondados */
218+
rx: 8px;
167219
}
168220
.node-group:hover .node-rect {
169221
stroke: var(--sniff-accent);
170222
}
171-
172-
/* Estilo para o texto do nó */
173223
.node-label {
174-
fill: var(--sniff-text-primary); /* Cor do texto */
224+
fill: var(--sniff-text-primary);
175225
font-size: 14px;
176-
text-anchor: middle; /* Centraliza o texto horizontalmente */
177-
dominant-baseline: middle; /* Centraliza o texto verticalmente */
178-
pointer-events: none; /* Faz o texto não interferir no clique do mouse */
226+
text-anchor: middle;
227+
dominant-baseline: middle;
228+
pointer-events: none;
179229
}
180-
181-
/* Estilo para a seta */
182230
.arrowhead-path {
183-
fill: #4a4a52; /* Mesma cor da linha */
231+
fill: #4a4a52;
184232
}
185-
186-
/* Estilo para a linha de conexão (edge) */
187233
.edge-path {
188234
stroke: #4a4a52;
189235
stroke-width: 2px;
190236
fill: none;
191-
marker-end: url(#arrowhead); /* Aplica a seta */
237+
marker-end: url(#arrowhead);
192238
}
193-
194-
/* Estilo para a linha de preview de conexão */
195239
.link-preview-path {
196-
stroke: var(--sniff-accent); /* Laranja para destaque */
240+
stroke: var(--sniff-accent);
197241
stroke-width: 2px;
198-
stroke-dasharray: 5, 5; /* Tracejada */
242+
stroke-dasharray: 5, 5;
199243
fill: none;
200244
opacity: 0.6;
201-
pointer-events: none; /* Ignora cliques para não atrapalhar a seleção do alvo */
202-
transition: d 0.05s linear; /* Suaviza levemente o movimento */
245+
pointer-events: none;
246+
transition: d 0.05s linear;
203247
}
204248

205-
/* Estilo para o nó selecionado */
206249
.node-group.selected .node-rect {
207250
stroke: var(--sniff-accent);
208251
stroke-width: 3px;
209252
}
210253

211254
/* Estilos para os elementos HTML dentro do nó SVG */
212255
.node-foreign-object {
213-
/* Garante que o texto possa ser selecionado */
214256
pointer-events: none;
215257
}
216258

@@ -256,7 +298,7 @@ body {
256298

257299
#add-controls-container.visible {
258300
opacity: 1;
259-
pointer-events: all; /* Ativa a interação quando visível */
301+
pointer-events: all;
260302
}
261303

262304
.add-node-context-btn {
@@ -272,8 +314,6 @@ body {
272314
font-weight: bold;
273315
line-height: 1;
274316
cursor: pointer;
275-
276-
/* Transição suave para todas as propriedades */
277317
transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
278318
}
279319

@@ -282,23 +322,20 @@ body {
282322
transform-origin: center;
283323
}
284324

285-
/* Estilos para os nós de imagem */
286325
.node-image-container {
287326
width: 100%;
288327
height: 100%;
289328
border-radius: 6px;
290-
overflow: hidden; /* Corta as pontas da imagem */
291-
position: relative; /* Contexto para a legenda */
329+
overflow: hidden;
330+
position: relative;
292331
}
293332

294-
/* A imagem em si */
295333
.node-image {
296334
width: 100%;
297335
height: 100%;
298336
object-fit: cover;
299337
}
300338

301-
/* A legenda da imagem */
302339
.image-node-label {
303340
position: absolute;
304341
bottom: 5px;
@@ -312,7 +349,7 @@ body {
312349
max-width: 90%;
313350
white-space: nowrap;
314351
overflow: hidden;
315-
text-overflow: ellipsis; /* Adiciona "..." se o nome for muito longo */
352+
text-overflow: ellipsis;
316353
}
317354

318355
.view-image-btn {
@@ -333,14 +370,12 @@ body {
333370
transition: all 0.2s ease;
334371
}
335372

336-
/* Legenda e botão ficam escondidos por padrão */
337373
.image-node-label,
338374
.view-image-btn {
339375
opacity: 0;
340376
transition: opacity 0.2s ease-in-out;
341377
}
342378

343-
/* Mostra a legenda e o botão no hover ou quando selecionado */
344379
.node-group:hover .image-node-label,
345380
.node-group.selected .image-node-label,
346381
.node-group:hover .view-image-btn,
@@ -1250,4 +1285,41 @@ body {
12501285

12511286
@keyframes fadeOut {
12521287
to { opacity: 0; transform: scale(0.95); }
1288+
}
1289+
1290+
/* Temas */
1291+
/* --- Override para Exportação em Tema Claro --- */
1292+
.forcing-light-theme {
1293+
background-color: #ffffff !important;
1294+
}
1295+
1296+
.forcing-light-theme .node-group rect {
1297+
fill: #f2f2f2 !important;
1298+
stroke: #333 !important;
1299+
}
1300+
1301+
.forcing-light-theme text,
1302+
.forcing-light-theme input,
1303+
.forcing-light-theme textarea,
1304+
.forcing-light-theme .text-sticker-label,
1305+
.forcing-light-theme .node-foreign-object,
1306+
.forcing-light-theme h4,
1307+
.forcing-light-theme span,
1308+
.forcing-light-theme div {
1309+
fill: #000000 !important;
1310+
color: #000000 !important;
1311+
}
1312+
1313+
.forcing-light-theme i {
1314+
color: #000000 !important;
1315+
text-shadow: none !important;
1316+
}
1317+
1318+
.forcing-light-theme path,
1319+
.forcing-light-theme line {
1320+
stroke: #333 !important;
1321+
}
1322+
.forcing-light-theme input::placeholder,
1323+
.forcing-light-theme textarea::placeholder {
1324+
color: rgba(0, 0, 0, 0.5) !important;
12531325
}

0 commit comments

Comments
 (0)