@@ -65,18 +136,10 @@
\ No newline at end of file
diff --git a/src/routes/work/md/jpl.md b/src/routes/work/md/jpl.md
index b035936..1bc50e3 100644
--- a/src/routes/work/md/jpl.md
+++ b/src/routes/work/md/jpl.md
@@ -3,19 +3,13 @@ title: JustPeace Labs
header_bg_image: /work/jpl/jpl_hero.jpg
description: JustPeace Labs is a non-profit organization that works with local communities to build peace and prevent violence.
order: 11
-svg: ''
+svg: ''
---
-
Adidas, as you might have heard, is an international sports and lifestyle clothing brand. I worked on several digital campaigns as a graphic designer and illustrator.
-
+
+## JPL's Mission
+The startup has declared their mission "to empower local communities to be active participants in creating lasting just peace through the use of technology". I created a logo and housestyle for them that conveyes their goals and products.
+
+## The "broken peace" logo
+Since 1958, the Symbol for the British nuclear disarmament movement by Gerald Holtom is used as an international symbol for peace.
+
+Clients of JustPeace Labs are peace builders. The logo is a 'broken' peace sign with only the frame intact. It stands for the technological and ethical frameworks that JPL aims to provide that can be used to achieve long lasting, just peace.
\ No newline at end of file
diff --git a/src/routes/work/work.scss b/src/routes/work/work.scss
index f0fb534..bfa581b 100644
--- a/src/routes/work/work.scss
+++ b/src/routes/work/work.scss
@@ -1,13 +1,14 @@
h1 {
- font-size: 12vw;
+ font-size: 16vw;
font-style: italic;
- margin: 0.5em 0 0.5em 0;
+ margin: 0 0 0.5em 0;
letter-spacing: -0.04em;
text-align: center;
position: fixed;
top: 0;
width: 100%;
visibility: hidden;
+ transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
@media screen and (min-width: 768px) {
font-size: 7vw;
@@ -21,9 +22,7 @@ h1 {
h2 {
line-height: 1.1;
letter-spacing: -0.025em;
- // font-weight: 400;
font-size: 2.5vw;
- // visibility: hidden;
opacity: 0;
position: absolute;
left: .5em;
@@ -31,7 +30,6 @@ h2 {
transform: scale(0.8) translateY(100%);
margin: 0;
padding: 0.1em 0.4em 0.2em 0.4em;
- // border-radius: .25em;
text-align: center;
transform-origin: center center;
width: auto;
@@ -48,17 +46,19 @@ h2 {
.works {
padding: 15vw 0.5em 0.5em 0.5em;
display: flex;
- gap: 0.5em;
+ gap: 0.25em;
flex-wrap: wrap;
@media screen and (min-width: 768px) {
gap: 0.25em;
padding: 8.5vw 0.5em 0.5em 0.5em;
width: 100%;
+ max-width: 1200px;
+ margin: 0 auto;
padding-bottom: 20svh;
}
}
.work {
- flex: 0 0 100%;
+ flex: 0 0 calc(50% - 0.125em );
display: block;
position: relative;
padding: 0;
@@ -68,11 +68,11 @@ h2 {
@media screen and (min-width: 768px) {
flex: 0 0 calc(33% - .125em);
-
}
}
.workhero {
width: 100%;
+ height: auto;
aspect-ratio: var(--aspect-ratio-heroes);
object-fit: fill;
visibility: hidden;
diff --git a/src/routes/work/workUtils.ts b/src/routes/work/workUtils.ts
index 9b33f9b..9727db3 100644
--- a/src/routes/work/workUtils.ts
+++ b/src/routes/work/workUtils.ts
@@ -8,6 +8,42 @@ workbulge.subscribe(value => {
bulge.factor = value;
})
+export function initWorkPage( h1: HTMLElement, canvasImgElems: Array) {
+
+ workbulge.set(0.25);
+
+ gsap.registerPlugin( SplitText );
+
+ const h1Text = h1?.innerHTML || '';
+ h1.innerHTML = h1Text + h1Text + h1Text + h1Text || '';
+ h1.style.overflow = 'hidden';
+ h1.style.whiteSpace = 'nowrap';
+ const spans = Array.from(h1.querySelectorAll('span'));
+ spans.forEach((span) => {
+ gsap.set(span, { opacity: 0, y: window.innerHeight })
+ gsap.to(span, { opacity: 1, y: 0, duration: 1, ease: 'power3.out' })
+ gsap.to(span, { xPercent: -100, duration: 4, ease: 'none', repeat: -1 })
+ });
+
+ gsap.set(canvasImgElems, {
+ opacity: 0, yPercent: 100
+ })
+
+ gsap.to(canvasImgElems, {
+ duration: 1,
+ opacity: 1,
+ yPercent: 0,
+ stagger: 0.05,
+ ease: 'elastic.out(0.75, 0.5)',
+ delay: 0.3
+ })
+
+ return {
+ text: spans,
+ images: canvasImgElems
+ }
+}
+
export function workClickHandler(e:Event){
e.preventDefault();
const target = e.target as HTMLElement;
@@ -20,8 +56,11 @@ export function workClickHandler(e:Event){
targetImg.style.height = `${targetImgRect.height}px`;
targetImg.style.top = `${targetImgRect.top}px`;
targetImg.style.left = `${targetImgRect.left}px`;
+ const clone = targetImg.cloneNode(true) as HTMLElement;
+ targetImg.parentElement?.insertBefore(clone, targetImg);
targetImg.style.position = 'fixed';
+
gsap.to('.work:not(.active) .workhero', {
duration: .3,
opacity: 0,
@@ -48,59 +87,14 @@ export function workClickHandler(e:Event){
workbulge.set(bulge.factor);
}
})
- gsap.to('h1', {
+ gsap.to('h1 span', {
duration: .3,
- yPercent: -200,
+ yPercent: -100,
+ opacity: 0,
ease: 'circ.inOut',
})
setTimeout(() => {
goto(originalLink);
}, 600);
-}
-
-export function initWorkPage( h1: HTMLElement, canvasImgElems: Array) {
-
- workbulge.set(0.25);
-
- gsap.registerPlugin( SplitText );
-
- console.log('initWorkPage:', h1);
- const h1Text = h1?.innerHTML || '';
- h1.innerHTML = h1Text + h1Text + h1Text + h1Text || '';
- h1.style.overflow = 'hidden';
- h1.style.whiteSpace = 'nowrap';
-
- h1.querySelectorAll('span').forEach((span) => {
- gsap.to(span, {xPercent: -100, duration: 4, ease: 'none', repeat: -1 })
- });
-
- const split = new SplitText(h1, { type: 'words', wordsClass: 'words' });
-
- gsap.set(split.words, {
- opacity: 0, yPercent: -10
- })
- gsap.to(split.words, {
- duration: 1,
- opacity: 1,
- yPercent: 0,
- stagger: 0.1,
- ease: 'power4.out',
- })
-
- gsap.set(canvasImgElems, {
- opacity: 1, yPercent: 100
- })
- gsap.to(canvasImgElems, {
- duration: 1,
- opacity: 1,
- yPercent: 0,
- stagger: 0.05,
- ease: 'power4.out',
- })
-
- return {
- text: Array.from(split.words),
- images: canvasImgElems
- }
}
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
index c126657..89989a4 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,8 @@
import { sveltekit } from '@sveltejs/kit/vite';
+import{ imagetools }from'vite-imagetools';
import { defineConfig } from 'vite';
export default defineConfig({
- plugins: [sveltekit()]
+ plugins: [imagetools(),sveltekit()]
});