diff --git a/nodemon.json b/nodemon.json deleted file mode 100644 index 6624c2c..0000000 --- a/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": ["src/server"], - "ext": "ts,json", - "ignore": ["src/**/*.spec.ts"], - "exec": "ts-node ./src/server/main.ts" - } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7a0f18f..3f1a120 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1292,6 +1292,12 @@ "@types/range-parser": "*" } }, + "@types/howler": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/howler/-/howler-2.2.1.tgz", + "integrity": "sha512-1MiSldngr+eAO4lDPtjzl4Nf2GmRh8VDHIpNBIkyd25L22JExVlI6w3fjSM7+FNc1e1WZAPNq7/flkw685byfg==", + "dev": true + }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", @@ -1347,6 +1353,16 @@ "@types/react": "*" } }, + "@types/react-howler": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@types/react-howler/-/react-howler-3.7.2.tgz", + "integrity": "sha512-2R2nypBTD8L1vHL7Sz5Pn7L5I0v5+UIp5y4ZnZ3r7uggqghVf1DLo/pJ9e7g2A+PWq/xZJXvzrF9ZQSdwrQyEQ==", + "dev": true, + "requires": { + "@types/howler": "*", + "@types/react": "*" + } + }, "@types/serve-static": { "version": "1.13.8", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz", @@ -3327,6 +3343,11 @@ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, + "howler": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/howler/-/howler-2.2.1.tgz", + "integrity": "sha512-0iIXvuBO/81CcrQ/HSSweYmbT50fT2mIc9XMFb+kxIfk2pW/iKzDbX1n3fZmDXMEIpYvyyfrB+gXwPYSDqUxIQ==" + }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -4331,7 +4352,6 @@ "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -4447,11 +4467,19 @@ "scheduler": "^0.20.1" } }, + "react-howler": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-howler/-/react-howler-5.0.0.tgz", + "integrity": "sha512-0JJapjFv0rd7sAZ9l9TuKVN2m4aRN3/yQYzRKQpaoK0FXldzM6LuP2XN/QetlubAqHF5F3wrk29QF0gngj+gRQ==", + "requires": { + "howler": "^2.2.0", + "prop-types": "^15.5.6" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "read-pkg": { "version": "4.0.1", diff --git a/package.json b/package.json index 0e71410..1e4ca8e 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "dev:client:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput --pretty --project config/tsconfig.client.json", "dev:client:js": "webpack --config config/webpack.client.dev.js", "dev:client": "concurrently \"npm:dev:client:types\" \"npm:dev:client:js\"", - "dev:start": "mkdir -p dev/server && touch dev/server/bundle.js && nodemon dev/server/bundle.js", + "dev:start": "mkdir -p dist/server && touch dist/server/bundle.js && nodemon dist/server/bundle.js", "dev": "rm -rf dist && concurrently \"npm:dev:server\" \"npm:dev:client\" \"npm:dev:start\"", "start": "node dist/server/bundle.js" }, @@ -43,6 +43,7 @@ "@types/express": "^4.17.9", "@types/react": "^16.14.0", "@types/react-dom": "^16.9.9", + "@types/react-howler": "^3.7.2", "@typescript-eslint/eslint-plugin": "^4.8.1", "@typescript-eslint/parser": "^4.8.1", "babel-loader": "^8.2.1", @@ -52,6 +53,7 @@ "eslint-config-google": "^0.14.0", "eslint-plugin-react": "^7.21.5", "eslint-webpack-plugin": "^2.4.0", + "howler": "^2.2.1", "nodemon": "^2.0.6", "ts-node": "^9.0.0", "typescript": "^4.1.2", @@ -65,6 +67,7 @@ "express": "^4.17.1", "react": "^17.0.1", "react-dom": "^17.0.1", + "react-howler": "^5.0.0", "shadertoy-react": "^1.1.1" } } diff --git a/public/css/style.css b/public/css/style.css index dbe8880..a4da24b 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -13,6 +13,11 @@ body { overflow: hidden; } +img { + width: 100%; + height: auto; +} + .shader { padding: 0; margin: 0; @@ -21,6 +26,7 @@ body { } .tile { + background-color: #000000; display: inline-block; vertical-align: top; padding: 0; @@ -38,6 +44,28 @@ body { width: 100%; } +.tile-player { + animation: player 2s infinite; +} + +.player-text { + color: #ebdbb2; +} + +.loader { + border: 12px solid #ebdbb2; + border-top: 12px solid #458588; + border-radius: 50%; + height: 120px; + width: 120px; + animation: spin 2s linear infinite; +} + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + #whoami { background-color: #1d2021; color: #ebdbb2; @@ -118,4 +146,15 @@ body { 71.42% {background-color: #d65d0e;} 85.71% {background-color: #cc241d;} 100% {background-color: #b16286;} +} + +@keyframes player { + 0% {background-color: #b1628633;} + 14.28% {background-color: #45858833;} + 28.57% {background-color: #689d6a33;} + 42.85% {background-color: #98971a33;} + 57.14% {background-color: #d7992133;} + 71.42% {background-color: #d65d0e33;} + 85.71% {background-color: #cc241d33;} + 100% {background-color: #b1628633;} } \ No newline at end of file diff --git a/public/images/1.jpg b/public/images/1.jpg index d02664e..2c3d8c9 100755 Binary files a/public/images/1.jpg and b/public/images/1.jpg differ diff --git a/public/images/10.jpg b/public/images/10.jpg index 4ce0b32..a417815 100755 Binary files a/public/images/10.jpg and b/public/images/10.jpg differ diff --git a/public/images/11.jpg b/public/images/11.jpg index 79384bd..237c2a8 100755 Binary files a/public/images/11.jpg and b/public/images/11.jpg differ diff --git a/public/images/12.jpg b/public/images/12.jpg index b9dfa14..995876f 100755 Binary files a/public/images/12.jpg and b/public/images/12.jpg differ diff --git a/public/images/2.jpg b/public/images/2.jpg index 24500d0..1816f6c 100755 Binary files a/public/images/2.jpg and b/public/images/2.jpg differ diff --git a/public/images/3.jpg b/public/images/3.jpg index 94cc004..ec61df3 100755 Binary files a/public/images/3.jpg and b/public/images/3.jpg differ diff --git a/public/images/4.jpg b/public/images/4.jpg index 2ea62b9..7b98610 100755 Binary files a/public/images/4.jpg and b/public/images/4.jpg differ diff --git a/public/images/5.jpg b/public/images/5.jpg index dcec9bd..5fec5da 100755 Binary files a/public/images/5.jpg and b/public/images/5.jpg differ diff --git a/public/images/6.jpg b/public/images/6.jpg index beead09..f578a3c 100755 Binary files a/public/images/6.jpg and b/public/images/6.jpg differ diff --git a/public/images/7.jpg b/public/images/7.jpg index 9f0368d..e478c09 100755 Binary files a/public/images/7.jpg and b/public/images/7.jpg differ diff --git a/public/images/8.jpg b/public/images/8.jpg index 4d91776..5f9c723 100755 Binary files a/public/images/8.jpg and b/public/images/8.jpg differ diff --git a/public/images/9.jpg b/public/images/9.jpg index a3493c0..3d94157 100755 Binary files a/public/images/9.jpg and b/public/images/9.jpg differ diff --git a/public/images/article.jpg b/public/images/article.jpg deleted file mode 100755 index 95f399e..0000000 Binary files a/public/images/article.jpg and /dev/null differ diff --git a/public/images/carte.png b/public/images/carte.png deleted file mode 100755 index c1bd53f..0000000 Binary files a/public/images/carte.png and /dev/null differ diff --git a/src/client/components/ClickMe.tsx b/src/client/components/ClickMe.tsx index fca6cc9..f6aae4c 100644 --- a/src/client/components/ClickMe.tsx +++ b/src/client/components/ClickMe.tsx @@ -3,12 +3,13 @@ import React, {useState, useEffect} from 'react'; interface ClickMeProps { windowSize: number; setTrigger: any; + setBusy: any; } /** * @return {jsx} a presentation of me */ -export default function ClickMe({windowSize, setTrigger}: ClickMeProps) { +export default function ClickMe({windowSize, setTrigger, setBusy}: ClickMeProps) { const [buttonClass, setButtonClass] = useState(''); useEffect(() => { @@ -29,11 +30,13 @@ export default function ClickMe({windowSize, setTrigger}: ClickMeProps) { id='clickme'> -
); -}; \ No newline at end of file +}; diff --git a/src/client/components/DownloadCV.tsx b/src/client/components/DownloadCV.tsx index 8ce133d..51dc15a 100644 --- a/src/client/components/DownloadCV.tsx +++ b/src/client/components/DownloadCV.tsx @@ -27,11 +27,13 @@ export default function DownloadCV({windowSize}: DownloadCVProps) { justify-content-center' id='downloadcv'> Download my CV -
); -}; \ No newline at end of file +}; diff --git a/src/client/components/Player.tsx b/src/client/components/Player.tsx new file mode 100644 index 0000000..06b7064 --- /dev/null +++ b/src/client/components/Player.tsx @@ -0,0 +1,46 @@ +import React, {useState} from 'react'; +import ReactHowler from 'react-howler'; + +interface PlayerProps { + src: string; +} + +/** + * @return {jsx} The root component + */ +export default function Player({src}: PlayerProps) { + const [play, setPlay] = useState(false); + const [playText, setPlayText] = useState('Play'); + + function handlePlay() { + setPlay(!play); + if (play) { + setPlayText('Play'); + } else { + setPlayText('Pause'); + } + } + + return ( + + +
+
{src.split('/')[3].split('.')[0]}
+ +
+
+ ); +} diff --git a/src/client/components/Root.tsx b/src/client/components/Root.tsx index f1b3573..5412235 100644 --- a/src/client/components/Root.tsx +++ b/src/client/components/Root.tsx @@ -4,6 +4,7 @@ import WhoAmI from './WhoAmI'; import Git from './Git'; import DownloadCV from './DownloadCV'; import ClickMe from './ClickMe'; +import Player from './Player'; /** * @return {jsx} The root component @@ -12,7 +13,67 @@ export default function Root() { const [windowSize, setWindowSize] = useState(0); const [trigger, setTrigger] = useState(0); const [content, setContent]: any = useState([]); - + const [busy, setBusy]: any = useState(true); + const loader: Array = []; + + for (let i = 0; i < 5; i++) { + loader.push( +
+
+
+
+
); + } + loader.push(
); + loader.push( +
+ +
); + for (let i = 0; i < 2; i++) { + loader.push( +
+
+
+
+
); + } + loader.push( +
+ +
); + loader.push( +
+ +
); + for (let i = 0; i < 5; i++) { + loader.push( +
+
+
+
+
); + } const Shaders = [ 'BaseRaymarching', 'Collapse', @@ -24,6 +85,16 @@ export default function Root() { 'BaseLattice', ]; + const Sounds = [ + 'Collapse.mp3', + 'Droplets.mp3', + 'Heavy Ropes.mp3', + 'Inception.mp3', + 'Menstom.mp3', + 'Speechless.mp3', + 'Triangle.mp3', + ]; + const handleWindowResize = useCallback((_event) => { setWindowSize(window.innerWidth); }, []); @@ -35,52 +106,127 @@ export default function Root() { }, [handleWindowResize]); useEffect(() => { - let newContent = []; - let randomContent = []; - let shadersRandom = []; - let imagesRandom = []; + const newContent = []; + const randomContent = []; + const shadersRandom: Array = []; + const imagesRandom: Array = []; + const soundsRandom: Array = []; - shadersRandom.push(Math.floor(Math.random() * 8)); - shadersRandom.push(Math.floor(Math.random() * 8)); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); + for (let i = 0; i < 3; i++) { + shadersRandom.push(Math.floor(Math.random() * 8)); + while (shadersRandom.indexOf( + shadersRandom[shadersRandom.length - 1]) != + shadersRandom.length - 1) { + shadersRandom[shadersRandom.length - 1] += 1; + if (shadersRandom[shadersRandom.length - 1] == 8) { + shadersRandom[shadersRandom.length - 1] = 1; + } + } + } + for (let i = 0; i < 3; i++) { + shadersRandom[i] = +
+ +
; + } + + for (let i = 0; i < 7; i++) { + imagesRandom.push(Math.floor(Math.random() * 12) + 1); + while (imagesRandom.indexOf( + imagesRandom[imagesRandom.length - 1]) != + imagesRandom.length - 1) { + imagesRandom[imagesRandom.length - 1] += 1; + if (imagesRandom[imagesRandom.length - 1] == 13) { + imagesRandom[imagesRandom.length - 1] = 1; + } + } + } + for (let i = 0; i < 7; i++) { + imagesRandom[i] = +
+ + +
; + } + + for (let i = 0; i < 2; i++) { + soundsRandom.push(Math.floor(Math.random() * 7)); + } + if (soundsRandom[0] == soundsRandom[1]) { + soundsRandom[1] += 1; + if (soundsRandom[1] == 7) { + soundsRandom[1] = 0; + } + } + soundsRandom[0] = Sounds[soundsRandom[0]]; + soundsRandom[1] = Sounds[soundsRandom[1]]; + for (let i = 0; i < soundsRandom.length; i++) { + soundsRandom[i] = +
+ +
; + } + + while (shadersRandom.length || + imagesRandom.length || + soundsRandom.length) { + const random = Math.floor(Math.random() * 4); + if (random == 0) { + if (shadersRandom.length > 0) { + randomContent.push(shadersRandom[0]); + shadersRandom.shift(); + } + } else if (random == 1) { + if (soundsRandom.length > 0) { + randomContent.push(soundsRandom[0]); + soundsRandom.shift(); + } + } else { + if (imagesRandom.length > 0) { + randomContent.push(imagesRandom[0]); + imagesRandom.shift(); + } + } + } + newContent.push(randomContent[0]); + newContent.push(randomContent[1]); + newContent.push(randomContent[2]); + newContent.push(randomContent[3]); + newContent.push(randomContent[4]); newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); - newContent.push(
); + newContent.push( +
+ +
); + newContent.push(randomContent[5]); + newContent.push(randomContent[6]); + newContent.push( +
+ +
); + newContent.push( +
+ +
); + newContent.push(randomContent[7]); + newContent.push(randomContent[8]); + newContent.push(randomContent[9]); + newContent.push(randomContent[10]); + newContent.push(randomContent[11]); setContent(newContent); + setBusy(false); }, [trigger]); return (
- {content} - {/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
*/} + {busy ? loader : content}
); } diff --git a/src/server/main.ts b/src/server/main.ts index 3025fcb..4c7ff25 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -3,13 +3,13 @@ import path from 'path'; const app = express(); -app.set('view engine', 'ejs') +app.set('view engine', 'ejs'); app.use('/static', express.static(path.join(__dirname, '../../public'))); app.use('/js', express.static(path.join(__dirname, '../../dist/client'))); app.get('/', (_req, res) => { res.render('index'); -}) +}); -app.listen(3000); \ No newline at end of file +app.listen(3000); diff --git a/tsconfig.json b/tsconfig.json index c79ead9..0a1329b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,8 +16,6 @@ "node_modules", "config", "views", - "build", - "dev", "dist" ] }