Kevin Chen

Shanghai | Boston | New York

“Be yourself so that the people looking for you can find you.”

(function () { const words = [ "Learning how to learn.", "Building.", "Wandering.", "Taking the scenic route.", "Reading.", "Sketching.", "Exploring.", "Somewhere in New York.", "Figuring It Out." ]; const text = document.getElementById("typingText"); let wordIndex = 0; let charIndex = 0; let deleting = false; function type() { const word = words[wordIndex]; if (!deleting) { text.textContent = word.substring(0, charIndex + 1); charIndex++; if (charIndex === word.length) { deleting = true; setTimeout(type, 900); return; } setTimeout(type, 55); } else { text.textContent = word.substring(0, charIndex - 1); charIndex--; if (charIndex === 0) { deleting = false; wordIndex = (wordIndex + 1) % words.length; setTimeout(type, 400); return; } setTimeout(type, 30); } } type(); })();
YEAR0.00%
JAN 01DEC 31
(function () { function updateYearProgress() { var now = new Date(); /* Get current Eastern Time */ var eastern = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", hour12: false }).formatToParts(now); var parts = {}; eastern.forEach(function (item) { if (item.type !== "literal") { parts[item.type] = Number(item.value); } }); var year = parts.year; var month = parts.month; var day = parts.day; var hour = parts.hour; var minute = parts.minute; var second = parts.second; /* Treat the year as a simple calendar timeline */ var start = Date.UTC(year, 0, 1, 0, 0, 0); var end = Date.UTC(year + 1, 0, 1, 0, 0, 0); var current = Date.UTC( year, month - 1, day, hour, minute, second ); var percentage = ((current - start) / (end - start)) * 100; /* Keep value between 0 and 100 */ percentage = Math.max(0, Math.min(100, percentage)); /* Date */ var dateText = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York", month: "long", day: "2-digit", year: "numeric" }).format(now); /* Time */ var timeText = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York", hour: "numeric", minute: "2-digit", second: "2-digit", hour12: true, timeZoneName: "short" }).format(now); document.getElementById("yp-date").textContent = dateText.toUpperCase(); document.getElementById("yp-time").textContent = timeText; document.getElementById("yp-percent").textContent = percentage.toFixed(2) + "%"; document.getElementById("yp-bar").style.width = percentage + "%"; document.getElementById("yp-year").textContent = year; } updateYearProgress(); setInterval(updateYearProgress, 1000); })();
Loading...
Loading...
Loading...
(function () { /* ========================================================= ELEMENTS ========================================================= */ const canvas = document.getElementById("moon-canvas-final"); const ctx = canvas.getContext("2d"); const phaseLabel = document.getElementById("moon-phase-final"); const percentLabel = document.getElementById("moon-percent-final"); const dateLabel = document.getElementById("moon-date-final"); const previousButton = document.getElementById("moon-prev-final"); const todayButton = document.getElementById("moon-today-final"); const nextButton = document.getElementById("moon-next-final"); if (!canvas || !ctx) return; /* ========================================================= SETTINGS ========================================================= */ const SIZE = 32; const CENTER = 15.5; const RADIUS = 14; /* The date currently being displayed. */ let viewedDate = new Date(); let dragging = false; let dragStartX = 0; let dragStartTime = 0; /* ========================================================= MATH HELPERS ========================================================= */ function rad(degrees) { return degrees * Math.PI / 180; } function normalize(degrees) { degrees %= 360; if (degrees < 0) degrees += 360; return degrees; } /* ========================================================= JULIAN DATE ========================================================= */ function getJulianDate(date) { return date.getTime() / 86400000 + 2440587.5; } /* ========================================================= SUN ECLIPTIC LONGITUDE ========================================================= */ function getSunLongitude(jd) { const T = (jd - 2451545.0) / 36525; const T2 = T * T; const L0 = 280.46646 + 36000.76983 * T + 0.0003032 * T2; const M = 357.52911 + 35999.05029 * T - 0.0001537 * T2; const Mr = rad(M); const C = (1.914602 - 0.004817 * T - 0.000014 * T2) * Math.sin(Mr) + (0.019993 - 0.000101 * T) * Math.sin(2 * Mr) + 0.000289 * Math.sin(3 * Mr); return normalize(L0 + C); } /* ========================================================= MOON ECLIPTIC LONGITUDE ========================================================= */ function getMoonLongitude(jd) { const T = (jd - 2451545.0) / 36525; const T2 = T * T; const T3 = T2 * T; const T4 = T3 * T; const Lp = 218.3164477 + 481267.88123421 * T - 0.0015786 * T2 + T3 / 538841 - T4 / 65194000; const D = 297.8501921 + 445267.1114034 * T - 0.0018819 * T2 + T3 / 545868 - T4 / 113065000; const M = 357.5291092 + 35999.0502909 * T - 0.0001536 * T2 + T3 / 24490000; const Mp = 134.9633964 + 477198.8675055 * T + 0.0087414 * T2 + T3 / 69699 - T4 / 14712000; const F = 93.2720950 + 483202.0175233 * T - 0.0036539 * T2 - T3 / 3526000 + T4 / 863310000; const Dr = rad(D); const Mr = rad(M); const Mpr = rad(Mp); const Fr = rad(F); let longitude = Lp; longitude += 6.289 * Math.sin(Mpr); longitude += 1.274 * Math.sin(2 * Dr - Mpr); longitude += 0.658 * Math.sin(2 * Dr); longitude += 0.214 * Math.sin(2 * Mpr); longitude -= 0.186 * Math.sin(Mr); longitude -= 0.059 * Math.sin(2 * Dr - 2 * Mpr); longitude -= 0.057 * Math.sin(2 * Dr - Mr - Mpr); longitude += 0.053 * Math.sin(2 * Dr + Mpr); longitude += 0.046 * Math.sin(2 * Dr - Mr); longitude += 0.041 * Math.sin(Mr - Mpr); longitude -= 0.035 * Math.sin(Dr); longitude -= 0.031 * Math.sin(Mr + Mpr); longitude -= 0.015 * Math.sin(2 * Fr - 2 * Dr); longitude += 0.011 * Math.sin(2 * Dr - Mr - 2 * Mpr); return normalize(longitude); } /* ========================================================= LUNAR DATA ========================================================= */ function getLunarData(date) { /* Use the actual selected time. This is important for Today. */ const jd = getJulianDate(date); const sun = getSunLongitude(jd); const moon = getMoonLongitude(jd); /* Angular separation. 0° = New Moon 90° = First Quarter 180° = Full Moon 270° = Last Quarter */ const elongation = normalize(moon - sun); /* Illuminated fraction. */ const fraction = (1 - Math.cos(rad(elongation))) / 2; return { elongation: elongation, percentage: Math.round(fraction * 100) }; } /* ========================================================= PHASE NAME ========================================================= */ function getPhaseName(angle) { if (angle < 22.5 || angle >= 337.5) { return "New Moon"; } if (angle < 90) { return "Waxing Crescent"; } if (angle < 112.5) { return "First Quarter"; } if (angle < 157.5) { return "Waxing Gibbous"; } if (angle < 202.5) { return "Full Moon"; } if (angle < 270) { return "Waning Gibbous"; } if (angle < 292.5) { return "Last Quarter"; } return "Waning Crescent"; } /* ========================================================= DATE ========================================================= */ function formatDate(date) { return date.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); } /* ========================================================= DRAW MOON ========================================================= */ function drawMoon() { const data = getLunarData(viewedDate); const angle = rad(data.elongation); ctx.clearRect(0, 0, SIZE, SIZE); /* ------------------------------------------------------- STARS ------------------------------------------------------- */ const stars = [ [3, 4], [7, 9], [27, 5], [24, 11], [4, 25], [28, 23], [10, 29], [22, 28] ]; ctx.fillStyle = "rgba(232,223,204,0.30)"; stars.forEach(function (star) { ctx.fillRect(star[0], star[1], 1, 1); }); /* ------------------------------------------------------- SUNLIGHT DIRECTION ------------------------------------------------------- */ const lightX = Math.sin(angle); const lightZ = -Math.cos(angle); /* ------------------------------------------------------- MOON PIXELS ------------------------------------------------------- */ for (let y = 0; y < SIZE; y++) { for (let x = 0; x < SIZE; x++) { const dx = x - CENTER; const dy = y - CENTER; const distance = Math.sqrt(dx * dx + dy * dy); if (distance > RADIUS) { continue; } const nx = dx / RADIUS; const ny = dy / RADIUS; const nz = Math.sqrt( Math.max( 0, 1 - nx * nx - ny * ny ) ); const illumination = nx * lightX + nz * lightZ; if (illumination > 0) { let brightness = 205 + illumination * 45; /* Subtle pixel texture. */ brightness += ((x * 17 + y * 31) % 9) - 4; brightness = Math.max( 0, Math.min( 255, brightness ) ); const r = Math.round(brightness); const g = Math.round(brightness * 0.97); const b = Math.round(brightness * 0.90); ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; ctx.fillRect(x, y, 1, 1); } else { /* Very faint dark side. */ ctx.fillStyle = "rgba(232,223,204,0.045)"; ctx.fillRect(x, y, 1, 1); } } } /* ------------------------------------------------------- CRATERS ------------------------------------------------------- */ const craters = [ [11, 10], [19, 10], [16, 14], [10, 18], [21, 18], [14, 21], [18, 23] ]; craters.forEach(function (crater) { const x = crater[0]; const y = crater[1]; const dx = x - CENTER; const dy = y - CENTER; if ( Math.sqrt(dx * dx + dy * dy) <= RADIUS ) { ctx.fillStyle = "rgba(80,75,68,0.22)"; ctx.fillRect(x, y, 1, 1); } }); /* ------------------------------------------------------- TEXT ------------------------------------------------------- */ phaseLabel.textContent = getPhaseName(data.elongation); percentLabel.textContent = data.percentage + "% illuminated"; dateLabel.textContent = formatDate(viewedDate); } /* ========================================================= CHANGE DATE ========================================================= */ function changeDay(amount) { const nextDate = new Date(viewedDate); nextDate.setDate( nextDate.getDate() + amount ); /* Keep manually selected dates at noon. */ nextDate.setHours(12, 0, 0, 0); viewedDate = nextDate; drawMoon(); } /* ========================================================= BUTTONS ========================================================= */ previousButton.addEventListener( "click", function () { changeDay(-1); } ); nextButton.addEventListener( "click", function () { changeDay(1); } ); todayButton.addEventListener( "click", function () { viewedDate = new Date(); drawMoon(); } ); /* ========================================================= KEYBOARD ========================================================= */ document.addEventListener( "keydown", function (event) { const tag = document.activeElement && document.activeElement.tagName; if ( tag === "INPUT" || tag === "TEXTAREA" ) { return; } if (event.key === "ArrowLeft") { changeDay(-1); } if (event.key === "ArrowRight") { changeDay(1); } } ); /* ========================================================= DRAG / TOUCH ========================================================= */ canvas.addEventListener( "pointerdown", function (event) { dragging = true; dragStartX = event.clientX; dragStartTime = viewedDate.getTime(); canvas.setPointerCapture( event.pointerId ); } ); canvas.addEventListener( "pointermove", function (event) { if (!dragging) { return; } const distance = event.clientX - dragStartX; /* 18px of dragging = 1 day. */ const days = Math.round(distance / 18); viewedDate = new Date( dragStartTime - days * 86400000 ); drawMoon(); } ); canvas.addEventListener( "pointerup", function () { dragging = false; } ); canvas.addEventListener( "pointercancel", function () { dragging = false; } ); /* ========================================================= INITIAL RENDER ========================================================= */ drawMoon(); /* ========================================================= UPDATE WHEN VIEWING TODAY ========================================================= */ setInterval( function () { const now = new Date(); const viewingToday = viewedDate.getFullYear() === now.getFullYear() && viewedDate.getMonth() === now.getMonth() && viewedDate.getDate() === now.getDate(); if (viewingToday) { viewedDate = now; drawMoon(); } }, 60000 ); })();

