refactor layout; streamline class attributes for improved readability and maintainability
This commit is contained in:
47
index.pug
47
index.pug
@@ -12,7 +12,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
include src/components/Academia
|
||||
include src/components/Footer
|
||||
|
||||
script(src = "https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js")
|
||||
script(src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js")
|
||||
|
||||
script.
|
||||
const footerEl = document.querySelector("#footer");
|
||||
@@ -93,8 +93,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
|
||||
// Guilloche Curtain
|
||||
class GuillocheCurtain {
|
||||
constructor(canvas, options = {})
|
||||
{
|
||||
constructor(canvas, options = {}) {
|
||||
this.canvas = canvas;
|
||||
this.containerHeight = window.innerHeight;
|
||||
this.containerWidth = window.innerWidth;
|
||||
@@ -171,16 +170,14 @@ html.scroll-smooth(lang=head.lang)
|
||||
this.animate();
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
init() {
|
||||
this.renderer.setSize(this.containerWidth, this.containerHeight);
|
||||
this.renderer.setClearColor(0x000000, 0);
|
||||
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||
this.camera.position.z = 1;
|
||||
}
|
||||
|
||||
setupInteraction()
|
||||
{
|
||||
setupInteraction() {
|
||||
const updateMousePosition = (clientX, clientY) => {
|
||||
const rect = this.canvas.getBoundingClientRect();
|
||||
const x = clientX - rect.left;
|
||||
@@ -212,8 +209,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
});
|
||||
}
|
||||
|
||||
updateDynamicParameters()
|
||||
{
|
||||
updateDynamicParameters() {
|
||||
const {normalizedX, normalizedY} = this.mouse;
|
||||
const {parameterLerp} = this.smoothing;
|
||||
|
||||
@@ -240,8 +236,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
this.dynamic.lightness.max = this.dynamic.lightness.max * (1 - parameterLerp) + targetLightMax * parameterLerp;
|
||||
}
|
||||
|
||||
createNodes()
|
||||
{
|
||||
createNodes() {
|
||||
for (let i = 0; i < this.options.nodeCount; i++) {
|
||||
this.nodes.push({
|
||||
x: (Math.random() - 0.5) * 3,
|
||||
@@ -253,8 +248,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
}
|
||||
}
|
||||
|
||||
getOffsetTransition(t)
|
||||
{
|
||||
getOffsetTransition(t) {
|
||||
const {startOffset, endOffset, offsetTransition} = this.options;
|
||||
|
||||
switch (offsetTransition) {
|
||||
@@ -270,8 +264,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
}
|
||||
}
|
||||
|
||||
createSplines()
|
||||
{
|
||||
createSplines() {
|
||||
for (let groupIndex = 0; groupIndex < this.options.groupCount; groupIndex++) {
|
||||
const group = new THREE.Group();
|
||||
const splines = [];
|
||||
@@ -296,8 +289,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
}
|
||||
}
|
||||
|
||||
createSingleSpline(offset, groupIndex, splineIndex)
|
||||
{
|
||||
createSingleSpline(offset, groupIndex, splineIndex) {
|
||||
const points = this.generateSplinePoints(offset, groupIndex, splineIndex, 0);
|
||||
const geometry = new THREE.BufferGeometry().setFromPoints(points);
|
||||
|
||||
@@ -321,8 +313,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
return new THREE.Line(geometry, material);
|
||||
}
|
||||
|
||||
generateSplinePoints(offset, groupIndex, splineIndex, timeOffset = 0)
|
||||
{
|
||||
generateSplinePoints(offset, groupIndex, splineIndex, timeOffset = 0) {
|
||||
const points = [];
|
||||
const {segments} = this.options;
|
||||
|
||||
@@ -362,8 +353,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
return points;
|
||||
}
|
||||
|
||||
updateSplineGeometry(splineData, groupIndex, splineIndex)
|
||||
{
|
||||
updateSplineGeometry(splineData, groupIndex, splineIndex) {
|
||||
const {line, offset} = splineData;
|
||||
const points = this.generateSplinePoints(offset, groupIndex, splineIndex);
|
||||
line.geometry.setFromPoints(points);
|
||||
@@ -381,8 +371,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
line.material.color.setHSL(hue, saturation, lightness);
|
||||
}
|
||||
|
||||
animate()
|
||||
{
|
||||
animate() {
|
||||
// Update dynamic parameters based on mouse interaction
|
||||
this.updateDynamicParameters();
|
||||
|
||||
@@ -415,14 +404,12 @@ html.scroll-smooth(lang=head.lang)
|
||||
requestAnimationFrame(() => this.animate());
|
||||
}
|
||||
|
||||
updateOptions(newOptions)
|
||||
{
|
||||
updateOptions(newOptions) {
|
||||
Object.assign(this.options, newOptions);
|
||||
this.rebuild();
|
||||
}
|
||||
|
||||
rebuild()
|
||||
{
|
||||
rebuild() {
|
||||
this.splineGroups.forEach(({group}) => {
|
||||
group.children.forEach((child) => {
|
||||
child.geometry.dispose();
|
||||
@@ -435,8 +422,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
this.createSplines();
|
||||
}
|
||||
|
||||
resize()
|
||||
{
|
||||
resize() {
|
||||
console.log("Resizing canvas and updating camera");
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
@@ -451,8 +437,7 @@ html.scroll-smooth(lang=head.lang)
|
||||
this.camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
destroy()
|
||||
{
|
||||
destroy() {
|
||||
this.splineGroups.forEach(({group}) => {
|
||||
group.children.forEach((child) => {
|
||||
child.geometry.dispose();
|
||||
|
||||
@@ -3,7 +3,9 @@ include Title
|
||||
include Container
|
||||
|
||||
section#academia
|
||||
.grid.grid-cols-1.p-8.bg-deepwhite.text-nls-black(class="xl:grid-cols-2 xl:gap-36 xl:grid-cols-2 dark:bg-deepblack dark:text-white xl:p-20 sm:py-32 xl:py-48 min-h-[120vh] border-t border-nls-black/50 dark:border-nls-white/50")
|
||||
.grid.grid-cols-1.p-8.bg-deepwhite.text-nls-black.border-t(
|
||||
class="xl:grid-cols-2 xl:gap-36 xl:grid-cols-2 dark:bg-deepblack dark:text-white xl:p-20 sm:py-32 xl:py-48 min-h-[120vh] border-nls-black/50 dark:border-nls-white/50"
|
||||
)
|
||||
+Container
|
||||
// region Skills
|
||||
+Title("h2") !{academia.expertise.title}
|
||||
|
||||
@@ -71,14 +71,14 @@ mixin Carousel(items, options)
|
||||
script.
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setInterval(
|
||||
() => {
|
||||
const track = document.querySelector(`##{id} .carousel-track`);
|
||||
if (track.scrollLeft + track.clientWidth >= track.scrollWidth) {
|
||||
track.scrollTo({left: 0, behavior: "smooth"});
|
||||
} else {
|
||||
carouselNext("#{id}");
|
||||
}
|
||||
},
|
||||
#{autoScroll},
|
||||
() => {
|
||||
const track = document.querySelector(`##{id} .carousel-track`);
|
||||
if (track.scrollLeft + track.clientWidth >= track.scrollWidth) {
|
||||
track.scrollTo({left: 0, behavior: "smooth"});
|
||||
} else {
|
||||
carouselNext("#{id}");
|
||||
}
|
||||
},
|
||||
#{autoScroll},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,17 +20,17 @@ mixin Svg
|
||||
svg.w-24.h-24(class="sm:w-8 sm:h-8", aria-hidden="true", fill="currentColor", viewbox="0 0 24 24")
|
||||
block
|
||||
|
||||
footer#footer.pt-24.relative.overflow-hidden(class="w-min-h-screen")
|
||||
footer#footer.pt-24.relative.overflow-hidden.w-min-h-screen
|
||||
// - Background canvas for Guilloche effect
|
||||
canvas#footer-canvas.absolute.left-0.right-0.bottom-0.top-0.mx-auto.transition.w-full(class="-z-20 h-[100vh]")
|
||||
canvas#footer-canvas.absolute.left-0.right-0.bottom-0.top-0.mx-auto.transition.w-full.-z-20(class="h-[100vh]")
|
||||
//- Background gradient
|
||||
.divider.absolute.left-0.right-0.top-0.h-full(class="-z-10 bg-gradient-to-t from-deepwhite/0 to-deepwhite dark:from-deepblack/0 dark:to-deepblack")
|
||||
.divider.absolute.left-0.right-0.top-0.h-full.-z-10.bg-gradient-to-t.to-deepwhite(class="from-deepwhite/0 dark:from-deepblack/0 dark:to-deepblack")
|
||||
//- Footer content
|
||||
.p-8.py-20.text-nls-black.z-20(class="sm:py-36 dark:text-white sm:p-20")
|
||||
+Container
|
||||
// region Contact
|
||||
h2.text-4xl.mb-4 #{footer.title}
|
||||
p.mb-8.max-w-prose(class="text-xl text-deepblack dark:text-deepwhite")
|
||||
p.mb-8.max-w-prose.text-xl.text-deepblack(class="dark:text-deepwhite")
|
||||
| !{landingpage.name}<br/>
|
||||
span.opacity-60 !{landingpage.jobTitle[0]}
|
||||
p.mb-8.max-w-prose #{footer.content}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
header.bg-nls-white.text-nls-black.relative.overflow-hidden(class="dark:text-white dark:bg-nls-black border-b border-nls-black/50 dark:border-nls-white/50")
|
||||
header.bg-nls-white.text-nls-black.relative.overflow-hidden.border-b(class="dark:text-white dark:bg-nls-black border-nls-black/50 dark:border-nls-white/50")
|
||||
.teaser.p-8.flex.flex-col.items-center.justify-center(class="sm:p-20")
|
||||
.max-w-3xl.mb-8.relative(class="w-4/5 min-h-[90vh]")
|
||||
.peer.absolute.bottom-0.left-0.right-0.z-40.text-center.max-w-3xl.center.py-8.pointer-events-none
|
||||
|
||||
@@ -2,7 +2,7 @@ include Carousel
|
||||
include Container
|
||||
include Title
|
||||
|
||||
section#portfolio(class="border-t border-nls-black/50 dark:border-nls-white/50")
|
||||
section#portfolio.border-t(class="border-nls-black/50 dark:border-nls-white/50")
|
||||
.p-8.bg-nls-white.text-nls-black(class="dark:bg-nls-black dark:text-white sm:py-32")
|
||||
+Container
|
||||
+Title("h2", true)
|
||||
|
||||
Reference in New Issue
Block a user