From 315fb5721c45716356abca80a1bd861b78e38696 Mon Sep 17 00:00:00 2001 From: Morten Olsen Date: Thu, 26 Aug 2021 09:36:43 +0200 Subject: [PATCH] Updated ui --- components/Background/index.tsx | 96 ++++++++++++++++++++++++++ components/Me.tsx | 57 +++++++++++++-- components/Social.tsx | 14 ++-- package.json | 4 +- pages/index.tsx | 32 ++------- public/images/logos/htb.svg | 4 +- public/images/logos/stackoverflow.svg | 2 +- public/images/smoke.png | Bin 0 -> 10632 bytes yarn.lock | 10 +++ 9 files changed, 177 insertions(+), 42 deletions(-) create mode 100644 components/Background/index.tsx create mode 100644 public/images/smoke.png diff --git a/components/Background/index.tsx b/components/Background/index.tsx new file mode 100644 index 0000000..daa8442 --- /dev/null +++ b/components/Background/index.tsx @@ -0,0 +1,96 @@ +// https://redstapler.co/cool-nebula-background-effect-three-js/ + +import * as THREE from 'three'; +import React, { useEffect } from 'react'; + +const setup = () => { + let scene, camera, renderer; + let cloudParticles = []; + + function init() { + scene = new THREE.Scene(); + camera = new THREE.PerspectiveCamera(60,window.innerWidth / window.innerHeight,1,1000); + camera.position.z = 1; + camera.rotation.x = 1.16; + camera.rotation.y = -0.12; + camera.rotation.z = 0.27; + let ambient = new THREE.AmbientLight(0x555555); + scene.add(ambient); + renderer = new THREE.WebGLRenderer(); + renderer.setSize(window.innerWidth,window.innerHeight); + scene.fog = new THREE.FogExp2(0x03544e, 0.001); + renderer.setClearColor(scene.fog.color); + renderer.domElement.style.position = 'fixed'; + renderer.domElement.style.top = '0'; + renderer.domElement.style.left = '0'; + renderer.domElement.style.width = '100%'; + renderer.domElement.style.height = '100%'; + renderer.domElement.style.zIndex = -1; + renderer.domElement.style.opacity = 1; + + document.body.appendChild(renderer.domElement); + addParticles(); + addLights(); + render(); + } + + const addParticles = () => { + let loader = new THREE.TextureLoader(); + loader.load("/images/smoke.png", (texture) => { + const cloudGeo = new THREE.PlaneBufferGeometry(500,500); + const cloudMaterial = new THREE.MeshLambertMaterial({ + map:texture, + transparent: true + }); + for(let p=0; p<50; p++) { + let cloud = new THREE.Mesh(cloudGeo, cloudMaterial); + cloud.position.set( + Math.random()*800 -400, + 500, + Math.random()*500-500 + ); + cloud.rotation.x = 1.16; + cloud.rotation.y = -0.12; + cloud.rotation.z = Math.random()*2*Math.PI; + cloud.material.opacity = 0.55; + cloudParticles.push(cloud); + scene.add(cloud); + } + }); + } + + const addLights = () => { + let directionalLight = new THREE.DirectionalLight(0xff8c19); + directionalLight.position.set(0,0,1); + scene.add(directionalLight); + + let orangeLight = new THREE.PointLight(0xcc6600,50,450,1.7); + orangeLight.position.set(200,300,100); + scene.add(orangeLight); + let redLight = new THREE.PointLight(0xd8547e,50,450,1.7); + redLight.position.set(100,300,100); + scene.add(redLight); + let blueLight = new THREE.PointLight(0x3677ac,50,450,1.7); + blueLight.position.set(300,300,200); + scene.add(blueLight); + }; + + function render() { + cloudParticles.forEach(p => { + p.rotation.z -=0.001; + }); + renderer.render(scene,camera); + requestAnimationFrame(render); + } + + init(); +}; + +const Background: React.FC<{}> = () => { + useEffect(() => { + setup(); + }, []); + return <> +}; + +export default Background; diff --git a/components/Me.tsx b/components/Me.tsx index be76a73..a194cec 100644 --- a/components/Me.tsx +++ b/components/Me.tsx @@ -3,16 +3,24 @@ import styled from 'styled-components'; const Wrapper = styled.div` display: flex; - display-direction: column; + flex-direction: column; align-items: center; justify-content: center; padding: 40px; `; -const Image = styled.div<{ src: string }>` - border: 30px #efefef solid; - width: 360px; +const ImageWrapper = styled.div` border-radius: 50%; + border: solid 15px rgba(255, 255, 255, .5); + box-shadow: 0 0 15px rgba(0, 0, 0, .5); + overflow: hidden; + margin: 0 40px; + width: 100%; + max-width: 360px; +`; + +const Image = styled.div<{ src: string }>` + width: 100%; background: url('${({ src }) => src}'); background-size: cover; `; @@ -21,11 +29,46 @@ const Spacer = styled.div` padding-bottom: 100%; `; +const Title = styled.h1` + text-transform: uppercase; + color: #fff; + font-size: 28px; + font-family: 'Source Code Pro', monospace; + text-shadow: + 0 0 5px rgba(255, 255, 255, .5); + 0 0 10px rgba(0, 0, 0, .5); + margin-bottom: 0px; +`; + +const SubTitle = styled.h2` + text-transform: uppercase; + color: #fff; + font-size: 14px; + font-family: 'Source Code Pro', monospace; + text-shadow: + 0 0 5px rgba(255, 255, 255, .5); + 0 0 10px rgba(0, 0, 0, .5); +`; + +const Divider = styled.div` + margin-top: 70px; + width: 100%; + max-width: 800px; + height: 1px; + background: rgba(255, 255, 255, .5); + box-shadow: 0 0 30px rgba(255, 255, 255, .7); +`; + const Me: React.FC<{}> = () => ( - - - + + + + + + Morten Olsen + “...One part genius, on part crazy” + ); diff --git a/components/Social.tsx b/components/Social.tsx index 7665aaf..78785d1 100644 --- a/components/Social.tsx +++ b/components/Social.tsx @@ -21,8 +21,8 @@ const Image = styled.div<{ src: string }>` background: url('${({ src }) => src}'); background-size: cover; margin-right: 10px; - filter: grayscale(100%); transition: all .8s; + filter: grayscale(100%) invert(); `; const Wrapper = styled.div` @@ -42,15 +42,19 @@ const ItemWrapper = styled.a` width: 220px; height: 100px; text-decoration: none; - color: #000; + font-weight: bold; + color: #fff; + font-family: 'Source Code Pro', monospace; + text-transform: uppercase; + text-shadow: 0 0 5px rgba(255, 255, 255, .5); &:hover > div { - background: #000; - color: #fff; + background: #fff; + color: #000; box-shadow: 0 0 35px rgba(0, 0, 0, .3); &> div { - filter: grayscale(100%) invert(); + filter: grayscale(100%); } } `; diff --git a/package.json b/package.json index c48acfa..823f0d2 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ "particlesjs": "^2.2.3", "react": "^17.0.2", "react-dom": "^17.0.2", - "styled-components": "^5.3.1" + "styled-components": "^5.3.1", + "three": "^0.131.3" }, "devDependencies": { "@types/react": "^17.0.19", "@types/styled-components": "^5.1.12", + "@types/three": "^0.131.0", "babel-plugin-styled-components": "^1.13.2", "typescript": "^4.3.5" } diff --git a/pages/index.tsx b/pages/index.tsx index 5ed282e..9f9e038 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,40 +1,20 @@ -import React, { useEffect } from 'react'; -import styled from 'styled-components'; +import React from 'react'; import Head from 'next/head'; +import Background from '../components/Background'; import Me from '../components/Me'; import Social from '../components/Social'; -const Canvas = styled.canvas` - position: fixed; - top: 0; - left: 0; - widht: 100%; - height: 100%; - z-index: -1; -`; - const Frontpage: React.FC<{}> = () => { - useEffect(() => { - const run = async () => { - const { default: Particles } = await import('particlesjs'); - Particles.init({ - selector: '.background', - connectParticles: true, - color: '#dddddd', - maxParticles: 200, - }); - console.log(Particles); - }; - run(); - }); - return ( <> Morten Olsen + + + + - @@ -19,4 +19,4 @@ Created with Sketch. - \ No newline at end of file + diff --git a/public/images/logos/stackoverflow.svg b/public/images/logos/stackoverflow.svg index 7a07930..76236f7 100644 --- a/public/images/logos/stackoverflow.svg +++ b/public/images/logos/stackoverflow.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/public/images/smoke.png b/public/images/smoke.png new file mode 100644 index 0000000000000000000000000000000000000000..eb66eec3e317009fc6454de00dd0142d644599ed GIT binary patch literal 10632 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

vN1TnHCzk7?NTWMf)z;}sj=C^e-p*h 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 OTgE5N^~-gs(f