diff --git a/src/lib/components/HomeCanvas.svelte b/src/lib/components/HomeCanvas.svelte index 7184776..0d547b5 100644 --- a/src/lib/components/HomeCanvas.svelte +++ b/src/lib/components/HomeCanvas.svelte @@ -7,38 +7,29 @@ import SplitText from 'gsap/dist/SplitText'; import { PixiPlugin } from "gsap/dist/PixiPlugin"; import { onMount, onDestroy } from 'svelte'; import { browser } from '$app/environment'; -import createCanvasText from '$lib/utils/creareCanvasText'; +import createCanvasText from '$lib/utils/createCanvasText'; +import createCanvasImg from '$lib/utils/createCanvasImg'; import { tick } from 'svelte'; -export let textsToCanvas: NodeListOf; +export let textsToCanvas: Array = []; +export let imgsToCanvas: Array = []; let app: PIXI.Application; +let canvas: HTMLCanvasElement; onMount(()=>{ gsap.registerPlugin(PixiPlugin, ScrollTrigger, SplitText); - if (document.querySelector('.homeCanvas')) { - app = new PIXI.Application({ - resizeTo: window, - antialias: true, - autoDensity: true, - resolution: 2, - backgroundAlpha: 0, - view: document.querySelector('.homeCanvas') as HTMLCanvasElement, - }); - } - else { - app = new PIXI.Application({ - resizeTo: window, - antialias: true, - autoDensity: true, - resolution: 2, - backgroundAlpha: 0, - }); - let canvaselem = document.body.appendChild(app.view as HTMLCanvasElement); - canvaselem.classList.add('homeCanvas'); - } - //for debugging but Typescript has an issue with this: + app = new PIXI.Application({ + resizeTo: window, + antialias: true, + autoDensity: true, + resolution: 2, + backgroundAlpha: 0, + view: canvas, + }); + + //for debugging but Typescript has an issue with this: // globalThis.__PIXI_APP__ = app as any; PixiPlugin.registerPIXI(PIXI); @@ -86,12 +77,11 @@ onMount(()=>{ async function convertText(){ await tick(); textsToCanvas.forEach((element) => { - elems.push(element as HTMLElement); - let canvasText = createCanvasText(element as HTMLElement, app.stage); - canvasTexts.push(canvasText as PIXI.Text); + elems.push(element); + let canvasText = createCanvasText(element, app.stage); + canvasTexts.push(canvasText); }) } - convertText(); /*---------------------------------- @@ -106,11 +96,45 @@ onMount(()=>{ }) } + /*---------------------------------- + * Convert images to canvas + * createCanvacImgs function + ----------------------------------*/ + let canvasImgs: Array = []; + let imgElems: Array = []; + + function convertImgs(){ + imgsToCanvas.forEach((element) => { + imgElems.push(element); + let canvasImg = createCanvasImg(element, app.stage); + canvasImgs.push(canvasImg); + }) + } + + setTimeout(() => { + convertImgs(); + convertText(); + }, 100); + // convertImgs(); + // convertText(); + + /*---------------------------------- + * Function to update text on canvas + * runs in the Ticker + ----------------------------------*/ + function updateImgs(){ + canvasImgs.forEach((image, index) => { + let imagePosition = imgElems[index].getBoundingClientRect(); + image.position.set(imagePosition.x, imagePosition.y); + image.width = imagePosition.width; + image.height = imagePosition.height; + }) + } /*---------------------------------- * Mousemove events *----------------------------------*/ - window.addEventListener('pointermove', (e) => { + window.addEventListener('mousemove', (e) => { const pointerX = e.clientX / window.innerWidth; const pointerY = e.clientY / window.innerHeight; const pointerXfrac = pointerX - 0.5; @@ -128,9 +152,9 @@ onMount(()=>{ app.ticker.add((delta) => { elapsed += delta; bulgefilter.center = [(center[0] + Math.sin(elapsed/200)/20 ),(center[1] + Math.cos(elapsed/200)/20 )]; + updateImgs(); updateText(); }) - console.log('HomeCanvas mounted', textsToCanvas); }) // <- end onMount onDestroy(() => { @@ -140,3 +164,14 @@ onDestroy(() => { }) // <- end onDestroy + + + + \ No newline at end of file diff --git a/src/lib/components/WorkCanvas.svelte b/src/lib/components/WorkCanvas.svelte new file mode 100644 index 0000000..8d0c514 --- /dev/null +++ b/src/lib/components/WorkCanvas.svelte @@ -0,0 +1,205 @@ + + + + + \ No newline at end of file diff --git a/src/lib/importMarkdown.ts b/src/lib/importMarkdown.ts index 1f9d21f..f7cf472 100644 --- a/src/lib/importMarkdown.ts +++ b/src/lib/importMarkdown.ts @@ -4,6 +4,7 @@ type Post = { date: string description: string tags: string[] + header_bg_image: string } default: { render: () => string diff --git a/src/lib/styles/global.scss b/src/lib/styles/global.scss index 91fdc3b..52cdde0 100644 --- a/src/lib/styles/global.scss +++ b/src/lib/styles/global.scss @@ -14,12 +14,6 @@ body { } body * { box-sizing: border-box; -} -canvas { - position: fixed; - top: 0; - left: 0; - z-index: -1; } h1, h2, h3, h4, h5 { font-size: 1em; diff --git a/src/lib/utils/createCanvasImg.ts b/src/lib/utils/createCanvasImg.ts new file mode 100644 index 0000000..ca96156 --- /dev/null +++ b/src/lib/utils/createCanvasImg.ts @@ -0,0 +1,19 @@ +import * as PIXI from 'pixi.js'; + +export default function createCanvasText( element: HTMLElement, stage: PIXI.Container ){ + + const elem = element; + // console.log(elem); + const elemSrc = elem.getAttribute('src') || ''; + const elemPosition = elem.getBoundingClientRect(); + + const canvasImg = PIXI.Sprite.from(elemSrc); + canvasImg.position.set(elemPosition.x, elemPosition.y); + canvasImg.width = elemPosition.width; + canvasImg.height = elemPosition.height; + stage.addChild(canvasImg); + + // elem.style.opacity = '0'; + elem.style.visibility = 'hidden'; + return canvasImg; +} \ No newline at end of file diff --git a/src/lib/utils/creareCanvasText.ts b/src/lib/utils/createCanvasText.ts similarity index 78% rename from src/lib/utils/creareCanvasText.ts rename to src/lib/utils/createCanvasText.ts index fcf6c6d..4af9cdd 100644 --- a/src/lib/utils/creareCanvasText.ts +++ b/src/lib/utils/createCanvasText.ts @@ -6,7 +6,9 @@ export default function createCanvasText( element: HTMLElement, stage: PIXI.Con const elem = element; const elemStyles = window.getComputedStyle(elem); const elemFontSize = elemStyles.getPropertyValue('font-size'); + const elemFontWeight = elemStyles.getPropertyValue('font-weight'); const elemFontFamily = elemStyles.getPropertyValue('font-family'); + const elemFontStyle = elemStyles.getPropertyValue('font-style'); const elemLetterSpacing = parseInt(elemStyles.getPropertyValue('letter-spacing')); const elemColor = elemStyles.getPropertyValue('color'); const elemAlignment = elemStyles.getPropertyValue('text-align'); @@ -15,11 +17,14 @@ export default function createCanvasText( element: HTMLElement, stage: PIXI.Con const canvasText = new Text(elem?.textContent as string, { fontFamily: elemFontFamily, fontSize: elemFontSize, + fontWeight: elemFontWeight as PIXI.TextStyleFontWeight, + fontStyle: elemFontStyle as PIXI.TextStyleFontStyle, letterSpacing: elemLetterSpacing, fill: elemColor, align: elemAlignment as PIXI.TextStyleAlign, }); canvasText.position.set(elemPosition.x, elemPosition.y); + // canvasText.zIndex = 100; stage.addChild(canvasText); elem.style.opacity = '0'; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index a0ada83..d499cfd 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -6,42 +6,45 @@ onMount(() => { let navlinks = document.querySelectorAll('nav a'); + navlinks.forEach((link, index) => { link.addEventListener('click', (e)=> { const checkbox = document.querySelector('input[type="checkbox"]') as HTMLInputElement; checkbox ? checkbox.checked = false : null; - gsap.to('.content', {duration: 0.5, y: '0%', autoAlpha: 1, ease: 'power4.out'}); + gsap.to('.content > *', {duration: 0.5, y: '0%', autoAlpha: 1, ease: 'power4.out'}); }) }); + let checkbox = document.getElementById('menustate') as HTMLInputElement; + checkbox.addEventListener('change', (e)=> { if (checkbox.checked) { - gsap.to('.content', {duration: 0.75, y: -200, autoAlpha: 0.5, ease: 'power2.inOut'}); + gsap.to('.content > *', {duration: 0.75, y: -200, autoAlpha: 0.5, ease: 'power2.inOut'}); gsap.from('#nav', {duration: 0.5, autoAlpha: 0, y: '100%', ease: 'power4.out', delay: 0.1}); gsap.from('nav a', {duration: 0.5, autoAlpha: 0, y: 20, stagger: 0.1, ease: 'power4.out' , delay: 0.2}); } else { - gsap.to('.content', {duration: 0.5, y: '0%', autoAlpha: 1, ease: 'power4.out'}); + gsap.to('.content > *', {duration: 0.5, y: '0%', autoAlpha: 1, ease: 'power4.out'}); } }) }); - -
- - - - -
+ +
+ + + + +
@@ -52,13 +55,24 @@ position: fixed; bottom: 0; right: 0; - z-index: 1; + z-index: 3; padding: var(--spacing-outer); display: flex; gap: .75em; justify-content: flex-end; align-items: flex-end; box-sizing: border-box; + // width: 100%; + + // &:before { + // content: ''; + // position: absolute; + // bottom: 0; + // left: 0; + // width: 100%; + // height: 100%; + // background: linear-gradient(0deg, #00117fFF 0%, #00117fFF 30%, #00117f00 100%); + // } } label { height: 36px; @@ -95,7 +109,7 @@ width: auto; position: fixed; bottom: 0; - z-index: 2; + z-index: 4; display: flex; margin: var(--spacing-outer); } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 69ff7a0..b76ba45 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -5,9 +5,8 @@ import SplitText from 'gsap/dist/SplitText'; import { onMount } from 'svelte'; - let canvasElems: NodeListOf; + let canvasElems: Array; onMount(() => { - console.log('Home mounted'); gsap.registerPlugin( ScrollTrigger, SplitText ); @@ -51,7 +50,7 @@ }) } }) - canvasElems = document.querySelectorAll('.lineChildren') as NodeListOf; + canvasElems = Array.from(document.querySelectorAll('.lineChildren')); }); @@ -98,13 +97,7 @@
- {#await onMount} - waiting - {:then} - - {:catch error} -

error

- {/await} + \ No newline at end of file diff --git a/src/routes/work/[slug]/+page.server.ts b/src/routes/work/[slug]/+page.server.ts index 0b113e0..fc0a5b5 100644 --- a/src/routes/work/[slug]/+page.server.ts +++ b/src/routes/work/[slug]/+page.server.ts @@ -1,12 +1,13 @@ export async function load({ params }){ try { const post = await import(`../${params.slug}.md`) - const { title, date } = post.metadata + const { title, date, header_bg_image } = post.metadata const Content = post.default.render() return { title, date, + header_bg_image, Content } } catch (error) { diff --git a/src/routes/work/[slug]/+page.svelte b/src/routes/work/[slug]/+page.svelte index 34657e4..8368a9c 100644 --- a/src/routes/work/[slug]/+page.svelte +++ b/src/routes/work/[slug]/+page.svelte @@ -1,13 +1,45 @@ -
-

{data.title}

-

{@html data.Content.html}

+ {data.title} + {#if visible} +

{data.title}

+

{@html data.Content.html}

+ {/if}
\ No newline at end of file diff --git a/src/routes/work/adidas.md b/src/routes/work/adidas.md index c184728..b1e963f 100644 --- a/src/routes/work/adidas.md +++ b/src/routes/work/adidas.md @@ -1,10 +1,8 @@ --- title: Adidas -category: Visual Design -permalink: /work/adidas -header_bg_image: ./img/work_adidas/adidas_hero_bw.jpg -extra_classes: portfolio theme-adidas +header_bg_image: /work/adidas/adidas_hero.jpg order: 12 +description: 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. svg: ' ' diff --git a/src/routes/work/formo.md b/src/routes/work/formo.md new file mode 100644 index 0000000..aa6f9f1 --- /dev/null +++ b/src/routes/work/formo.md @@ -0,0 +1,21 @@ +--- +title: Formo.bio +header_bg_image: /work/formo/formo_hero.png +order: 12 +description: Formo, 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. +svg: ' + + ' +--- +
+

Client: Adidas E-commerce dept

+ Tasks: +
    +
  • Visual Design
  • +
  • Campaign asset production
  • +
  • Illustration
  • +
+
+
+

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.

+
diff --git a/src/routes/work/jpl.md b/src/routes/work/jpl.md new file mode 100644 index 0000000..b035936 --- /dev/null +++ b/src/routes/work/jpl.md @@ -0,0 +1,21 @@ +--- +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: ' + + ' +--- +
+

Client: Adidas E-commerce dept

+ Tasks: +
    +
  • Visual Design
  • +
  • Campaign asset production
  • +
  • Illustration
  • +
+
+
+

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.

+
diff --git a/static/work/adidas/adidas_hero.jpg b/static/work/adidas/adidas_hero.jpg new file mode 100644 index 0000000..5d0e9ae Binary files /dev/null and b/static/work/adidas/adidas_hero.jpg differ diff --git a/static/work/formo/formo_hero.png b/static/work/formo/formo_hero.png new file mode 100644 index 0000000..679e5ff Binary files /dev/null and b/static/work/formo/formo_hero.png differ diff --git a/static/work/jpl/jpl_hero.jpg b/static/work/jpl/jpl_hero.jpg new file mode 100644 index 0000000..7912ec0 Binary files /dev/null and b/static/work/jpl/jpl_hero.jpg differ diff --git a/vite.config.ts b/vite.config.ts index bbf8c7d..c126657 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,7 @@ import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; + export default defineConfig({ plugins: [sveltekit()] });