From 42de67f8e7392e9548f5ac03d32aefc5daa279bb Mon Sep 17 00:00:00 2001 From: Truong Le Date: Mon, 5 Sep 2022 15:51:08 +0700 Subject: [PATCH] feat(wavy-line): add component and story --- src/assets/styles/base.css | 17 +++++ src/components/WavyLine.tsx | 72 ++++++++++++++++++++++ src/stories/molecules/WavyLine.stories.tsx | 15 +++++ 3 files changed, 104 insertions(+) create mode 100644 src/components/WavyLine.tsx create mode 100644 src/stories/molecules/WavyLine.stories.tsx diff --git a/src/assets/styles/base.css b/src/assets/styles/base.css index 7ceefdf..8e4a249 100644 --- a/src/assets/styles/base.css +++ b/src/assets/styles/base.css @@ -117,4 +117,21 @@ .lightbox .slick-slide>div { @apply h-full; } + + #wave { + stroke-dasharray: 0 16 880 16; + animation: moveTheWave 16000ms linear infinite; + } + + @keyframes moveTheWave { + 0% { + stroke-dashoffset: 0; + transform: translate3d(0, 0, 0); + } + + 100% { + stroke-dashoffset: -922; + transform: translate3d(-612px, 0, 0); + } + } } \ No newline at end of file diff --git a/src/components/WavyLine.tsx b/src/components/WavyLine.tsx new file mode 100644 index 0000000..f6ec6fc --- /dev/null +++ b/src/components/WavyLine.tsx @@ -0,0 +1,72 @@ +import React, { useEffect, useRef } from "react"; + +interface Props { + color: string; + speed: number; +} + +const WavyLine: React.FC = ({ color, speed }) => { + const containerRef = useRef(null); + const pathRef = useRef(null); + // eslint-disable-next-line @typescript-eslint/no-loss-of-precision + const m = 0.512286623256592433; + + const buildWave = (w: number, h: number, blocks: number) => { + const a = h / 4; + const y = h / 2; + const down = ["s", -(1 - a) * m, a, a, a]; + const up = ["s", -(1 - a) * m, -a, a, -a]; + + const extendedPath = [...Array(blocks + 50).keys()] + .map((i) => { + return (i + 1) % 2 === 0 ? up : down; + }) + .flat(); + + const pathData = [ + "M", + w * 0, + y + a / 2, + "c", + a * m, + 0, + -(1 - a) * m, + -a, + a, + -a, + ...extendedPath, + ].join(" "); + + if (pathRef.current) { + pathRef.current.setAttribute("d", pathData); + } + }; + + useEffect(() => { + if (containerRef.current) { + const containerWidth = containerRef.current.offsetWidth; + const waveBlockAmount = Math.ceil(containerWidth / 15); + buildWave(90, 60, waveBlockAmount); + } + }, []); + + return ( +
+ + + +
+ ); +}; + +export default WavyLine; diff --git a/src/stories/molecules/WavyLine.stories.tsx b/src/stories/molecules/WavyLine.stories.tsx new file mode 100644 index 0000000..4f03784 --- /dev/null +++ b/src/stories/molecules/WavyLine.stories.tsx @@ -0,0 +1,15 @@ +import * as React from "react"; +import WavyLine from "@components/WavyLine"; + +export const WavyLineStory = () => ( +
+
+ +
+
+); + +export default { + title: "Molecules", +}; +WavyLineStory.storyName = "Wavy Line"; -- GitLab