diff options
| author | Hsieh Chin Fan <pham@topo.tw> | 2024-09-22 19:15:23 +0800 |
|---|---|---|
| committer | Hsieh Chin Fan <pham@topo.tw> | 2024-09-22 19:29:51 +0800 |
| commit | bdafef6dd6b5399e0d552452ef63c52c5061d38b (patch) | |
| tree | ec1ac0a63a66fc867d2b7d90cbaab9753461e2b0 /src | |
| parent | e7715f530a25cd923581dfbbb847e22793f5cde3 (diff) | |
feat: make utils stable when user is managing
Diffstat (limited to 'src')
| -rw-r--r-- | src/Layout.mjs | 15 | ||||
| -rw-r--r-- | src/css/dumbymap.css | 106 |
2 files changed, 71 insertions, 50 deletions
diff --git a/src/Layout.mjs b/src/Layout.mjs index d0fde0f..23588a1 100644 --- a/src/Layout.mjs +++ b/src/Layout.mjs | |||
| @@ -157,9 +157,24 @@ export class Overlay extends Layout { | |||
| 157 | .finished | 157 | .finished |
| 158 | .finally(() => this.addDraggable(wrapper)) | 158 | .finally(() => this.addDraggable(wrapper)) |
| 159 | 159 | ||
| 160 | // Trivial case: | ||
| 161 | // This hack make sure utils remains at the same place even when wrapper resized | ||
| 162 | // Prevent DOMRect changes when user clicking plus/minus button many times | ||
| 163 | const utils = wrapper.querySelector('.utils') | ||
| 164 | utils.onmouseover = () => { | ||
| 165 | const { left, top } = utils.getBoundingClientRect() | ||
| 166 | utils.style.cssText = `visibility: visible; z-index: 9000; position: fixed; transition: unset; left: ${left}px; top: ${top}px;` | ||
| 167 | document.body.appendChild(utils) | ||
| 168 | } | ||
| 169 | utils.onmouseout = () => { | ||
| 170 | wrapper.appendChild(utils) | ||
| 171 | utils.removeAttribute('style') | ||
| 172 | } | ||
| 173 | |||
| 160 | // Close button | 174 | // Close button |
| 161 | wrapper.querySelector('#close').onclick = () => { | 175 | wrapper.querySelector('#close').onclick = () => { |
| 162 | wrapper.classList.add('hide') | 176 | wrapper.classList.add('hide') |
| 177 | utils.removeAttribute('style') | ||
| 163 | } | 178 | } |
| 164 | // Plus/Minus font-size of content | 179 | // Plus/Minus font-size of content |
| 165 | wrapper.querySelector('#plus-font-size').onclick = () => { | 180 | wrapper.querySelector('#plus-font-size').onclick = () => { |
diff --git a/src/css/dumbymap.css b/src/css/dumbymap.css index cb692ae..b4689b9 100644 --- a/src/css/dumbymap.css +++ b/src/css/dumbymap.css | |||
| @@ -248,6 +248,51 @@ | |||
| 248 | } | 248 | } |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | .utils { | ||
| 252 | display: flex; | ||
| 253 | |||
| 254 | position: absolute; | ||
| 255 | left: 100%; | ||
| 256 | top: calc(0% - 2rem); | ||
| 257 | |||
| 258 | font-size: 1.5rem; | ||
| 259 | |||
| 260 | visibility: hidden; | ||
| 261 | |||
| 262 | gap: 6px; | ||
| 263 | padding-inline: 1rem; | ||
| 264 | padding-block: 2rem; | ||
| 265 | |||
| 266 | |||
| 267 | &:hover { | ||
| 268 | opacity: 1; | ||
| 269 | visibility: visible; | ||
| 270 | } | ||
| 271 | |||
| 272 | [id] { | ||
| 273 | padding: 0.2rem 0.4rem; | ||
| 274 | |||
| 275 | border: 3px gray solid; | ||
| 276 | border-radius: 5px; | ||
| 277 | |||
| 278 | background: white; | ||
| 279 | |||
| 280 | user-select: none; | ||
| 281 | } | ||
| 282 | |||
| 283 | #close { | ||
| 284 | cursor: pointer; | ||
| 285 | } | ||
| 286 | |||
| 287 | #plus-font-size { | ||
| 288 | cursor: zoom-in; | ||
| 289 | } | ||
| 290 | |||
| 291 | #minus-font-size { | ||
| 292 | cursor: zoom-out; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | |||
| 251 | .draggable-block { | 296 | .draggable-block { |
| 252 | overflow: visible; | 297 | overflow: visible; |
| 253 | width: fit-content; | 298 | width: fit-content; |
| @@ -277,7 +322,6 @@ | |||
| 277 | padding-inline: 1em; | 322 | padding-inline: 1em; |
| 278 | 323 | ||
| 279 | /* allow random width/height after resize */ | 324 | /* allow random width/height after resize */ |
| 280 | |||
| 281 | &[style*="height"], | 325 | &[style*="height"], |
| 282 | &[style*="width"] { | 326 | &[style*="width"] { |
| 283 | max-width: unset; | 327 | max-width: unset; |
| @@ -307,6 +351,7 @@ | |||
| 307 | display: block; | 351 | display: block; |
| 308 | overflow: clip; | 352 | overflow: clip; |
| 309 | width: 100%; | 353 | width: 100%; |
| 354 | padding-bottom: 1em; | ||
| 310 | 355 | ||
| 311 | position: absolute; | 356 | position: absolute; |
| 312 | left: 0; | 357 | left: 0; |
| @@ -314,6 +359,7 @@ | |||
| 314 | z-index: 1; | 359 | z-index: 1; |
| 315 | border-top-left-radius: 0.3rem; | 360 | border-top-left-radius: 0.3rem; |
| 316 | border-top-right-radius: 0.3rem; | 361 | border-top-right-radius: 0.3rem; |
| 362 | } | ||
| 317 | 363 | ||
| 318 | .handle { | 364 | .handle { |
| 319 | font-size: 1.1rem; | 365 | font-size: 1.1rem; |
| @@ -322,72 +368,32 @@ | |||
| 322 | transform: translate(0, -0.6rem); | 368 | transform: translate(0, -0.6rem); |
| 323 | transition: all 0.3s ease-in-out; | 369 | transition: all 0.3s ease-in-out; |
| 324 | } | 370 | } |
| 325 | } | ||
| 326 | |||
| 327 | .utils { | ||
| 328 | display: none; | ||
| 329 | } | ||
| 330 | 371 | ||
| 331 | &.hide { | 372 | &.hide { |
| 332 | animation: fade-out 0.3s; | ||
| 333 | |||
| 334 | opacity: 0; | 373 | opacity: 0; |
| 374 | transition: all 0.5s; | ||
| 335 | visibility: hidden; | 375 | visibility: hidden; |
| 336 | } | 376 | } |
| 337 | 377 | ||
| 338 | &:has(.draggable-part:hover, .utils:hover), | 378 | &.drag, &:has(.draggable-part:hover) { |
| 339 | &.drag { | ||
| 340 | .dumby-block { | ||
| 341 | color: gray; | ||
| 342 | |||
| 343 | opacity: 0.7; | ||
| 344 | } | ||
| 345 | |||
| 346 | .handle { | 379 | .handle { |
| 347 | background: #e1e1e1; | 380 | background: #e1e1e1; |
| 348 | 381 | ||
| 349 | transform: unset; | 382 | transform: unset; |
| 350 | } | 383 | } |
| 351 | 384 | ||
| 352 | .utils { | 385 | .dumby-block { |
| 353 | display: flex; | 386 | color: gray; |
| 354 | 387 | ||
| 355 | position: absolute; | 388 | opacity: 0.7; |
| 356 | left: 100%; | 389 | } |
| 357 | top: 0; | ||
| 358 | top: -0.5rem; | ||
| 359 | 390 | ||
| 360 | font-size: 1.5rem; | ||
| 361 | 391 | ||
| 362 | gap: 6px; | 392 | .utils { |
| 393 | visibility: visible; | ||
| 363 | animation: fade-in 1s; | 394 | animation: fade-in 1s; |
| 364 | padding-left: 1rem; | ||
| 365 | |||
| 366 | transition: opacity 0.5s; | ||
| 367 | |||
| 368 | > * { | ||
| 369 | padding: 0.2rem 0.4rem; | ||
| 370 | |||
| 371 | border: 3px gray solid; | ||
| 372 | border-radius: 5px; | ||
| 373 | |||
| 374 | background: white; | ||
| 375 | |||
| 376 | user-select: none; | ||
| 377 | } | ||
| 378 | |||
| 379 | #close { | ||
| 380 | cursor: pointer; | ||
| 381 | } | ||
| 382 | |||
| 383 | #plus-font-size { | ||
| 384 | cursor: zoom-in; | ||
| 385 | } | ||
| 386 | |||
| 387 | #minus-font-size { | ||
| 388 | cursor: zoom-out; | ||
| 389 | } | ||
| 390 | } | 395 | } |
| 396 | |||
| 391 | } | 397 | } |
| 392 | } | 398 | } |
| 393 | 399 | ||