-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathwhy-dev-stream.js
156 lines (149 loc) · 4.7 KB
/
why-dev-stream.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import clsx from 'clsx';
import React, { useEffect, useRef, useState } from 'react';
import Ripple from '@site/static/img/ripple-mark.svg';
import { useParallax } from 'react-scroll-parallax';
const reasons = [
'Too much effort integrating and maintaining every piece of DevOps?',
'Difficult (if not impossible) to track who changed what config?',
'Too much hassle to replace one of your DevOps tools?',
'Small team, a lot of tools, and way too few DevOps engineers to fully realize your pipelines?',
];
function throttle(fn) {
let timer = null;
return function () {
if (timer === null) {
timer = setTimeout(() => {
fn();
timer = null;
}, 100);
}
};
}
const useFadeIn = ({ startVh, endVh } = { startVh: 100, endVh: 0 }) => {
const [startScroll, setStartScroll] = useState(0);
const [endScroll, setEndScroll] = useState(0);
const bodyHeightRef = useRef(0);
const { ref } = useParallax({
translateY: ['100px', '0px'],
opacity: [0, 1],
startScroll,
endScroll,
});
useEffect(() => {
const handleScroll = () => {
if (!ref.current) {
return;
}
const bodyTop = document.body.getBoundingClientRect().top;
const top = ref.current.getBoundingClientRect().top;
const bodyHeight = document.body.scrollHeight;
const viewportHeight = window.innerHeight;
const distance = Math.abs(top - bodyTop);
// only update startScroll when the height of body is changed
if (bodyHeight !== bodyHeightRef.current) {
bodyHeightRef.current = bodyHeight;
const start = distance - viewportHeight * (startVh / 100);
setStartScroll(start);
setEndScroll(start + viewportHeight * (1 - endVh / 100));
}
};
window.addEventListener('scroll', throttle(handleScroll));
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [startScroll]);
return ref;
};
export const WhyDevStream = () => {
const fadeInRef1 = useFadeIn({ startVh: 100, endVh: 50 });
const fadeInRef2 = useFadeIn({ startVh: 100, endVh: 50 });
const fadeInRef3 = useFadeIn({ startVh: 100, endVh: 80 });
const fadeInRef4 = useFadeIn({ startVh: 100, endVh: 80 });
return (
<section
className="bg-primary-100 relative overflow-hidden flex flex-col flex-nowrap items-center justify-start
py-6 dark:bg-primary-dark-light
"
>
<h3 className="z-10 section-title dark:text-primary" ref={fadeInRef1}>
Why DevStream
</h3>
<div ref={fadeInRef2} className="z-10">
<MsgBox
className="mx-4 self-stretch flex flex-col flex-nowrap space-y-3
sm2:mx-6 sm2:space-y-1
lg:space-y-[4px] lg:max-w-[1086px] lg:self-center
"
>
{reasons.map((reason) => (
<Reason key={reason}>{reason}</Reason>
))}
</MsgBox>
</div>
<span
ref={fadeInRef3}
className="text-heading2stream text-primary font-semibold mt-[10px] z-10
lg:text-[64px] leading-[1.2] lg:mt-3"
>
Worry no more.
</span>
<span
ref={fadeInRef4}
className="text-heading4stream text-neutral-600 font-semibold mt-1 z-10
lg:text-heading1stream lg:mt-3 dark:text-neutral-300
"
>
DevStream will get you covered.
</span>
<Ripple
className="absolute opacity-50 dark:opacity-5 z-0
right-[-80px] top-[-50px] w-[200px]
lg:w-[600px] lg:h-[600px] lg:top-[-170px] lg:right-[-200px]"
/>
<Ripple
className="absolute opacity-50 dark:opacity-5 z-0 rotate-90
left-[-70px] bottom-[-80px] w-[200px]
lg:w-[400px] lg:h-[400px]"
/>
</section>
);
};
const MsgBox = ({ children, className }) => {
return (
<div
className={clsx(
className,
'bg-white max-w-full rounded-[20px] px-3 py-4 relative mb-3',
'sm2:px-6',
'lg:px-8 lg:py-[40px]',
'drop-shadow-xl shadow-lg shadow-primary-light/10'
)}
>
{children}
<svg
className="w-4 h-3 -bottom-3 left-1/2 absolute -translate-x-1/2 translate-y-[-1px]
lg:w-[36px] lg:h-[24px] lg:-bottom-[24px]
"
viewBox="0 0 25 17"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M12.5 16.4757L24.5 0.475708H0.5L12.5 16.4757Z" fill="white" />
</svg>
</div>
);
};
const Reason = ({ children, className }) => {
return (
<div
className={clsx(
className,
'text-neutral-400 text-label14stream flex flex-row flex-nowrap justify-start items-center',
'lg:text-label18stream'
)}
>
<span className="rounded-full h-[6px] w-[6px] bg-primary block shrink-0 mr-3"></span>
{children}
</div>
);
};