About Me

Hi.Welcome. I hope you are happy.I am currently 20.Ever since I washed up in New York after high school, I've been wondering if I am coming or going; if I am ever going to be who I think I am.My only fear is being 80 years old and thinking to myself:
"I got here too early. I didn't take the scenic route for some stupid reason. I had my whole life in front of me, and I no longer do. I'm here now, and there's nothing I can do."
I don’t want that for myself. I want to see how far I can take my one life. I never want to think:
I should have climbed that mountain.
I should have loved that person.
I should have chased that dream.
I should have cherished that moment.
I have spent precious years of my life on the sidelines, analyzing life more than I ever lived it. I don't want time to keep passing, day by day, while I'm accompanied by the guilt of knowing I spent my only life on disguising fear as practicality.
I won’t let time take away what should have been. I won’t give it the satisfaction.
One life. It’s worth an attempt.

Just For Fun


Photos


Sketches

Currently...

Videos

What if I Call?

What If I Call?

A video I made for Alex Crichton for his song. Inspired by NYC and the melancholy of the holidays. Cool guy. 9 Million listeners on Spotify.

Coffee

La Colombe Coffee

A video I made for La Colombe Coffee. Inspired by the feeling of getting ready and having that first sip of coffee.


Building ASPERA

The Company

My roommate and I wanted wanted to build something to help the people that are in our shoes just a couple years ago. Those who are struggling to find their balance and routine as they transition into adulthood.

