Cara Membuat Tumpukan Isometrik 3D yang Terurai Saat Scroll, Crosshair, dan Diagram Gantt Otomatis (CSS, JS & PHP)
Cara Membuat Tumpukan Isometrik 3D yang Terurai Saat Scroll, Crosshair, dan Diagram Gantt Otomatis (CSS, JS & PHP)
Engineer backend dan DevOps sering kesulitan memamerkan karyanya. Tidak ada tampilan aplikasi yang cantik untuk difoto, yang ada hanya arsitektur, antrean, dan angka latensi. Template Blueprint menjawabnya dengan meminjam bahasa gambar teknik: kertas biru bergaris, blok judul, anotasi ukuran, dan tampilan isometrik. Artikel ini membahas lima teknik intinya beserta kode yang benar-benar dipakai.
1. Tumpukan isometrik murni CSS 3D
Tampilan isometrik bisa didapat dari dua rotasi saja: miringkan bidang ke belakang dengan rotateX, lalu putar 45 derajat dengan rotateZ. Setiap lapisan adalah div persegi yang diangkat setinggi --i × --gap di sumbu Z:
.iso{--gap:34px;width:280px;height:280px;transform-style:preserve-3d;
transform:rotateX(58deg) rotateZ(-45deg)}
.slab{position:absolute;inset:0;border:2px solid #fff;background:var(--acc);
transform:translateZ(calc(var(--i) * var(--gap)))}
Supaya lapisan terlihat punya ketebalan, tambahkan dua sisi dengan pseudo-element. Sisi depan dilipat ke bawah dengan rotateX(-90deg) dari tepi bawah, sisi kanan dilipat dengan rotateY(90deg) dari tepi kanan:
.slab::before{content:'';position:absolute;left:0;right:0;bottom:0;height:16px;
transform-origin:50% 100%;transform:rotateX(-90deg)}
.slab::after{content:'';position:absolute;top:0;bottom:0;right:0;width:16px;
transform-origin:100% 50%;transform:rotateY(90deg)}
Isinya dibuat dari data. Di PHP, teknologi dikelompokkan per kategori, dan setiap kategori menjadi satu lapisan:
$lapis = array_slice($D['tek_kategori'], 0, 6, true);
foreach ($lapis as $kat => $list) {
echo '<div class="slab" style="--i:' . $i++ . '">';
// label kategori + maksimal 4 logo
}
Pemilik cukup menambah teknologi di CMS. Lapisan baru muncul dengan sendirinya.
2. Exploded view: jarak lapisan mengikuti scroll
Karena posisi setiap lapisan bergantung pada satu variabel --gap, efek "terurai" cukup dibuat dengan mengubah variabel itu dari JavaScript:
const onScroll = () => {
const p = Math.min(1, scrollY / (innerHeight * 0.8));
iso.style.setProperty('--gap', (34 + p * 62).toFixed(1) + 'px');
};
addEventListener('scroll', () => requestAnimationFrame(onScroll), { passive: true });
Saat halaman masih di atas, lapisan rapat seperti satu blok. Setelah digulir 80% tinggi layar, jaraknya hampir tiga kali lipat dan logo di setiap lapisan terlihat jelas. Mengubah satu custom property jauh lebih murah daripada menghitung ulang transformasi enam elemen satu per satu.
3. Crosshair dengan koordinat
Dua garis tipis yang posisinya fixed digeser mengikuti kursor, ditambah label koordinat:
addEventListener('pointermove', e => {
document.body.classList.add('xh-moved');
h.style.transform = `translateY(${e.clientY}px)`;
v.style.transform = `translateX(${e.clientX}px)`;
c.style.transform = `translate(${e.clientX + 12}px, ${e.clientY + 12}px)`;
c.textContent = `X ${String(Math.round(e.pageX)).padStart(4, '0')} · Y ${String(Math.round(e.pageY)).padStart(4, '0')}`;
});
Ada tiga detail kecil yang penting. Pertama, pointer-events: none di lapisan crosshair agar klik tetap sampai ke tombol di bawahnya. Kedua, efek hanya diaktifkan jika matchMedia('(hover: hover) and (pointer: fine)') benar, karena di HP tidak ada kursor. Ketiga, crosshair baru tampil setelah gerakan pertama (kelas xh-moved), sehingga label tidak menempel di pojok kiri atas saat halaman baru dibuka.
4. Diagram Gantt karier dari tanggal di database
Setiap pengalaman punya kolom mulai dan selesai (boleh kosong untuk pekerjaan yang masih berjalan). Kita ubah tanggal menjadi persentase di sepanjang garis waktu:
$posisi = function (?string $tgl) use ($thAwal, $thAkhir): float {
$t = $tgl ? strtotime($tgl) : time();
$x = ((int) date('Y', $t) - $thAwal + ((int) date('n', $t) - 1) / 12) / max(1, $thAkhir - $thAwal);
return round(max(0, min(1, $x)) * 100, 2);
};
Bulan ikut dihitung sebagai pecahan tahun, jadi pekerjaan Juli 2021 berada tepat di tengah tahun 2021. Batang digambar dengan left dan width dalam persen:
<i class="g-bar" style="left:<?= $a ?>%;width:<?= max(1.5, $b - $a) ?>%"></i>
Lebar minimal 1,5% menjaga sertifikasi atau kursus singkat tetap terlihat. Pekerjaan yang masih berjalan diberi kelas now berwarna sorot dengan ujung panah. Saat bagian ini masuk layar, setiap batang dianimasikan dari scaleX(0) dengan transform-origin: 0 50%, seolah sedang digambar dengan penggaris.
5. Kaca pembesar di cover proyek
Lensa adalah elemen bulat yang memakai gambar yang sama sebagai background-image, tetapi dua kali lebih besar. Posisi latar digeser berlawanan arah kursor:
area.addEventListener('pointermove', e => {
const r = img.getBoundingClientRect();
const x = e.clientX - r.left, y = e.clientY - r.top;
lens.style.left = x + 'px'; lens.style.top = y + 'px';
lens.style.backgroundSize = `${r.width * 2}px ${r.height * 2}px`;
lens.style.backgroundPosition = `${-(x * 2 - 110)}px ${-(y * 2 - 110)}px`;
});
Angka 110 adalah setengah diameter lensa (220 piksel), sehingga titik di bawah kursor tepat berada di tengah lensa. Karena ukuran latar dihitung dari ukuran gambar yang sedang tampil, lensa tetap akurat di layar selebar apa pun. URL gambar untuk background-image ditulis di PHP lewat e(), sehingga tanda kutip di nama file tidak bisa memecah atribut style.
6. Nomor lembar yang ikut berganti
Gambar teknik selalu punya nomor lembar di blok judulnya. Di template ini, setiap section diberi atribut data-sheet, lalu angka di pojok kanan atas header diganti sesuai section terakhir yang melewati 40% tinggi layar:
let cur = sheets[0]?.dataset.sheet;
for (const s of sheets) if (s.getBoundingClientRect().top < innerHeight * 0.4) cur = s.dataset.sheet;
sheetNo.textContent = cur;
Perulangan sederhana ini cukup karena jumlah section sedikit, dan dijalankan di callback scroll yang sama dengan efek exploded view, jadi tidak ada listener tambahan. Hasilnya kecil, tetapi membuat pengunjung merasa sedang membalik berkas gambar kerja sungguhan, bukan sekadar menggulir halaman web.
Ringkasan
- Isometrik =
rotateX(58deg) rotateZ(-45deg)+ lapisantranslateZ, sisi tebal dari pseudo-element yang dilipat. - Exploded view cukup mengubah satu custom property
--gapmengikuti progres scroll. - Crosshair = dua garis
fixedtanpapointer-events, hanya untuk perangkat ber-mouse. - Diagram Gantt = tanggal dikonversi ke persentase tahun, dianimasikan dengan
scaleX. - Kaca pembesar = latar dua kali lipat yang digeser berlawanan arah kursor.
- Nomor lembar =
data-sheetper section, dibaca di callback scroll yang sama.
Download source code lengkapnya
Template Blueprint lengkap dengan CMS (profil, proyek + galeri, 70+ logo teknologi, pengalaman, layanan, testimoni, pesan masuk, dashboard pengunjung), data contoh, dan diagram ilustrasi siap pakai bisa kamu unduh gratis.
Download Source Code Template Portofolio Blueprint + CMS di Papicode
Source code lengkapnya gratis
Lihat semua yang dibahas di artikel ini langsung berjalan.
Tutorial lainnya
Cara Membuat Sistem Tiket Travel dengan Pilih Kursi di Google Apps Script: Layout Armada, Anti Kursi Dobel, dan Kursi Kedaluwarsa
20 Oktober 2026
Cara Membuat Website Donasi Transparan dengan Google Apps Script: Kode Unik Transfer dan Laporan Penyaluran
20 Oktober 2026