Skip to content

Commit a9595a9

Browse files
Implemented interactive and animated port project SVG illustration
A static vector graphic that is currently placed in the port section of the landing (`/`) page has been implemented as interactive animated component. It uses a 3D depth effect for the port project's logos by moving against the direction of the current mouse position where the larger logos will move more to give the impression that they are closer. For the interactive animation the awesome react-spring (1) project is used which allows, like the fantastic and also already used react-pose (2) library, to use spring-physics based animations. The advantage of react-spring is that it bails out of the React renderer to avoid unnecessary renders and instead uses native methods to get the best performance even for complex animations. It comes with first-class support for Hooks (3), a great and extensive documentation and a lot of examples for inspirations (4). References: (1) https://www.react-spring.io (2) https://popmotion.io/pose (3) https://www.react-spring.io/docs/hooks/basics (4) https://www.react-spring.io/docs/hooks/examples GH-119
1 parent 3b131b1 commit a9595a9

File tree

7 files changed

+679
-0
lines changed

7 files changed

+679
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (C) 2018-present Arctic Ice Studio <[email protected]>
3+
* Copyright (C) 2018-present Sven Greb <[email protected]>
4+
*
5+
* Project: Nord Docs
6+
* Repository: https://github.com/arcticicestudio/nord-docs
7+
* License: MIT
8+
*/
9+
10+
import React from "react";
11+
import PropTypes from "prop-types";
12+
import styled from "styled-components";
13+
14+
import LogosLayerBottom from "./styled/LogosLayerBottom";
15+
import LogosLayerMiddle from "./styled/LogosLayerMiddle";
16+
import LogosLayerTop from "./styled/LogosLayerTop";
17+
import Window from "./styled/Window";
18+
19+
const Svg = styled.svg`
20+
display: block;
21+
overflow: visible;
22+
`;
23+
24+
const transformLogosBottom = (x, y) => `translate3d(${-x * 0.008}px, ${-y * 0.009}px, 0)`;
25+
const transformLogosMiddle = (x, y) => `translate3d(${-x * 0.015}px, ${-y * 0.02}px, 0)`;
26+
const transformLogosTop = (x, y) => `translate3d(${-x * 0.03}px, ${-y * 0.038}px, 0)`;
27+
28+
/**
29+
* An interactive illustration with a 3D depth effect that reacts and animates floating port project logos based on the
30+
* current mouse poiner position.
31+
* The animation is computed with react-spring through the exported `useFloatingLogos` hook.
32+
*
33+
* @author Arctic Ice Studio <[email protected]>
34+
* @author Sven Greb <[email protected]>
35+
* @since 0.9.0
36+
* @see https://www.react-spring.io
37+
*/
38+
const PortProjectsWindow = ({ logoLayerTransformer, ...passProps }) => (
39+
<Svg {...passProps} viewBox="0 0 1678.836 503.798" xmlns="http://www.w3.org/2000/svg">
40+
<LogosLayerBottom style={{ transform: logoLayerTransformer(transformLogosBottom) }} />
41+
<LogosLayerMiddle style={{ transform: logoLayerTransformer(transformLogosMiddle) }} />
42+
<LogosLayerTop style={{ transform: logoLayerTransformer(transformLogosTop) }} />
43+
<Window />
44+
</Svg>
45+
);
46+
47+
PortProjectsWindow.propTypes = {
48+
logoLayerTransformer: PropTypes.func.isRequired
49+
};
50+
51+
export default PortProjectsWindow;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) 2018-present Arctic Ice Studio <[email protected]>
3+
* Copyright (C) 2018-present Sven Greb <[email protected]>
4+
*
5+
* Project: Nord Docs
6+
* Repository: https://github.com/arcticicestudio/nord-docs
7+
* License: MIT
8+
*/
9+
10+
import { useSpring } from "react-spring";
11+
12+
const calcWindowDimensions = (x, y) => [x - window.innerWidth / 2, y - window.innerHeight / 2];
13+
14+
/**
15+
* A hook that provides calculated spring-physic values based on the current window dimensions.
16+
*
17+
* @author Arctic Ice Studio <[email protected]>
18+
* @author Sven Greb <[email protected]>
19+
* @since 0.9.0
20+
*/
21+
export default function useFloatingLogos() {
22+
const [{ xy }, set] = useSpring(() => ({
23+
xy: [0, 0],
24+
config: { mass: 10, tension: 800, friction: 140 }
25+
}));
26+
27+
function calcFloatingLogos(x, y) {
28+
return set({ xy: calcWindowDimensions(x, y) });
29+
}
30+
31+
return { transformLogoLayer: xy.interpolate, calcFloatingLogos };
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (C) 2018-present Arctic Ice Studio <[email protected]>
3+
* Copyright (C) 2018-present Sven Greb <[email protected]>
4+
*
5+
* Project: Nord Docs
6+
* Repository: https://github.com/arcticicestudio/nord-docs
7+
* License: MIT
8+
*/
9+
10+
import PortProjectsWindow from "./PortProjectsWindow";
11+
import useFloatingLogos from "./hooks/useFloatingLogos";
12+
13+
export { useFloatingLogos };
14+
export default PortProjectsWindow;

0 commit comments

Comments
 (0)