The Mission

Aspera is for the people who feel overwhlemd. We hope that the people who come across our app can use it to help them find their rhythm in the noise. So that they can organize their life to direct their actions towards their ambitions.

The App

Aspera helps you choose specific, quantifiable goals that you want to pursue to become the person you wish to be. It helps you master the small actions that contribute to your greatest ambitions and tracks your progress along the way.


In The Past…

A Clothing Company. BEDIATI.

The Company

I sought out to make a brand that connects people with streetsy and contemporary clothing. Got some good sales, and ended up moving onto other things, like the website you're on:)

The Mission

This is a picture of one of the customers, Jose. He bought shirts and a laptop case, partially to match one of his new tattoos. I love how people around the world are captivated by the same things, whether that's a mythology or a style.

The Designs

One of the best selling designs. It depicts a stylized Icarus as he flies high into the sky. Another popular collection is "Above The Law", which features vintage-style western designs.


Freelance Work

Quotes I Like

  • “There are years that ask questions and years that answer.”
    - Zora Neale Hurston

  • “It takes a long time to become young.”
    - Pablo Picasso

  • “'You're not the same as you were before,' he said. 'You were much more... muchier... you've lost your muchness.'”
    - Lewis Carroll

  • “If you're lonely when you're alone, you're in bad company.”
    - Jean-Paul Sartre

  • "Better to be worn from wear than worn from rust."
    - Unknown

  • "It ain't what they call you, it's what you answer to."
    - W.C. Fields

  • "Be yourself so people looking for you can find you."
    - Arlan Hamilton

  • "The proper function of man is to live, not to exist. I shall not waste my days in trying to prolong them. I shall use my time."
    - Jack London

  • “Let's think the unthinkable, let's do the undoable. Let us prepare to grapple with the ineffable itself, and see if we may not eff it after all.”
    - Douglas adams

  • “My kids are starting to notice I'm a little different from the other dads. "Why don't you have a straight job like everyone else?" they asked me the other day.
    I told them this story:
    In the forest, there was a crooked tree and a straight tree. Every day, the straight tree would say to the crooked tree, "Look at me...I'm tall, and I'm straight, and I'm handsome. Look at you...you're all crooked and bent over. No one wants to look at you." And they grew up in that forest together. And then one day the loggers came, and they saw the crooked tree and the straight tree, and they said, "Just cut the straight trees and leave the rest." So the loggers turned all the straight trees into lumber and toothpicks and paper. And the crooked tree is still there, growing stronger and stranger every day.”
    - Tom Waits

