Case Study: Anatole Touvron’s Portfolio
Like many developers, I’ve decided to redo my portfolio in the summer of 2021. I wanted to do everything from scratch, including the design and development, because I liked the idea of:
- doing the whole project on my own
- working on something different than coding
- being 100% responsible for the website
- being free to do whatever I want
I know that I wanted to do something simple but efficient. I’ve tried many times to do another portfolio but I’ve always felt stuck at some point and wanted to wipe everything clean by remaking the design or the entire development. I talked to many developers about this and I think that we all know this feeling of getting tired of a project because of how long it is taking to finish. For the first time, I’ve managed to never get this feeling simply by designing this entire project in one afternoon and developing it in two weeks.
Without going further, I want to point out that prior to that I’ve studied @lhbizarro’s course on how to create an immersive website from scratch and I would not have been able to create my portfolio this fast without. It is a true wealth of knowledge that I now use on a regular basis.
Going fast
One of the best tips that I can give to any developer in order to not get tired of doing their portfolio is to go as fast as possible. If you know that you get tired easily with a project, I highly suggest doing it when you have the time and then rush it like crazy. This goes for the coding and for the design part.
Get inspired by websites that you like, find colours that match your vibe, fonts that you like, use your favourite design tool and don’t overthink it.
Things can always get better but if you don’t stick to what you’re doing you will never be able to finish it.
I’m really proud and happy about my portfolio but I know that it isn’t that creative and that crazy compared to stuff that you can see online. I’ve set the bar at a level that I knew I could reach and I think that this is a good way of being sure that you’ll have a new website that will make you progress and feel good about yourself.
Text animations
For the different text animations I’ve chose to do something that I’ve been doing a long time, which is animating lines for paragraphs and letters or words for titles with the help of the Intersection Observer API.
Using it is the most efficient and optimal way to do such animations as it only triggers once in your browser and allows you to have many spans translating without making your user’s machine launch like a rocket.
You have to know that, the more elements there are to animate, the harder it will be to have a smooth experience on every device, which is why I used the least amount of spans to do my animations.
To split my text I always use GSAP’s SplitText because it spoon-feeds you the least fun part of the work. It’s really easy to use and never disappoints.
How to animate
There is multiple ways of animating your divs or spans and I’ve decided to show you two ways of doing it:
- fully with JavaScript
- CSS and JavaScript-based
Controlling an animation entirely with JavaScript allows you to have code that’s easier to read and understand because everything will be in the same file. But it could a bit less optimal because you’ll be using JavaScript animation libraries.
Open the following example to see the code:
With CSS your code can get a bit out of hand if you are not organised. There’s a lot more classes to take care of. It’s up to you what you prefer to use but I feel like it’s important to talk about both options because each can have their advantages and disadvantages depending on your needs.
The next example shows how to do it with CSS + JS (open the Codesandbox):
Infinite slider
I’d like to show you the HTML and CSS part of the infinite slider on my portfolio. If you’d like to understand the WebGL part, I can recommend the following tutorial: Creating an Infinite Circular Gallery using WebGL with OGL and GLSL Shaders
The main idea of an infinite slider is to duplicate the actual content so that you can never see the end of it.
You can see the example here (open the Codesandbox for a better scroll experience):
Basically, you wrap everything in a big division that contains the doubled content and when you’ve translated the equivalent of 50% of the big wrapper, you put everything back to its initial position. It’s more like an illusion and it will make more sense when you look at this schematic drawing:
At this very moment the big wrapper snaps back to its initial position to mimic the effect of an infinite slider.
WebGL
Although I won’t explain the WebGL part because Luis already explains it in his tutorial, I do want to talk about the post-processing part with OGL because I love this process and it provides a very powerful way of adding interactions to your website.
To do the post-processing, all you need is the following:
this.post = new Post(this.gl);
this.pass = this.post.addPass({
fragment,
uniforms: {
uResolution: {
value: new Vec2(1, window.innerHeight / window.innerWidth)
},
uMouse: {
value: new Vec2()
},
uVelo: {
value: 0
},
uAmount: {
value: 0
}
}
});
We pass the mouse position, velocity and the time to the uniform. It will allow us to create a grain effect, and an RGB distortion based on the mouse position. You can find many shaders like this and I find it really cool to have it. And it’s not that hard to implement.
float circle(vec2 uv, vec2 disc_center, float disc_radius, float border_size) {
uv -= disc_center;
uv*= uResolution;
float dist = sqrt(dot(uv, uv));
return smoothstep(disc_radius+border_size, disc_radius-border_size, dist);
}
float random( vec2 p )
{
vec2 K1 = vec2(
23.14069263277926,
2.665144142690225
);
return fract( cos( dot(p,K1) ) * 12345.6789 );
}
void main() {
vec2 newUV = vUv;
float c = circle(newUV, uMouse, 0.0, 0.6);
float r = texture2D(tMap, newUV.xy += c * (uVelo * .9)).x;
float g = texture2D(tMap, newUV.xy += c * (uVelo * .925)).y;
float b = texture2D(tMap, newUV.xy += c * (uVelo * .95)).z;
vec4 newColor = vec4(r, g, b, 1.);
newUV.y *= random(vec2(newUV.y, uAmount));
newColor.rgb += random(newUV)* 0.10;
gl_FragColor = newColor;
}
You can find the complete implementation here:
Conclusion
I hoped that you liked this case study and learned a few tips and tricks! If you have any questions you can hit me up @anatoletouvron