Panel1 telah dipisahkan menjadi 2 layer terpisah untuk mengoptimalkan pengalaman zoom:
- panel1-root: Background/wallpaper (fixed, tidak zoom)
- panel1-layercontainer: Layer objects (dapat zoom)
<div class="panel1 container" id="panel1">
<!-- Background + Layers dijadikan satu -->
</div><div class="panel1 container" id="panel1">
<div class="panel1-root" id="panel1-root">
<!-- Background/Wallpaper tetap full size -->
</div>
<div class="panel1-layercontainer" id="panel1-layercontainer">
<!-- Semua layer objects -->
<canvas id="guideCanvas" class="panel1-guide-canvas"></canvas>
</div>
</div>.panel1.container {
position: absolute;
width: 100%;
height: 100%;
top: 0; left: 0;
display: flex;
flex-direction: column;
}.panel1-root {
position: absolute;
top: 0; left: 0;
right: 0; bottom: 0;
background-size: cover;
background-position: center;
background-attachment: fixed; /* PENTING: Tidak ikut scroll/zoom */
z-index: 0;
}.panel1-layercontainer {
position: absolute;
top: 0; left: 0;
right: 0; bottom: 0;
z-index: 1;
transform-origin: center center;
transform: scale(1); /* Akan diubah oleh zoom */
}.panel1-guide-canvas {
position: absolute;
top: 0; left: 0;
z-index: 0;
pointer-events: none;
display: none; /* Tampil saat zoom < 100% */
}Dipanggil saat zoom slider berubah.
// Input: value dari slider (0-10000, 100 = 100%)
// Target: panel1-layercontainer
// Actions:
// - Set transform scale ke layerContainer
// - Update zoomInput display
// - Call updateGuideCanvasVisibility()
// - Record ke historyDipanggil saat user mengetik di zoom input field.
// Input: string nilai zoom (misal "50%")
// Target: panel1-layercontainer
// Actions:
// - Parse value, clamp 0-10000
// - Set transform scale
// - Update slider
// - Call updateGuideCanvasVisibility()Show/hide guide berdasarkan zoom level.
// Input: zoomScale (dari zoom slider, 1.0 = 100%)
// Logic:
// - Jika zoomScale < 1 (zoom out): tampilkan guide
// - Jika zoomScale >= 1 (zoom normal/in): sembunyikan guide
// - Call drawGuideOutline() saat tampilMenggambar outline garis biru langit pada canvas.
// Input: canvas element, layer container element
// Features:
// - Warna: Sky Blue (#87CEEB)
// - Style: Garis dash (5px dash, 5px gap)
// - Spacing: 10% dari tepi
// - Responsive: Otomatis fit ke container size
// - Geometry: Rectangle outline di tengah-tengahconst container = document.getElementById('panel1');
layer.attach(container, null);const container = document.getElementById('panel1-layercontainer') ||
document.getElementById('panel1') ||
document.querySelector('.container');
layer.attach(container, null);Note: Fallback dibuat untuk backward compatibility jika panel1-layercontainer tidak ditemukan.
Mengatur background image untuk panel.
const targetElement = document.getElementById('panel1-root') ||
document.getElementById('panel1');
targetElement.style.backgroundImage = `url('${imageUrl}')`;const targetElement = document.getElementById(panelId);
targetElement.style.backgroundImage = `url('${imageUrl}')`;Mengatur opacity untuk panel.
const targetElement = document.getElementById('panel1-root') ||
document.getElementById('panel1');
targetElement.style.opacity = opacitySlider.value / 100;Guide canvas akan otomatis redraw saat window resize:
window.addEventListener('resize', () => {
const guideCanvas = document.getElementById('guideCanvas');
const layerContainer = document.getElementById('panel1-layercontainer');
if (guideCanvas && layerContainer && guideCanvas.style.display !== 'none') {
drawGuideOutline(guideCanvas, layerContainer);
}
});- Target:
panel1-layercontainer - Action: scale += 0.1
- Max scale: 3.0
- Call:
updateGuideCanvasVisibility()
- Target:
panel1-layercontainer - Action: scale -= 0.1
- Min scale: 0.1
- Call:
updateGuideCanvasVisibility()
| File | Changes |
|---|---|
js/frame/studiopose.js |
HTML structure, CSS styling |
studiopose.html |
HTML structure, CSS styling |
js/studiocharacter/sensivity.js |
handleZoom(), handleZoomInput(), updateGuideCanvasVisibility(), drawGuideOutline() |
js/studiocharacter/studiopose.js |
Layer attachment, renderLayer(), onLayerPointerDown() |
js/studiocharacter/background.js |
setBackground() target updated |
js/studiocharacter/opacity.js |
setOpacity() target updated |
js/studiocharacter/bgconfig.js |
applyBgConfig() target updated |
js/studiocharacter/function.js |
Keyboard shortcut zoom handlers |
-
Zoom Slider Test
- Drag zoom slider ke kanan (zoom in)
- Drag zoom slider ke kiri (zoom out)
- Verifikasi: Layer zoom, background tetap fixed
-
Zoom Input Test
- Ketik "50" di zoom input
- Ketik "150" di zoom input
- Verifikasi: Nilai terupdate, layer berubah ukuran
-
Guide Outline Test
- Set zoom ke 75%
- Verifikasi: Garis biru langit tampil dengan dash pattern
- Set zoom ke 100%
- Verifikasi: Garis biru langit hilang
-
Background Test
- Upload background image untuk panel1
- Zoom in/out
- Verifikasi: Background tetap sama, tidak ikut zoom
- Upload background lain
- Verifikasi: Background berubah, layer tetap di posisi
-
Layer Manipulation Test
- Drag layer saat zoom 50%
- Drag layer saat zoom 150%
- Verifikasi: Layer bergerak sesuai zoom scale, tapi dapat dikontrol
-
Opacity Test
- Set opacity slider untuk panel1
- Verifikasi: Hanya background yang berubah opacity
- Verifikasi: Layer tetap 100% opaque
-
Keyboard Shortcuts Test
- Press Ctrl+P (zoom in)
- Press Ctrl+M (zoom out)
- Verifikasi: Zoom berubah, slider terupdate, guide tampil/hilang
-
Window Resize Test
- Resize window saat zoom 75%
- Verifikasi: Guide outline adjust ke ukuran baru
- Cek apakah
guideCanvaselement ada di HTML - Cek apakah
updateGuideCanvasVisibility()dipanggil - Check browser console untuk error
- Verifikasi bahwa background ditaruh di
panel1-root, bukanpanel1-layercontainer - Check CSS:
background-attachment: fixedharus ada
- Verifikasi bahwa layer.element ada di dalam
panel1-layercontainer - Check pointer event listeners attach ke layer element
- Verifikasi bahwa zoom slider memanggil
handleZoom() - Check console untuk error
- Verifikasi
panel1-layercontainerelement exist
- Guide canvas redraw hanya saat zoom < 100%
- Canvas size matches container size untuk sharp rendering
- Pointer events disabled pada guide canvas (pointer-events: none)
- Transform scale lebih efisien daripada resize individual elements
- Opsi untuk customize guide spacing (bukan hard-coded 10%)
- Opsi untuk customize guide color dan dash style
- Grid guide mode (selain rectangle outline)
- Ruler display di edges saat zoom < 100%
- Snap-to-guide functionality