ch ch ch changes

This commit is contained in:
saiminh 2023-10-04 16:08:54 +02:00
parent 7edcaae656
commit 8a5a4bb40e
7 changed files with 202 additions and 120 deletions

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
import { BulgePinchFilter } from 'pixi-filters'; import { BulgePinchFilter, TwistFilter } from 'pixi-filters';
import gsap from 'gsap'; import gsap from 'gsap';
import ScrollTrigger from 'gsap/dist/ScrollTrigger'; import ScrollTrigger from 'gsap/dist/ScrollTrigger';
import SplitText from 'gsap/dist/SplitText'; import SplitText from 'gsap/dist/SplitText';
@ -29,6 +29,7 @@ onMount(()=>{
let is_coarse = window.matchMedia('(pointer:coarse)').matches let is_coarse = window.matchMedia('(pointer:coarse)').matches
let is_landscape = window.matchMedia('(orientation:landscape)').matches let is_landscape = window.matchMedia('(orientation:landscape)').matches
let is_portrait = window.matchMedia('(orientation:portrait)').matches let is_portrait = window.matchMedia('(orientation:portrait)').matches
let is_twisted = false;
gsap.registerPlugin(PixiPlugin, ScrollTrigger, SplitText); gsap.registerPlugin(PixiPlugin, ScrollTrigger, SplitText);
@ -69,7 +70,24 @@ onMount(()=>{
bulgefilter.center = is_landscape ? center : [0.5, 0]; bulgefilter.center = is_landscape ? center : [0.5, 0];
bulgefilter.resolution = 2; bulgefilter.resolution = 2;
bulgegroup.filters = [bulgefilter]; let twistfilter = new TwistFilter();
twistfilter.angle = 0;
twistfilter.radius = window.innerWidth/2;
twistfilter.offset = new PIXI.Point(window.innerWidth/2, window.innerHeight/2);
twistfilter.resolution = 2;
bulgegroup.filters = [bulgefilter, twistfilter];
gsap.to(twistfilter, {
angle: .75,
duration: 1,
ease: 'elastic.out',
delay: 2,
onComplete: () => {
is_twisted = true;
}
})
/*---------------------------------- /*----------------------------------
* Convert text to canvas using * Convert text to canvas using
@ -169,9 +187,8 @@ onMount(()=>{
ease: 'power3.out', ease: 'power3.out',
overwrite: true, overwrite: true,
x: 0.5 + pointerXfrac/2, x: 0.5 + pointerXfrac/2,
y: 0.5 + pointerYfrac/2, y: 0.5 + pointerYfrac/6,
}) })
}) })
} }
@ -185,10 +202,12 @@ onMount(()=>{
elapsed += delta; elapsed += delta;
if (!is_landscape) { if (!is_landscape) {
// bulgefilter.center = [(tween.x + Math.sin(elapsed/200)/20 ),(tween.y + Math.cos(elapsed/200)/20 )]; // bulgefilter.center = [(tween.x + Math.sin(elapsed/200)/20 ),(tween.y + Math.cos(elapsed/200)/20 )];
bulgefilter.center = [(0.5 + Math.sin(elapsed/200)/20 ),(0.25 + Math.cos(elapsed/200)/20 )]; bulgefilter.center = [(0.5 + Math.sin(elapsed/200)/20 ),(0.4 + Math.cos(elapsed/200)/20 )];
twistfilter.offset = new PIXI.Point( twistfilter.offset.x + Math.sin(elapsed/100) - Math.sin(elapsed/100) * 2, twistfilter.offset.y );
// bulgefilter.center = [0.5, 0.25]; // bulgefilter.center = [0.5, 0.25];
} else { } else {
bulgefilter.center = [tween.x, 0.5]; bulgefilter.center = [tween.x, tween.y];
twistfilter.offset = new PIXI.Point(mouse.x, mouse.y);
} }
updateImgs(); updateImgs();
updateText(); updateText();

View file

@ -207,7 +207,7 @@ onMount(()=>{
bulgefilter.center = [(0.5 + Math.sin(elapsed/200)/20 ),(0.45 + Math.cos(elapsed/200)/20 )]; bulgefilter.center = [(0.5 + Math.sin(elapsed/200)/20 ),(0.45 + Math.cos(elapsed/200)/20 )];
// bulgefilter.center = [0.5, 0.45]; // bulgefilter.center = [0.5, 0.45];
} else { } else {
bulgefilter.center = [tween.x, 0.5]; bulgefilter.center = [tween.x, tween.y];
} }
updateImgs(); updateImgs();
updateText(); updateText();

View file

@ -14,6 +14,7 @@
} }
.shape > * { .shape > * {
transform-origin: 50% 50%; transform-origin: 50% 50%;
fill: var(--color-highlight, #000);
} }
.sphere, .quartercirc, .triangle, .rectangle { .sphere, .quartercirc, .triangle, .rectangle {
fill: none; fill: none;

Before

Width:  |  Height:  |  Size: 744 B

After

Width:  |  Height:  |  Size: 784 B

View file

@ -1,9 +1,9 @@
:root { :root {
--spacing-outer: 5vw; --spacing-outer: 5vw;
--spacing-nav: 5vw; --spacing-nav: 5vw;
--color-bg: #3c71c8; --color-bg: #2085e3;
--color-text: #ffeee6; --color-text: #ffe9e6;
--color-highlight: #000000; --color-highlight: #1d0c12;
// --color-bg: #000000; // --color-bg: #000000;
// --color-text: #FFFFFF; // --color-text: #FFFFFF;
// --color-highlight: #FF4D00; // --color-highlight: #FF4D00;
@ -86,11 +86,20 @@ a {
padding: .75em; padding: .75em;
text-decoration: none; text-decoration: none;
box-sizing: border-box; box-sizing: border-box;
border: none;
color: var(--color-text); color: var(--color-text);
line-height: 1.2; line-height: 1.2;
cursor: url('/pointer.svg'), auto;
position: relative; position: relative;
z-index: 2; z-index: 2;
transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
&:hover {
@media screen and (min-width: 768px) {
// font-size: 1.05em;
letter-spacing: 0.01em;
}
}
&:before { &:before {
content: ''; content: '';
@ -114,7 +123,7 @@ a {
transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275); transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
} }
&.button--primary { &.button--primary {
color: var(--color-bg); color: var(--color-text);
&:before { &:before {
background-color: var(--color-highlight); background-color: var(--color-highlight);
@ -125,9 +134,7 @@ a {
font-size: clamp(24px, 3.2vw, 3.2vw); font-size: clamp(24px, 3.2vw, 3.2vw);
padding: 0.5em; padding: 0.5em;
letter-spacing: -0.02em; letter-spacing: -0.02em;
// display: block;
margin: 0 auto; margin: 0 auto;
max-width: 40vw;
text-align: center; text-align: center;
&:hover { &:hover {

View file

@ -76,7 +76,7 @@
{/if} {/if}
<article class="scroller"> <article class="scroller">
<section class="splash"> <section class="splash">
<h1 class="align-middle">Hallo! I'm Simon. I forge websites that stand out with exemplary beauty.</h1> <h1 class="align-middle">Hallo! I'm Simon. I forge websites that <em>stand out</em> with exemplary beauty.</h1>
</section> </section>
<section class="intro"> <section class="intro">
<figure class="intro-image"> <figure class="intro-image">
@ -86,7 +86,7 @@
<p class="toCanvas">I fashion exquisitly tailored web experiences for discerning enterprises and their audiences.</p> <p class="toCanvas">I fashion exquisitly tailored web experiences for discerning enterprises and their audiences.</p>
<div class="cta"> <div class="cta">
<a href="/service" class="button">My Services</a> <a href="/service" class="button">My Services</a>
<a href="/work" class="button button--primary">Hire Simon</a> <a href="/contact" class="button button--primary">Get in touch!</a>
</div> </div>
</section> </section>
<section class="design"> <section class="design">
@ -96,13 +96,13 @@
<h2>Visual Design</h2> <h2>Visual Design</h2>
<p class="toCanvas">I'm also a seasoned designer, sculpting communication that's wickedly nice, full of jaw-dropping surprises, and utterly delightful.</p> <p class="toCanvas">I'm also a seasoned designer, sculpting communication that's wickedly nice, full of jaw-dropping surprises, and utterly delightful.</p>
<div class="cta"> <div class="cta">
<a href="/service" class="button">My Services</a> <a href="/work" class="button button--primary">Hire Simon</a> <a href="/service" class="button">My Services</a> <a href="/contact" class="button button--primary">Get in touch!</a>
</div> </div>
</section> </section>
<section class="more"> <section class="more">
<h2 class="align-middle">I work as a free agent. Both companies and noble causes can enlist my services for a reasonable wage.</h2> <h2 class="align-middle">I work as a free agent. Both companies and noble causes can <em>enlist my services</em> for a reasonable wage.</h2>
<div class="cta"> <div class="cta">
<a href="/work" class="button button--xl">Enlist my services</a> <a href="/contact" class="button button--xl">Enlist my services</a>
</div> </div>
</section> </section>
</article> </article>
@ -199,6 +199,11 @@
-moz-user-select: none; /* Firefox */ -moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */ -ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; user-select: none;
& > em {
font-style: normal;
font-weight: 400;
color: var(--color-highlight);
}
} }
h1 { h1 {
line-height: .9; line-height: .9;

View file

@ -6,12 +6,38 @@
import ScrollTrigger from 'gsap/dist/ScrollTrigger'; import ScrollTrigger from 'gsap/dist/ScrollTrigger';
let canvasTexts: Array<HTMLElement> = []; let canvasTexts: Array<HTMLElement> = [];
let contactFormVisible = false;
let contactFormClickHandler = (e: Event) => {
if (contactFormVisible) {
gsap.to('.wordChildren', { opacity: 1, yPercent: 0, duration: 1, ease: 'power4.inOut' })
gsap.to('.alternatives > *', { opacity: 1, scale: 1, duration: .5, stagger: 0.1, ease: 'power4.inOut' })
gsap.fromTo('.formwrapper',
{ opacity: 1, yPercent: 0 },
{ opacity: 0, yPercent: 50, duration: .6, ease: 'power4.inOut', onComplete: ()=>{
gsap.set('.formwrapper', { zIndex: -1 })
} }
)
} else {
gsap.to('.wordChildren', { opacity: 1, yPercent: -200, duration: 1, ease: 'power4.inOut' })
gsap.to('.alternatives > *', { opacity: 0, scale: 0.5, duration: .5, stagger: 0.1, ease: 'power4.inOut' })
gsap.set('.formwrapper', { zIndex: 2 })
gsap.fromTo('.formwrapper',
{ opacity: 1, yPercent: 100 },
{ opacity: 1, yPercent: 0, duration: 1, ease: 'power4.inOut' }
)
gsap.fromTo('.formwrapper label > *',
{ opacity: 0, yPercent: 100 },
{ opacity: 1, yPercent: 0, duration: .5, stagger: 0.0125, ease: 'power4.out', delay: .25}
)
}
contactFormVisible = !contactFormVisible;
}
onMount( () => { onMount( () => {
gsap.registerPlugin( SplitText, ScrollTrigger ); gsap.registerPlugin( SplitText, ScrollTrigger );
let split = new SplitText('.toCanvas', { type: 'lines', linesClass: 'lineChildren' }); let split = new SplitText('.toCanvas', { type: 'words, lines', wordsClass: 'wordChildren', linesClass: 'lineChildren' });
let alignmiddles: Array<HTMLElement> = Array.from(document.querySelectorAll('.toCanvas')); let alignmiddles: Array<HTMLElement> = Array.from(document.querySelectorAll('.toCanvas'));
alignmiddles.forEach( (toCanvas) => { alignmiddles.forEach( (toCanvas) => {
@ -28,188 +54,210 @@
toCanvas.style.left = (toCanvas.offsetWidth - longestSpan) / 2 + 'px'; toCanvas.style.left = (toCanvas.offsetWidth - longestSpan) / 2 + 'px';
}) })
canvasTexts = Array.from(document.querySelectorAll('.lineChildren')); canvasTexts = Array.from(document.querySelectorAll('.wordChildren'));
const introIn = document.querySelector('.contact') as HTMLElement; const introInElem = document.querySelector('.pagewrapper') as HTMLElement;
gsap.fromTo(introIn.querySelectorAll('.lineChildren'), { gsap.fromTo(introInElem.querySelectorAll('.wordChildren'), {
opacity: 0, yPercent: -100 opacity: 0, yPercent: -100
}, { }, {
opacity: 1, yPercent: 0, duration: 1.5, stagger: 0.05, ease: 'power4.inOut', opacity: 1, yPercent: 0, duration: 1.5, stagger: 0.025, ease: 'power4.inOut',
}) })
gsap.fromTo(introIn?.querySelectorAll('p, input, .button'), { gsap.fromTo(introInElem?.querySelectorAll('.alternatives p, .alternatives .button'), {
opacity: 0, yPercent: 100 opacity: 0, yPercent: 100
}, { }, {
opacity: 1, yPercent: 0, duration: 1, stagger: 0.05, ease: 'power4.inOut', opacity: 1, yPercent: 0, duration: 1, stagger: 0.025, ease: 'power4.inOut',
}) })
const scrollIns = document.querySelectorAll('.scrollIn');
scrollIns.forEach( scrollIn => {
gsap.set(scrollIn.querySelectorAll('p, input, textarea, .button'), { opacity: 0, y: 100 });
gsap.to(scrollIn.querySelectorAll('p, input, textarea, .button'), { opacity: 1, y: 0, duration: 1, stagger: 0.05, ease: 'power4.inOut',
scrollTrigger: { trigger: scrollIn, start: 'top 66%', end: 'bottom 50%', scrub: false }
})
gsap.fromTo(scrollIn.querySelectorAll('.lineChildren'), {
opacity: 0, yPercent: 100
},{
opacity: 1, yPercent: 0, duration: 1, stagger: 0.05, ease: 'power4.inOut',
scrollTrigger: { trigger: scrollIn, start: 'top 66%', end: 'bottom 50%', scrub: false }
})
})
let textarea = document.querySelector('textarea') as HTMLElement
textarea?.addEventListener('focus', () => {
window.scrollTo(0, textarea.offsetTop - 100);
})
return () => { return () => {
gsap.killTweensOf('.toCanvas, .lineChildren'); gsap.killTweensOf('.toCanvas, .wordChildren');
} }
}) })
</script> </script>
<div class="formwrapper"> <div class="pagewrapper">
<form name="contact" action="/success" method="POST" data-netlify="true"> <div class="intro">
<input type="hidden" name="form-name" value="contact"> <h1 class="toCanvas">Life is weird. <em>Let's be weird together.</em></h1>
<section class="contact"> <div class="alternatives">
<h1 class="toCanvas">Don't be a stranger. Let's get acquainted.</h1> <p>Choose your flavour of contact:</p>
<div class="alternatives"> <ul>
<p>You can fill in the form below or:</p> <li><span class="button" on:click={contactFormClickHandler} on:keydown={contactFormClickHandler} role="button" tabindex="0">Contact form</span></li>
<ul> <li><a class="button" href="mailto:simon@floter.design">Email</a></li>
<li><a class="button" href="mailto:simon@floter.design">Send an Email</a></li> <li><a class="button" href="https://www.linkedin.com/in/floter/">LinkedIn</a></li>
<li><a class="button" href="https://www.linkedin.com/in/floter/">Connect on LinkedIn</a></li> </ul>
</div>
</div>
<div class="formwrapper">
<span class="button button-back" on:click={contactFormClickHandler} on:keydown={contactFormClickHandler} role="button" tabindex="0">← Back</span>
<form name="contact" action="/success" method="POST" data-netlify="true">
<input type="hidden" name="form-name" value="contact">
<div class="inputs-flex-row">
<label for="name">
<!-- <p>How would you like to be addressed?</p> -->
<input type="text" name="name" id="name" placeholder="Your name">
</label>
<label for="email">
<!-- <p>For receiving a reply, add your Email address:</p> -->
<input type="email" name="email" id="email" placeholder="Your Email?*" required>
</label>
</div> </div>
<label for="name">
<p>How would you like to be addressed?</p>
<input type="text" name="name" id="name" placeholder="Your name">
</label>
<label for="email">
<p>For receiving a reply, add your Email address:</p>
<input type="email" name="email" id="email" placeholder="Your Email?*" required>
</label>
</section>
<section class="message scrollIn">
<h3 class="toCanvas contactheadline">How can I assist in your noble cause?</h3>
<label for="contact"> <label for="contact">
<p>Please describe your plight in a few words</p> <!-- <p>Please describe your plight in a few words</p> -->
<textarea rows="6" name="contact" id="contact" /> <textarea rows="6" name="contact" id="contact" placeholder="Your business propositions, praise, complaints and/or threats" required />
</label> </label>
<button class="button" type="submit">Send it!</button> <div class="send">
</section> <button class="button button--xl button--primary" type="submit">Send it!</button>
</form> </div>
</form>
</div>
</div> </div>
<ContactCanvas textsToCanvas={canvasTexts} /> <ContactCanvas textsToCanvas={canvasTexts} />
<style lang="scss"> <style lang="scss">
h1, h3 { h1 {
visibility: hidden; visibility: hidden;
font-size: 2.5em; font-size: 12vw;
line-height: .9; line-height: .9;
letter-spacing: -0.04em; letter-spacing: -0.04em;
margin: 1em var(--spacing-nav) 1em var(--spacing-nav); margin: 1em var(--spacing-nav) 1em var(--spacing-nav);
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
margin: 1em var(--spacing-outer) 0.33em var(--spacing-outer); margin: 1em var(--spacing-outer) .75em var(--spacing-outer);
font-size: 4.5em; font-size: 4.5em;
} }
}
h3 { & em {
font-size: 2em; font-style: normal;
@media screen and (min-width: 768px) { font-weight: 400;
font-size: 3em; color: var(--color-highlight);
} }
} }
.contact p, .contact input { .intro {
opacity: 0; width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
padding-bottom: 4em;
@media screen and (min-width: 768px) {
padding-bottom: 0;
}
} }
.formwrapper { .formwrapper {
margin: 0 auto; position: fixed;
padding: 1em 1em calc(4 * var(--spacing-outer)) 1em; top: 0;
left: 0;
width: 100%;
height: 100%;
padding: var(--spacing-outer) var(--spacing-outer) 4em var(--spacing-outer);
background-color: var(--color-bg);
z-index: 0;
opacity: 0;
overflow-y: scroll;
--form-maxwidth: 1000px;
}
.button-back {
margin: 0;
} }
form { form {
box-sizing: border-box; box-sizing: border-box;
max-width: inherit; max-width: inherit;
margin: 0 auto; margin: 0 auto;
overflow: hidden; overflow: hidden;
padding: 1em 0;
}
.inputs-flex-row {
@media screen and (min-width: 768px) {
display: flex;
gap: 1em;
justify-content: center;
max-width: var(--form-maxwidth);
margin: auto;
& label {
flex-basis: 50%;
}
}
} }
.alternatives { .alternatives {
margin: 4em auto 1em auto; margin: 0em auto 1em auto;
width: 100%; width: 100%;
text-align: center;
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
margin: 0 auto 2em auto; margin: 0 auto 2em auto;
padding-bottom: 1em; padding-bottom: 1em;
max-width: 640px;
} }
& p, & .button {
opacity: 0;
}
& p { & p {
margin: 0; margin: 0 0 .5em 0;
} }
& ul { & ul {
list-style-type: none; margin: 0 var(--spacing-outer);
display: flex;
gap: .5em; // @media screen and (min-width: 768px) {
list-style-type: none;
display: flex;
justify-content: center;
gap: .25em;
// }
}
& ul li {
display: block;
margin: 0; margin: 0;
} }
& .button { & .button {
margin-top: 0.5em; margin: 0.25em 0;
} display: block;
} font-size: .9em;
section {
box-sizing: border-box;
margin: 0;
min-height: 70vh;
@media screen and (min-width: 768px) {
// display: flex;
// flex-direction: column;
// justify-content: center;
max-width: 75vw;
margin: 0 auto;
gap: 0;
} }
} }
label { label {
font-size: 1.25em; font-size: 1em;
@media screen and (min-width: 768px) {
font-size: 1.25em;
}
} }
input[type='text'], input[type='email'], textarea { input[type='text'], input[type='email'], textarea {
width: 100%; width: 100%;
border: 0px solid var(--color-text); border: 3px solid var(--color-text);
background-color: rgba(255, 205, 205, 0.2); background-color: var(--color-text);
color: var(--color-text); color: var(--color-bg);
border-radius: 4px; border-radius: 4px;
font-family: 'Stratos', sans-serif; font-family: 'Stratos', sans-serif;
font-size: 1em; font-size: 1em;
line-height: 1.2;
padding: .75em; padding: .75em;
transition: all 0.3s ease-out; transition: all 0.3s ease-out;
margin: 0 auto 1em auto; margin: 0 auto 1em auto;
display: block; display: block;
max-width: 640px; max-width: var(--form-maxwidth);
&:focus { &:focus {
outline: none; outline: none;
color: var(--color-bg); color: var(--color-bg);
background-color: var(--color-text); background-color: var(--color-text);
} }
&:placeholder-shown {
background-color: rgba(255, 205, 205, 0);
}
&::placeholder { &::placeholder {
color: var(--color-text); color: var(--color-text);
opacity: .7; opacity: .7;
} }
} }
label p { label p {
max-width: 640px; max-width: var(--form-maxwidth);
margin: 0 auto 1em auto; margin: 0 auto 1em auto;
display: block; display: block;
font-size: .75em; font-size: .75em;
margin-bottom: .5em; margin-bottom: .5em;
} }
button { .send {
display: block; max-width: var(--form-maxwidth);
width: 100%; margin: auto;
margin: 0 auto;
font-size: 1.25em;
max-width: 640px;
opacity: 0;
} }
</style> </style>

View file

@ -10,6 +10,8 @@
onMount( () => { onMount( () => {
let highLightColor = window.getComputedStyle(document.body).getPropertyValue('--color-highlight');
let is_fine = window.matchMedia('(pointer:fine)').matches let is_fine = window.matchMedia('(pointer:fine)').matches
let is_landscape = window.matchMedia('(orientation:landscape)').matches let is_landscape = window.matchMedia('(orientation:landscape)').matches
@ -44,7 +46,7 @@
// fontWeight: '800', // fontWeight: '800',
lineHeight: 0, lineHeight: 0,
letterSpacing: -20, letterSpacing: -20,
fill: `#000`, fill: highLightColor,
padding: 0 padding: 0
} }
); );