diff --git a/package-lock.json b/package-lock.json index e8b4eb5..05aff34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "project-share-web", "version": "0.0.0", "dependencies": { + "framer-motion": "^10.16.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.1", @@ -3774,6 +3775,49 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/framer-motion": { + "version": "10.16.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.0.tgz", + "integrity": "sha512-R+88Mkr/1dr7XHjacwptfJyrywRzQ1HZX3YSZtN4tFMBq1O8GGCbDEv31Nf/H08o0hUXLC87GkxsR/1bZgwXfw==", + "dependencies": { + "tslib": "^2.4.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/framer-motion/node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + }, + "node_modules/framer-motion/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -7531,6 +7575,37 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "framer-motion": { + "version": "10.16.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.0.tgz", + "integrity": "sha512-R+88Mkr/1dr7XHjacwptfJyrywRzQ1HZX3YSZtN4tFMBq1O8GGCbDEv31Nf/H08o0hUXLC87GkxsR/1bZgwXfw==", + "requires": { + "@emotion/is-prop-valid": "^0.8.2", + "tslib": "^2.4.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + }, + "tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + } + } + }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", diff --git a/package.json b/package.json index 21d6875..8f53354 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "framer-motion": "^10.16.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.1", diff --git a/public/media/logos/project-share.svg b/public/media/logos/project-share.svg deleted file mode 100644 index a1f2741..0000000 --- a/public/media/logos/project-share.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/ProjectList/ProjectTile.tsx b/src/ProjectList/ProjectTile.tsx index c257121..81a3a56 100644 --- a/src/ProjectList/ProjectTile.tsx +++ b/src/ProjectList/ProjectTile.tsx @@ -5,6 +5,8 @@ import SketchLines from '../components/SketchLines' import { StyledLink } from '../components/StyledLink' import ProjectCreator from './ProjectCreator' import Dot from '../components/Dot' +import { useState } from 'react' +import Logo from '../components/Logo' const TopBar = styled.div` display: flex; @@ -19,11 +21,24 @@ const ProjectId = styled.p` user-select: none; ` +const ProjectVideoWrapper = styled.div` + position: relative; + border-radius: 8px; + overflow: hidden; + box-sizing: border-box; + border: 1px solid rgb(0 0 0 / 10%); + background-color: #f7f6f3; +` + const ProjectVideo = styled.video` width: 100%; border-radius: 7px; - border: 1px solid rgb(0 0 0 / 10%); box-sizing: border-box; + object-fit: cover; + transition: opacity 0.3s ease-in-out; + margin: 0; + padding: 0; + display: block; ` const BottomBar = styled.div` @@ -76,6 +91,8 @@ const ProjectTile = ({ media, icon, }: Project) => { + const [isVideoLoaded, setIsVideoLoaded] = useState(false) + return (
@@ -86,14 +103,28 @@ const ProjectTile = ({ )} - + + setIsVideoLoaded(false)} + style={{ opacity: isVideoLoaded ? 1 : 0 }} + /> +
+ {!isVideoLoaded && } +
+
+ diff --git a/src/components/Logo.tsx b/src/components/Logo.tsx index 5ee15e6..d842f09 100644 --- a/src/components/Logo.tsx +++ b/src/components/Logo.tsx @@ -1,18 +1,83 @@ import { FC } from 'react' +import styled, { css, keyframes } from 'styled-components' interface LogoProps { size?: number + animated?: boolean } -const Logo: FC = ({ size = 126 }) => { +const rotateAnimation = keyframes` + 40% { + transform: rotate(0deg); + } + 45% { + transform: rotate(-5deg); + } + 75% { + transform: rotate(363deg); + } + 80% { + transform: rotate(360deg); + } + 100% { + transform: rotate(360deg); + } +` +const Rotate = styled.g<{ animated: boolean }>` + transform-origin: 50% 50%; + animation: ${({ animated }) => + animated + ? css` + ${rotateAnimation} 3s infinite cubic-bezier(0.680, -0.550, 0.265, 1.550) + ` + : 'none'}; + animation-fill-mode: backwards; +` + +const Logo: FC = ({ size = 126, animated = false }) => { return ( - Project Share Logo +
+ + + + + + + + + + + + + + + + + +
) }