diff --git a/config/webpack.server.common.js b/config/webpack.server.common.js index 0506ddc..9e740ea 100644 --- a/config/webpack.server.common.js +++ b/config/webpack.server.common.js @@ -23,7 +23,7 @@ module.exports = { plugins: [ new EsLint({ extensions: ['.ts', '.tsx'], - context: path.join(__dirname, '../src/client'), + context: path.join(__dirname, '../src/server'), }), ], }; diff --git a/public/css/style.css b/public/css/style.css index 18be001..dbe8880 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -29,9 +29,93 @@ body { width: 25%; } +.tile-child { + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + height: 100%; + width: 100%; +} + +#whoami { + background-color: #1d2021; + color: #ebdbb2; +} + +#git { + background-color: #282828; +} + +#downloadcv { + background-color: #282828; + color: #8ec07c; + border-color: #8ec07c; +} + +#clickme { + background-color: #1d2021; + color: #d3869b; + border-color: #d3869b; +} + #root { padding: 0; margin: 0; height: 100%; width: 100%; +} + +.btn, +.btn:focus, +.btn:active { + outline: none; + box-shadow: none; + background-color: none; +} + +.btn-mine { + border-radius: 0; + white-space: normal; + background-color: #1d2021; + color: #ebdbb2; + border-color: #ebdbb2; + transition: none; +} + +.btn-mine:hover, +.btn-mine:focus, +.btn-mine:active { + background-color: #3c3638; + color: #fbf1c7; + border-color: #fbf1c7; +} + +.btn-clickme, +.btn-clickme:focus { + border-radius: 0; + white-space: normal; + background-color: #1d2021; + color: #ebdbb2; + border-color: #ebdbb2; + transition: none; +} + +.btn-clickme:hover, +.btn-clickme:active { + background-color: #3c3638; + color: #fbf1c7; + border-color: #fbf1c7; + animation: clickme 2s infinite; +} + +@keyframes clickme { + 0% {background-color: #b16286;} + 14.28% {background-color: #458588;} + 28.57% {background-color: #689d6a;} + 42.85% {background-color: #98971a;} + 57.14% {background-color: #d79921;} + 71.42% {background-color: #d65d0e;} + 85.71% {background-color: #cc241d;} + 100% {background-color: #b16286;} } \ No newline at end of file diff --git a/public/images/1.jpg b/public/images/1.jpg new file mode 100755 index 0000000..d02664e Binary files /dev/null and b/public/images/1.jpg differ diff --git a/public/images/10.jpg b/public/images/10.jpg new file mode 100755 index 0000000..4ce0b32 Binary files /dev/null and b/public/images/10.jpg differ diff --git a/public/images/11.jpg b/public/images/11.jpg new file mode 100755 index 0000000..79384bd Binary files /dev/null and b/public/images/11.jpg differ diff --git a/public/images/12.jpg b/public/images/12.jpg new file mode 100755 index 0000000..b9dfa14 Binary files /dev/null and b/public/images/12.jpg differ diff --git a/public/images/2.jpg b/public/images/2.jpg new file mode 100755 index 0000000..24500d0 Binary files /dev/null and b/public/images/2.jpg differ diff --git a/public/images/3.jpg b/public/images/3.jpg new file mode 100755 index 0000000..94cc004 Binary files /dev/null and b/public/images/3.jpg differ diff --git a/public/images/4.jpg b/public/images/4.jpg new file mode 100755 index 0000000..2ea62b9 Binary files /dev/null and b/public/images/4.jpg differ diff --git a/public/images/5.jpg b/public/images/5.jpg new file mode 100755 index 0000000..dcec9bd Binary files /dev/null and b/public/images/5.jpg differ diff --git a/public/images/6.jpg b/public/images/6.jpg new file mode 100755 index 0000000..beead09 Binary files /dev/null and b/public/images/6.jpg differ diff --git a/public/images/7.jpg b/public/images/7.jpg new file mode 100755 index 0000000..9f0368d Binary files /dev/null and b/public/images/7.jpg differ diff --git a/public/images/8.jpg b/public/images/8.jpg new file mode 100755 index 0000000..4d91776 Binary files /dev/null and b/public/images/8.jpg differ diff --git a/public/images/9.jpg b/public/images/9.jpg new file mode 100755 index 0000000..a3493c0 Binary files /dev/null and b/public/images/9.jpg differ diff --git a/public/images/article.jpg b/public/images/article.jpg new file mode 100755 index 0000000..95f399e Binary files /dev/null and b/public/images/article.jpg differ diff --git a/public/images/carte.png b/public/images/carte.png new file mode 100755 index 0000000..c1bd53f Binary files /dev/null and b/public/images/carte.png differ diff --git a/src/client/components/BaseLattice.tsx b/src/client/components/BaseLattice.tsx new file mode 100644 index 0000000..1e35906 --- /dev/null +++ b/src/client/components/BaseLattice.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +// @ts-ignore +import ShadertoyReact from 'shadertoy-react'; +// @ts-ignore +import fs from '../shaders/baseLattice'; + +/** + * @return {jsx} a shader + */ +export default function BaseLattice() { + return ( + + ); +}; diff --git a/src/client/components/ClickMe.tsx b/src/client/components/ClickMe.tsx new file mode 100644 index 0000000..fca6cc9 --- /dev/null +++ b/src/client/components/ClickMe.tsx @@ -0,0 +1,39 @@ +import React, {useState, useEffect} from 'react'; + +interface ClickMeProps { + windowSize: number; + setTrigger: any; +} + +/** + * @return {jsx} a presentation of me + */ +export default function ClickMe({windowSize, setTrigger}: ClickMeProps) { + const [buttonClass, setButtonClass] = useState(''); + + useEffect(() => { + if (window.innerWidth > 1200) { + setButtonClass('btn-lg'); + } else { + setButtonClass(''); + } + }, [windowSize]); + + return ( +
+ +
+
+ ); +}; \ No newline at end of file diff --git a/src/client/components/Collapse.tsx b/src/client/components/Collapse.tsx index d7a3175..129fa89 100644 --- a/src/client/components/Collapse.tsx +++ b/src/client/components/Collapse.tsx @@ -1,14 +1,14 @@ -import React from 'react'; -// @ts-ignore -import ShadertoyReact from 'shadertoy-react'; -// @ts-ignore -import fs from '../shaders/collapse'; - -/** - * @return {jsx} a shader - */ -export default function Collapse() { - return ( - - ); -}; +import React from 'react'; +// @ts-ignore +import ShadertoyReact from 'shadertoy-react'; +// @ts-ignore +import fs from '../shaders/collapse'; + +/** + * @return {jsx} a shader + */ +export default function Collapse() { + return ( + + ); +}; diff --git a/src/client/components/DownloadCV.tsx b/src/client/components/DownloadCV.tsx new file mode 100644 index 0000000..8ce133d --- /dev/null +++ b/src/client/components/DownloadCV.tsx @@ -0,0 +1,37 @@ +import React, {useState, useEffect} from 'react'; + +interface DownloadCVProps { + windowSize: number; +} + +/** + * @return {jsx} a presentation of me + */ +export default function DownloadCV({windowSize}: DownloadCVProps) { + const [buttonClass, setButtonClass] = useState(''); + + useEffect(() => { + if (window.innerWidth > 1200) { + setButtonClass('btn-lg'); + } else { + setButtonClass(''); + } + }, [windowSize]); + + return ( + + ); +}; \ No newline at end of file diff --git a/src/client/components/Git.tsx b/src/client/components/Git.tsx new file mode 100644 index 0000000..3b6ae02 --- /dev/null +++ b/src/client/components/Git.tsx @@ -0,0 +1,45 @@ +import React, {useState, useEffect} from 'react'; + +interface GitProps { + windowSize: number; +} + +/** + * @return {jsx} a presentation of me + */ +export default function Git({windowSize}: GitProps) { + const [topClass, setTopClass] = useState(''); + const [bottomClass, setBottomClass] = useState(''); + + useEffect(() => { + if (window.innerWidth > 1200) { + setTopClass('btn-lg mb-3'); + setBottomClass('btn-lg mt-3'); + } else { + setTopClass('mb-1'); + setBottomClass('mt-1'); + } + }, [windowSize]); + + return ( + + ); +}; diff --git a/src/client/components/Root.tsx b/src/client/components/Root.tsx index a9e4bc6..f1b3573 100644 --- a/src/client/components/Root.tsx +++ b/src/client/components/Root.tsx @@ -1,25 +1,86 @@ -import React from 'react'; +import React, {useState, useEffect, useCallback} from 'react'; import Shader from './Shader'; +import WhoAmI from './WhoAmI'; +import Git from './Git'; +import DownloadCV from './DownloadCV'; +import ClickMe from './ClickMe'; /** * @return {jsx} The root component */ export default function Root() { + const [windowSize, setWindowSize] = useState(0); + const [trigger, setTrigger] = useState(0); + const [content, setContent]: any = useState([]); + const Shaders = [ 'BaseRaymarching', 'Collapse', 'Droplets', 'Inception', - 'Mentstom', + 'Menstom', 'Torus', 'Triangle', + 'BaseLattice', ]; + const handleWindowResize = useCallback((_event) => { + setWindowSize(window.innerWidth); + }, []); + useEffect(() => { + window.addEventListener('resize', handleWindowResize); + return () => { + window.removeEventListener('resize', handleWindowResize); + }; + }, [handleWindowResize]); + + useEffect(() => { + let newContent = []; + let randomContent = []; + let shadersRandom = []; + let imagesRandom = []; + + shadersRandom.push(Math.floor(Math.random() * 8)); + shadersRandom.push(Math.floor(Math.random() * 8)); + 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(
); + newContent.push(
); + newContent.push(
); + newContent.push(
); + setContent(newContent); + }, [trigger]); + + return (
+ {content} + {/*
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
*/}
); } diff --git a/src/client/components/Shader.tsx b/src/client/components/Shader.tsx index f7bf03e..6726617 100644 --- a/src/client/components/Shader.tsx +++ b/src/client/components/Shader.tsx @@ -13,6 +13,8 @@ import Menstom from './Menstom'; import Collapse from './Collapse'; // @ts-ignore import Torus from './Torus'; +// @ts-ignore +import BaseLattice from './BaseLattice'; interface ShaderProps { name: string; @@ -38,6 +40,8 @@ export default function Shader({name}: ShaderProps) { Shader = ; } else if (name == 'Torus') { Shader = ; + } else if (name == 'BaseLattice') { + Shader = ; } return ( diff --git a/src/client/components/Torus.tsx b/src/client/components/Torus.tsx index 75af254..5b2ba4a 100644 --- a/src/client/components/Torus.tsx +++ b/src/client/components/Torus.tsx @@ -1,14 +1,14 @@ -import React from 'react'; -// @ts-ignore -import ShadertoyReact from 'shadertoy-react'; -// @ts-ignore -import fs from '../shaders/torus'; - -/** - * @return {jsx} a shader - */ -export default function Torus() { - return ( - - ); -}; +import React from 'react'; +// @ts-ignore +import ShadertoyReact from 'shadertoy-react'; +// @ts-ignore +import fs from '../shaders/torus'; + +/** + * @return {jsx} a shader + */ +export default function Torus() { + return ( + + ); +}; diff --git a/src/client/components/WhoAmI.tsx b/src/client/components/WhoAmI.tsx new file mode 100644 index 0000000..2dd9153 --- /dev/null +++ b/src/client/components/WhoAmI.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +/** + * @return {jsx} a presentation of me + */ +export default function WhoAmI() { + return ( +
+
Gaƫtan Brochard
+
Developer
+
+ ); +}; diff --git a/src/client/shaders/baseLattice.js b/src/client/shaders/baseLattice.js new file mode 100644 index 0000000..6b2bb54 --- /dev/null +++ b/src/client/shaders/baseLattice.js @@ -0,0 +1,106 @@ +export default `#define MAX_STEPS 1000 +#define MAX_DIST 500. +#define E 0.000001 + +float sdCapsule(vec3 p, vec3 a, vec3 b, float r) +{ + vec3 ab = b - a; + vec3 ap = p - a; + + float t = dot(ab, ap) / dot(ab, ab); + t = clamp(t, 0., 1.); + + vec3 c = a + t * ab; + return length(p - c) - r; +} + +float sdTorus(vec3 p, vec2 r) +{ + float x = length(p.xz) - r.x; + return length(vec2(x, p.y)) - r.y; +} + +float sdBox(vec3 p, vec3 s) +{ + return length(max(abs(p) - s, 0.)); +} + +float GetDist(vec3 p) +{ + vec4 s = vec4(0, 0, 0, 2); + + p.x += iTime; + float s_dist = (length(mod(p, 10.) - s.xyz) - s.w); + + float b_dist1 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(0., sin(p.x * 0.2) * 2., sin(p.x * 0.2) * 2.), vec3(10., 0.5, 0.5)) * 0.3; + float b_dist2 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.y * 0.2) * 2., 0., sin(p.y * 0.2) * 2.), vec3(0.5, 10., 0.5)) * 0.3; + float b_dist3 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.z * 0.2) * 2., sin(p.z * 0.2) * 2., 0.), vec3(0.5, 0.5, 10.)) * 0.3; + + float d = min(b_dist1, b_dist2); + d = min(d, b_dist3); + return d; +} + +float RayMarch(vec3 ro, vec3 rd) { + float dO = 0.; + + for (int i = 0; i < MAX_STEPS; i++) + { + vec3 p = ro + rd * dO; + float dS = GetDist(p); + dO += dS; + if (dO > MAX_DIST || dS < E) + break; + } + + return dO; +} + +vec3 GetNormal(vec3 p) +{ + float d = GetDist(p); + vec2 e = vec2(0.3, 0); + + vec3 n = d - vec3( + GetDist(p - e.xyy), + GetDist(p - e.yxy), + GetDist(p - e.yyx)); + return (normalize(n)); +} + +float GetLight(vec3 p) +{ + vec3 lightPos = vec3(0, 10, iTime* 3.); + lightPos.xz += vec2(sin(iTime), cos(iTime)) * 5.; + vec3 l = normalize(lightPos - p); + vec3 n = GetNormal(p); + + float dif = clamp(dot(l, n), 0., 1.); + //float d = RayMarch(p+n*E * 30., l); + //if (d < length(lightPos - p)) + // dif *= 0.1; + return (dif); +} + +vec2 rotate(vec2 p, float theta) +{ + return vec2(cos(p.x) - sin(p.y), sin(p.x) + cos(p.y)); +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = ((fragCoord - .5 * iResolution.xy) / iResolution.y); + + vec3 up = normalize(vec3(cos(iTime), sin(iTime), 0)); + vec3 ro = vec3(5. + cos(iTime), 5. + sin(iTime), iTime* 3.); + vec3 rd = normalize(vec3(uv.x + 1., uv.y + 1., 1 + 1)); + + float d = RayMarch(ro, rd); + + vec3 p = ro + rd * d; + + float dif = GetLight(p); + vec3 col = vec3(abs(mod((p.x + sin(iTime))/ 10., 1.) - 0.5) * dif, abs(mod((p.y + sin(iTime)) / 10., 1.) - 0.5) * dif, abs(mod((p.z + sin(iTime)) / 10., 1.) - 0.5) * dif); + //col = myvec; + fragColor = vec4(col,1.0); +}`; diff --git a/src/client/shaders/inception.js b/src/client/shaders/inception.js index 6b2bb54..5a11e6b 100644 --- a/src/client/shaders/inception.js +++ b/src/client/shaders/inception.js @@ -1,106 +1,144 @@ -export default `#define MAX_STEPS 1000 -#define MAX_DIST 500. -#define E 0.000001 +export default ` +#define MAX_STEPS 1280 +#define MAX_DIST 128. +#define E 0.0001 +#define PI 3.141592 -float sdCapsule(vec3 p, vec3 a, vec3 b, float r) +vec3 rotX(vec3 v, float a) { - vec3 ab = b - a; - vec3 ap = p - a; - - float t = dot(ab, ap) / dot(ab, ab); - t = clamp(t, 0., 1.); - - vec3 c = a + t * ab; - return length(p - c) - r; + return vec3(v.x, v.y * cos(a) - v.z * sin(a), v.y * sin(a) + v.z * cos(a)); } -float sdTorus(vec3 p, vec2 r) +vec3 rotY(vec3 v, float a) +{ + return vec3(v.x * cos(a) + v.z * sin(a), v.y, v.z * cos(a) - v.x * sin(a)); +} + +vec3 rotZ(vec3 v, float a) +{ + return vec3(v.x * cos(a) - v.y * sin(a), v.x * sin(a) + v.y * cos(a), v.z); +} + +vec3 modSDF(vec3 p, vec3 c) +{ + return mod(p + 0.5 * c, c) - 0.5 * c; +} + +float sdfTorus(vec3 p, vec2 r) { float x = length(p.xz) - r.x; return length(vec2(x, p.y)) - r.y; } -float sdBox(vec3 p, vec3 s) + +// blackbody by aiekick : https://www.shadertoy.com/view/lttXDn + +// -------------blackbody----------------- // + +// return color from temperature +//http://www.physics.sfasu.edu/astro/color/blackbody.html +//http://www.vendian.org/mncharity/dir3/blackbody/ +//http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html + +vec3 blackbody(float Temp) { - return length(max(abs(p) - s, 0.)); + vec3 col = vec3(255.); + col.x = 56100000. * pow(Temp,(-3. / 2.)) + 148.; + col.y = 100.04 * log(Temp) - 623.6; + if (Temp > 6500.) col.y = 35200000. * pow(Temp,(-3. / 2.)) + 184.; + col.z = 194.18 * log(Temp) - 1448.6; + col = clamp(col, 0., 255.)/255.; + if (Temp < 1000.) col *= Temp/1000.; + return col; } -float GetDist(vec3 p) +// -------------blackbody----------------- // + + +float scene(vec3 p) { - vec4 s = vec4(0, 0, 0, 2); - - p.x += iTime; - float s_dist = (length(mod(p, 10.) - s.xyz) - s.w); - - float b_dist1 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(0., sin(p.x * 0.2) * 2., sin(p.x * 0.2) * 2.), vec3(10., 0.5, 0.5)) * 0.3; - float b_dist2 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.y * 0.2) * 2., 0., sin(p.y * 0.2) * 2.), vec3(0.5, 10., 0.5)) * 0.3; - float b_dist3 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.z * 0.2) * 2., sin(p.z * 0.2) * 2., 0.), vec3(0.5, 0.5, 10.)) * 0.3; - - float d = min(b_dist1, b_dist2); - d = min(d, b_dist3); + float td1 = sdfTorus( + modSDF( + rotX( + p - vec3(3. + cos(p.x * 10. + iTime) / 3., sin(p.y * 10. + iTime) / 3., 6.), + PI / 2.), + vec3(6.)), vec2(2., abs(sin(iTime)) * 0.2 + 0.1)) * 0.1; + float td2 = sdfTorus( + modSDF( + rotZ( + rotX( + p - vec3(3. + cos(p.x * 10. + iTime) / 3., -3. + sin(p.y * 10. + iTime) / 3., 6.), PI / 2.), PI / 2.), vec3(6.)), vec2(2., abs(cos(iTime)) * 0.2 + 0.1))* 0.1; + float td3 = sdfTorus( + modSDF( + rotZ( + p - vec3(cos(p.x * 10. + iTime) / 3., sin(p.y * 10. + iTime) / 3., 3.), PI / 2.), vec3(6.)), vec2(2., abs(sin(iTime)) * 0.2 + 0.1))* 0.1; + float td4 = sdfTorus(modSDF(p + vec3(cos(p.x * 10. + iTime) / 3., sin(p.y * 10. + iTime) / 3., -6.), vec3(6.)), vec2(2., abs(cos(iTime)) * 0.2 + 0.1))* 0.1; + //float td2 = 10000.; + float d = min(td1, td2); + d = min(d, td3); + d = min(d, td4); return d; } -float RayMarch(vec3 ro, vec3 rd) { +float march(vec3 ro, vec3 rd) +{ float dO = 0.; - - for (int i = 0; i < MAX_STEPS; i++) + + for (int steps = 0; steps < MAX_STEPS; steps++) { vec3 p = ro + rd * dO; - float dS = GetDist(p); + float dS = scene(p); dO += dS; - if (dO > MAX_DIST || dS < E) - break; + if (dS < E || dO > MAX_DIST) + break; } - return dO; } -vec3 GetNormal(vec3 p) +vec3 normal(vec3 p) { - float d = GetDist(p); + float d = scene(p); vec2 e = vec2(0.3, 0); - + vec3 n = d - vec3( - GetDist(p - e.xyy), - GetDist(p - e.yxy), - GetDist(p - e.yyx)); + scene(p - e.xyy), + scene(p - e.yxy), + scene(p - e.yyx)); return (normalize(n)); } -float GetLight(vec3 p) +float light(vec3 p) { - vec3 lightPos = vec3(0, 10, iTime* 3.); - lightPos.xz += vec2(sin(iTime), cos(iTime)) * 5.; + vec3 lightPos = vec3(0., 0., 0.); vec3 l = normalize(lightPos - p); - vec3 n = GetNormal(p); - - float dif = clamp(dot(l, n), 0., 1.); - //float d = RayMarch(p+n*E * 30., l); - //if (d < length(lightPos - p)) - // dif *= 0.1; - return (dif); -} + vec3 n = normal(p); -vec2 rotate(vec2 p, float theta) -{ - return vec2(cos(p.x) - sin(p.y), sin(p.x) + cos(p.y)); + float dif = clamp(dot(l, n), 0., 1.); +// float d = march(p+n*E * 30., l); +// if (d < length(lightPos - p)) +// dif *= 0.1; + return (dif); } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = ((fragCoord - .5 * iResolution.xy) / iResolution.y); - - vec3 up = normalize(vec3(cos(iTime), sin(iTime), 0)); - vec3 ro = vec3(5. + cos(iTime), 5. + sin(iTime), iTime* 3.); - vec3 rd = normalize(vec3(uv.x + 1., uv.y + 1., 1 + 1)); - - float d = RayMarch(ro, rd); - + + vec3 ro = vec3(7., 7., iTime); + vec3 rd = normalize(vec3(uv.x, uv.y, 1)); + rd = rotX(rd, iTime * 0.256); + rd = rotY(rd, iTime * 0.314); + rd = rotZ(rd, iTime * 0.1618); + //rd = rotX(rd, PI / 2.); + + float d = march(ro, rd); + vec3 p = ro + rd * d; - - float dif = GetLight(p); - vec3 col = vec3(abs(mod((p.x + sin(iTime))/ 10., 1.) - 0.5) * dif, abs(mod((p.y + sin(iTime)) / 10., 1.) - 0.5) * dif, abs(mod((p.z + sin(iTime)) / 10., 1.) - 0.5) * dif); - //col = myvec; - fragColor = vec4(col,1.0); -}`; + float dif = light(p); + vec3 col = vec3(dif); + col = blackbody(d * 10.); + col += vec3(abs(mod((p.x + sin(iTime))/ 10., 1.) - 0.5) * dif, abs(mod((p.y + sin(iTime)) / 10., 1.) - 0.5) * dif, abs(mod((p.z + sin(iTime)) / 10., 1.) - 0.5) * dif); + // Output to screen + col = pow(col, vec3(0.454545)); + fragColor = vec4(col, 1.0); +}` \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 9066470..ab7644a 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -6,6 +6,7 @@ Web-Expo +