diff --git a/package.json b/package.json index 95c846a6..ca46c2e2 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@giscus/react": "2.2.8", "@lottiefiles/lottie-player": "2.0.2", "@sendgrid/mail": "7.7.0", + "cobe": "^0.6.3", "cookies-next": "2.1.2", "dayjs": "1.11.8", "formik": "2.4.2", @@ -48,6 +49,7 @@ "react-dom": "18.2.0", "react-fast-marquee": "1.6.0", "react-lottie-player": "1.5.4", + "react-spring": "^9.7.1", "react-toastify": "9.1.3", "rehype-document": "6.1.0", "rehype-external-links": "2.1.0", diff --git a/src/components/home/cobe.jsx b/src/components/home/cobe.jsx new file mode 100644 index 00000000..e6dea22f --- /dev/null +++ b/src/components/home/cobe.jsx @@ -0,0 +1,143 @@ +import createGlobe from 'cobe'; +import { useEffect, useRef } from 'react'; +import { useSpring } from 'react-spring'; + +export default function Cobe() { + let phi = 0; + + const canvasRef = useRef(null); + + const pointerInteracting = useRef(null); + const pointerInteractionMovement = useRef(0); + + const genrateRandomMarkers = () => { + const markers = []; + + for (let i = 0; i < 10000; i++) { + markers.push({ + location: [Math.random() * 180 - 90, Math.random() * 360 - 180], + size: Math.random() * 0.1, + }); + } + + return markers; + }; + + const randomMarkers = genrateRandomMarkers(); + + const [{ r }, api] = useSpring(() => ({ + r: 0, + config: { + mass: 1, + tension: 280, + friction: 40, + precision: 0.001, + }, + })); + + useEffect(() => { + let width = 0; + + const onResize = () => { + canvasRef.current && (width = canvasRef.current.offsetWidth); + }; + + window.addEventListener(`resize`, onResize); + + onResize(); + + const globe = createGlobe(canvasRef.current, { + devicePixelRatio: 2, + width: width * 2, + height: width * 2 * 0, + phi: 0, + theta: 0.1, + dark: 0, + diffuse: 1, + mapSamples: 16000, + mapBrightness: 5, + baseColor: [1, 1, 1], + markerColor: [205 / 255, 50 / 255, 159 / 255], + glowColor: [1.0, 1.0, 1.0], + + markers: randomMarkers, + + scale: width > 800 ? 2.0 : 1.2, + offset: [0, width * 2 * 0.2 * 0.3], + + onRender: (state) => { + state.width = width * 2; + state.height = width * 2 * 0.4; + + state.phi = r.get() * 0.5 + phi; + // eslint-disable-next-line react-hooks/exhaustive-deps + phi += 0.001; + }, + }); + setTimeout(() => (canvasRef.current.style.opacity = `1`)); + + return () => globe.destroy(); + }, []); + + return ( +
+ { + pointerInteracting.current = + e.clientX - pointerInteractionMovement.current; + + canvasRef.current.style.cursor = `grabbing`; + }} + onPointerUp={() => { + pointerInteracting.current = null; + + canvasRef.current.style.cursor = `grab`; + }} + onPointerOut={() => { + pointerInteracting.current = null; + + canvasRef.current.style.cursor = `grab`; + }} + onMouseMove={(e) => { + if (pointerInteracting.current !== null) { + const delta = e.clientX - pointerInteracting.current; + + pointerInteractionMovement.current = delta; + + api.start({ + r: delta / 200, + }); + } + }} + onTouchMove={(e) => { + if (pointerInteracting.current !== null && e.touches[0]) { + const delta = e.touches[0].clientX - pointerInteracting.current; + + pointerInteractionMovement.current = delta; + + api.start({ + r: delta / 100, + }); + } + }} + style={{ + width: `100%`, + height: `100%`, + cursor: `grab`, + contain: `layout paint size`, + opacity: 0, + transition: `opacity 1s ease`, + }} + /> +
+ ); +} diff --git a/src/components/home/collaborators.tsx b/src/components/home/collaborators.tsx index 91576bb6..9d84d73e 100644 --- a/src/components/home/collaborators.tsx +++ b/src/components/home/collaborators.tsx @@ -1,6 +1,8 @@ import Image from 'next/image'; import Marquee from 'react-fast-marquee'; +import Cobe from '@/components/home/cobe'; + export default function Collaborators() { const logoImages = [ { @@ -36,39 +38,50 @@ export default function Collaborators() { ]; return ( -
-
+
+

Where do our tools make a difference?

-
- - {logoImages.map((logo, index) => ( - {logo.alt} - ))} - + +
+ +
+ +
+
+ + {logoImages.map((logo, index) => ( +
+ {logo.alt} +
+ ))} +
+
- - Disclaimer: All logos are used with adequate permissions. Opinions, - interpretations, conclusions and recommendations are those of the FAIR - Data Innovations Hub and are not necessarily endorsed by the other - organizations mentioned on this website. -
+ + Disclaimer: All logos are used with adequate permissions. Opinions, + interpretations, conclusions and recommendations are those of the FAIR + Data Innovations Hub and are not necessarily endorsed by the other + organizations mentioned on this website. +
); } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index a76ff385..da4d19f0 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -59,7 +59,7 @@ export default function Home() {
-
+
diff --git a/src/styles/global.css b/src/styles/global.css index 572d0974..68f98986 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -44,6 +44,10 @@ transform-origin: bottom left; } + .logo-overlay { + background: linear-gradient(0deg, white, white 80%, transparent); + } + .nav-item { @apply relative mx-1 cursor-pointer py-2 sm:px-1 lg:px-3; } diff --git a/tsconfig.json b/tsconfig.json index 7aab398a..47f2f880 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,5 +28,5 @@ "**/*.tsx", "src/components/layout/layout.js", "src/pages/blog/blog.jsx" - ] +, "src/components/home/cobe.jsx" ] } diff --git a/yarn.lock b/yarn.lock index 1a01422c..7f6143ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -899,6 +899,92 @@ "@pnpm/network.ca-file" "^1.0.1" config-chain "^1.1.11" +"@react-spring/animated@~9.7.2": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.2.tgz#0119db8075e91d693ec45c42575541e01b104a70" + integrity sha512-ipvleJ99ipqlnHkz5qhSsgf/ny5aW0ZG8Q+/2Oj9cI7LCc7COdnrSO6V/v8MAX3JOoQNzfz6dye2s5Pt5jGaIA== + dependencies: + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/core@~9.7.1", "@react-spring/core@~9.7.2": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.2.tgz#804ebadee45a6adff00886454d6f1c5d97ee219d" + integrity sha512-fF512edZT/gKVCA90ZRxfw1DmELeVwiL4OC2J6bMUlNr707C0h4QRoec6DjzG27uLX2MvS1CEatf9KRjwZR9/w== + dependencies: + "@react-spring/animated" "~9.7.2" + "@react-spring/rafz" "~9.7.2" + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/konva@~9.7.1": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/konva/-/konva-9.7.2.tgz#58ebae0d24b8887a24d2d6ed0e9dd08842632aa7" + integrity sha512-xMA0XkIyv02euso8BGlLA4iXVJ76p6WCjABMTjdvcp//KvIub596vLwoLzmqHYjqRhH7BP4UQKxzhHvM7AylQA== + dependencies: + "@react-spring/animated" "~9.7.2" + "@react-spring/core" "~9.7.2" + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/native@~9.7.1": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/native/-/native-9.7.2.tgz#dcf5cae844ec8693fa893f7fc3a15420523c2129" + integrity sha512-Ltq/F+4jY7aqHW1/f1xUb+e3XGbVxnllXfDYU+3nXi4sa7O+du755hpNbCHJ5ZgtkQYFKtQ7I+InTY+CDXPYfw== + dependencies: + "@react-spring/animated" "~9.7.2" + "@react-spring/core" "~9.7.2" + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/rafz@~9.7.2": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.2.tgz#77e7088c215e05cf893851cd87ceb40d89f2a7d7" + integrity sha512-kDWMYDQto3+flkrX3vy6DU/l9pxQ4TVW91DglQEc11iDc7shF4+WVDRJvOVLX+xoMP7zyag1dMvlIgvQ+dvA/A== + +"@react-spring/shared@~9.7.2": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.2.tgz#b8485617bdcc9f6348b245922051fb534e07c566" + integrity sha512-6U9qkno+9DxlH5nSltnPs+kU6tYKf0bPLURX2te13aGel8YqgcpFYp5Av8DcN2x3sukinAsmzHUS/FRsdZMMBA== + dependencies: + "@react-spring/rafz" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/three@~9.7.1": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/three/-/three-9.7.2.tgz#2dd23e6e654fc57589cf6f89d6a809bc7f8a96b1" + integrity sha512-u7VAjc+az82PM+WOC2sTbZQLBixuN+0jX/oahzyjEnIds5eUJgaBqZRYAAEMupuzGGl8H3QqL3bFgBEQLq6ADQ== + dependencies: + "@react-spring/animated" "~9.7.2" + "@react-spring/core" "~9.7.2" + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/types@~9.7.2": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.2.tgz#e04dd72755d88b0e3163ba143ecd8ba78b68a5b0" + integrity sha512-GEflx2Ex/TKVMHq5g5MxQDNNPNhqg+4Db9m7+vGTm8ttZiyga7YQUF24shgRNebKIjahqCuei16SZga8h1pe4g== + +"@react-spring/web@~9.7.1": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.7.2.tgz#76e53dd24033764c3062f9927f88b0f3194688d4" + integrity sha512-7qNc7/5KShu2D05x7o2Ols2nUE7mCKfKLaY2Ix70xPMfTle1sZisoQMBFgV9w/fSLZlHZHV9P0uWJqEXQnbV4Q== + dependencies: + "@react-spring/animated" "~9.7.2" + "@react-spring/core" "~9.7.2" + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + +"@react-spring/zdog@~9.7.1": + version "9.7.2" + resolved "https://registry.yarnpkg.com/@react-spring/zdog/-/zdog-9.7.2.tgz#3dcbdb28b6c04d4480a2a68b020802f7ec5c44dd" + integrity sha512-6z2qqhmbpoZrw1oThyn4zfejtLkuadsaZFVMFf/5l5cHTEdRC8HZsBRLo+Wiomkprg/F1hyhcXI5X1lJ+T/zdQ== + dependencies: + "@react-spring/animated" "~9.7.2" + "@react-spring/core" "~9.7.2" + "@react-spring/shared" "~9.7.2" + "@react-spring/types" "~9.7.2" + "@rushstack/eslint-patch@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz#6801033be7ff87a6b7cadaf5b337c9f366a3c4b0" @@ -2302,6 +2388,13 @@ cmd-shim@^6.0.0: resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== +cobe@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cobe/-/cobe-0.6.3.tgz#9c3d45ae3a328b7bf709eb17b02f9caff41b22f0" + integrity sha512-WHr7X4o1ym94GZ96h7b1pNemZJacbOzd02dZtnVwuC4oWBaLg96PBmp2rIS1SAhUDhhC/QyS9WEqkpZIs/ZBTg== + dependencies: + phenomenon "^1.6.0" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -7179,6 +7272,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +phenomenon@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/phenomenon/-/phenomenon-1.6.0.tgz#7b5b7647d0b48152cc0846994da3d92e8f6da677" + integrity sha512-7h9/fjPD3qNlgggzm88cY58l9sudZ6Ey+UmZsizfhtawO6E3srZQXywaNm2lBwT72TbpHYRPy7ytIHeBUD/G0A== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -7535,6 +7633,18 @@ react-lottie-player@1.5.4: lottie-web "^5.7.6" rfdc "^1.3.0" +react-spring@^9.7.1: + version "9.7.1" + resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.7.1.tgz#8acfed700823490a4d9d4cf131c5fea12d1aaa93" + integrity sha512-o2+r2DNQDVEuefiz33ZF76DPd/gLq3kbdObJmllGF2IUfv2W6x+ZP0gR97QYCSR4QLbmOl1mPKUBbI+FJdys2Q== + dependencies: + "@react-spring/core" "~9.7.1" + "@react-spring/konva" "~9.7.1" + "@react-spring/native" "~9.7.1" + "@react-spring/three" "~9.7.1" + "@react-spring/web" "~9.7.1" + "@react-spring/zdog" "~9.7.1" + react-toastify@9.1.3: version "9.1.3" resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff"