──[ VOL.1 :: İdil ]──────────────────────────────────────────────────────────//─
──
:..........................................................................:
[>] Project Link: https://idilart.com/
──[ 0x00 break ]────────────────────────────────────────────────────────────//──
─
After SAGD and SAY, I wanted to take a break.
Not a break from webdev or CS but, Making a project for money.
I wanted to do something fun. Something I could experiment in.
So I decided that instead of doing another organizational level/
production level project, I decided to do a creative portfolio
website for a friend.
──[ 0x01 brief ]────────────────────────────────────────────────────────────//──
─
Even as a portfolio website I wanted it to be unique.
Most portfolio websites today has the same properties.
Same kind of designs and that same corporate synthetic feel.
They are like the theisuses ship.
Same ship different places and presentations.
For me a portfolio website should balance two properties.
Those being; SEO and CV optimized & charachteristically sound.
So, I wanted to build an interactive, playful digital artifact.
Something that felt alive, visual,
and as cute as humanly possible.
──[ 0x02 three systems ]────────────────────────────────────────────────────//──
─
First, I managed to get all the borings parts right.
The stuff that an average portfolio website has.
CV, contacts, case studies all that jazz.
Then I decided to add charachter to the website by creating
three artifacts that reflected the charachter of the whole site
To pull this off without
making the site a laggy, unoptimized nightmare,
I had to build three distinct custom systems under the hood:
1. An autonomous butterfly "living" inside the website,
driven by the Drunkard's Walk stochastic pathfinding algorithm.
2. A magnifying glass lens using real time spatial canvas math
so users could inspect portfolio examples in a cool detectivy way.
3. A sketchbook canvas system powered by vector rendering
and absolute spatial coordinates stored in Sanity.io
(It sound more complicated then it actually is).
This case study tells the story of how those systems were built.
This case study is more SCIENCE related more than business related.
──[ 0x03 butterfly ]────────────────────────────────────────────────────────//──
─
System 1: The Autonomous Butterfly
(Drunkards Walk Algorithm)
I wanted a butterfly LIVING inside the viewport
that felt organic rather than synthetic.
A predictable CSS path animation would be a easy solution,
but it would look very mechanical and lame.
so I implemented a 2D Drunkard's Walk (Random Walk)
algorithm bound to the browser windows inner bounds
("window.innerWidth" x "window.innerHeight").
.------------------------------------------------.
| [ Current Pos (x, y) ] |
| | |
| v |
| (Generate Random Theta & Velocity Step) |
| | |
| v |
| [ Target Pos (x+dx, y+dy) ] |
| | |
| v |
| (Boundary Check: Clamp inside Viewport) |
| | |
| v |
| [ Smooth Interpolation (LERP) + Perlin Noise ]
| | |
| v |
| [ Render Frame to Canvas ] |
'------------------------------------------------'
At every frame tick inside a "requestAnimationFrame" loop,
the butterfly calculates its next target coordinates
(x_{t+1}, y_{t+1}) using random directional vectors:
x_{t+1} = x_t + cos(theta) cdot v
y_{t+1} = y_t + sin(theta) cdot v
where theta is a randomly mutating angle and v is velocity.
To avoid abrupt unnatural jitter,
I applied Linear Interpolation (LERP)
between current positional states and target coordinates,
combined with a slight Perlin noise offset
to simulate continuous wing turbulence.
When the butterfly approaches viewport edges,
the algorithm flips the direction vectors sign,
keeping the butterfly contained inside the active window.
The butterfly toggled between three states:
"FLUTTERING" (active random walk),
"HOVERING" (zero velocity with micro-vibrations),
and "LANDED"
(attaching to active DOM element bounding rects via
"getBoundingClientRect()").
TLDR (for people that dont like math):
.------------------------------------------------.
| We know the exact width and height of the users screen.
| |
| v
| We know where we are currently.
| |
| v
| We decide a random direction and velocity.
| |
| v
| We move as such.
| |
| v
| Ofcourse we check if we are still in the users screen.
| |
| v
| A "noise" could actually be considered as random numbers.
| So our butterfly will flutter randomly like a real one.
| |
| v
| Then we draw the butterfly.
'------------------------------------------------'
(btw Perlin noise is a little different.
It is smooth noise meaning that random numbers
dont have a huge difference between them
so it is not sharp moments but smooth organic ones.)
just like a flipbook or a video,
smooth motion is just a sequence of still images
displayed rapidly. On every browser frame tick,
we calculate the next position,
draw the new state to the canvas,
and repeat 60 times a second.
The previous Algorithm
shows how we create states
in this equation.
──[ 0x04 lens ]─────────────────────────────────────────────────────────────//──
─
To view portfolio showcases,
the user can control a custom circular magnifying glass lens.
Instead of using heavy CSS zoom transforms
(which trigger continuous DOM reflows and repaint cycles),
I engineered a dualcanvas spatial sync system.
How the Spatial Projection Worked:
1. Background Layer: A main "Canvas2D" element rendered
the standard resolution portfolio artwork.
2. Offscreen Buffer: A secondary hidden "<canvas>" held
the target assets rendered at 3x spatial resolution
("SCALE_FACTOR = 3").
3. Cursor Tracking: On "pointermove" events,
I captured the normalized cursor position (cx, cy)
relative to the viewport.
4. Sub region Clipping ("drawImage" API)
The lens element displayed a circular
HTML5 Canvas overlay.
Every frame it sliced a subregion from the
high resolution offscreen buffer
centered at (cx, cy) and projected it
inside the lens coordinates
lensCtx.drawImage(
offscreenCanvas,
cx * SCALE_FACTOR - LENS_RADIUS, // source X
cy * SCALE_FACTOR - LENS_RADIUS, // source Y
LENS_DIAMETER, // source width
LENS_DIAMETER, // source height
0, 0, // destination canvas (0,0)
LENS_DIAMETER, LENS_DIAMETER // destination dimensions
);
By constraining high resolution rendering strictly to
the circular boundary of the lens canvas,
GPU memory consumption remained minimal,
achieving a consistent 60 FPS on mobile and low-power devices.
TLDR (for people that hate math)
Think of it like this,
holding a magnifying glass over a physical document
instead of printing the entire page on a massive sheet of paper
just to see the details, you keep a single high resolution printout
hidden in a drawer and use a tiny circular cutout (your lens)
to peek at only the exact spot your cursor is hovering over.
By slicing and drawing just that tiny circle from the hidden sheet
60 times a second, the computer barely does any heavy lifting,
keeping performance buttery smooth on any device.
──[ 0x05 sketchbook ]───────────────────────────────────────────────────────//──
─
The final key feature was an interactive sketchbook system
where handwritten notes, doodles, and spatial diagrams were placed organically
across the page layout like a real physical journal.
Now how this idea came to my mind is an interesting story.
I was browsing the interwebs trying to see what other people built.
Expecially artistic portfolio websites.
Most artistic websites were vastly different from those more technical.
They didnt looked like template made websites but more like
single file "index.html" og websites from 2000s.
I really enjoyed the authenticity.
It was clear they wanted something else.
They didnt wanted the website to just show their skillsets.
They wanted their websites to reflect who they are in deep.
One of the websites I analyzed put an idea in my head.
I really liked the poems of Savannah Brown.
So I looked at her website and found
https://www.savbrown.com//garden
It wasnt routed through any links on the website
I found it through sitemap.xml
but it was public nonetheless.
I inspected the website and fount out that it was built with wix.
I thought to myself. Wix was a website builder yes
It made things kinda "easier" but made suboptimal websites.
These artists needed good websites.
GOOD Websites that they can be authentic in.
But due to them being not that technical (nothing bad with that)
They had to make a tradeoff between a GOOD website and authenticity.
I respected those that chose authenticity.
But I can also see that due to technical limitations
they couldnt even be as authentic as they wanted to be.
My instintcts told me so I have no proof of that.
So I wanted to make a system
where it can be built in a GOOD website
That allowed modular authenticity.
And the other charachteristic choicec could be made like
The author telling the developer what they want
and they do it.
But true authenticity needed hands on work.
So I made this one.
──[ 0x06 schema ]───────────────────────────────────────────────────────────//──
─
Vector Coordinate Schema in Sanity:
Instead of storing static images or fixed HTML blocks,
I modeled the sketchbook data in Sanity as discrete vector coordinate objects.
Each sketchbook element was defined by a custom GROQ schema:
{
"_type": "sketchElement",
"elementType": "vectorPath",
"viewBox": "0 0 500 500",
"svgData": "M10 80 Q 52 10, 95 80 T 180 80",
"positioning": {
"xPercent": 42.5,
"yPercent": 18.2,
"rotationDeg": -6.5,
"zIndex": 3
}
}
Absolute pixel positioning (top: 200px) breaks across variable screen sizes.
To maintain proportions across mobile and desktop viewports,
positioning coordinates were stored as viewport percentages (xPercent, yPercent)
.
On client hydration, a custom Vue component rendered
raw inline SVG strings dynamically inside absolute container wrappers,
using transform: translate3d(x, y, 0) rotate(deg) for
hardware accelerated GPU rendering.
The result was a light, scale invariant, responsive sketchbook layout
where vector paths scale infinitely without quality loss or layout thrashing.
TLDR (for those artists interested and those who dont enjoy math)
If you know how to draw you would understand this even better.
Its like taking reference from an apple
and drawing it on the canvas (PUN INTENDED!!!)
You take the relationship between objects and their scales and make a
sound painting that reflects the real world observation.
In result a painting of eifell tower doesnt need to be the size of eifell tower.
And still can be considered quite accurate.
BTW I enjoy surrealist paintings more than these ones :)
So you create the real object in CMS.
And each clients browser draws them the picture of it by taking precise referenc
es.
──[ 0x07 notes ]────────────────────────────────────────────────────────────//──
─
Building the random walk and magnifying projection from raw spatial math
(requestAnimationFrame, Canvas2D API, LERP)
was vastly more performant and lightweight
than dragging in 3D engines like Three.js
for simple 2D interactive mechanics.
(I actually made a artifact with three.js
of a entirely 3d portfolio website for myself
It was a cube with my info on each side.
It had poor performance on mobile and tbh
quite boring so I cancelled it.
But we can say that I know three.js pretty well.)
GPU Accelerated Transforms:
Moving entities across screen spaces via translate3d()
forces the browser to delegate rendering to GPU layers,
avoiding main thread layout recalculations.
CMS as a Spatial Database:
Sanity doesn't just have to store plain blog text;
treating a headless CMS as a relational store
for relative SVG coordinates
proved that structured data models can power creative,
non standard visual layouts cleanly.
It was artistic, it was cute, and it was a welcome break
from corporate web builds and under the hood, the math was clean.
I TRULY WISH I DIDNT HAD TO EARN MONEY AND COULD JUST DO COOL STUFF LIKE THIS :(
:..........................................................................:
──[ EOF :: vol.1 / İdil ]────────────────────────────────────────────────────//─
──