My Favorites


Books


Movies


Songs


Videos


Games


Poems

What's up?

leave a note
anonymous
no name. no email. just a note.
0/1000
received. thank you for leaving it here.
something went wrong. please try again.
(function () { const form = document.getElementById("anonymous-note-form"); const textarea = document.getElementById("anonymous-note"); const count = document.getElementById("notes-count"); const submit = document.getElementById("anonymous-note-submit"); const success = document.getElementById("notes-success"); const error = document.getElementById("notes-error"); /* CHARACTER COUNTER */ textarea.addEventListener("input", function () { count.textContent = textarea.value.length; }); /* SUBMIT */ form.addEventListener("submit", async function (event) { event.preventDefault(); success.classList.remove("show"); error.classList.remove("show"); submit.classList.add("loading"); submit.disabled = true; const formData = new FormData(form); try { const response = await fetch(form.action, { method: "POST", body: formData, headers: { "Accept": "application/json" } }); if (response.ok) { form.style.transition = "opacity 0.35s ease, transform 0.35s ease"; form.style.opacity = "0"; form.style.transform = "translateY(-4px)"; setTimeout(function () { form.style.display = "none"; success.classList.add("show"); }, 350); } else { throw new Error("Submission failed."); } } catch (err) { submit.classList.remove("loading"); submit.disabled = false; error.classList.add("show"); } }); })();

Cozy Corner

If you're tired, or nothing on here is particularly interesting to you, just take a break here:)