umwd-components 0.1.195 → 0.1.196
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/FluidBackground.js +261 -0
- package/dist/cjs/index.js +2 -0
- package/dist/esm/components/FluidBackground.js +257 -0
- package/dist/esm/index.js +1 -0
- package/package.json +1 -1
- package/src/components/FluidBackground.tsx +271 -0
- package/src/index.js +1 -0
- package/src/stories/FluidBackground.stories.js +29 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UMWD-Components
|
|
3
|
+
* @copyright Jelle Paulus
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
+
|
|
11
|
+
var React = require('react');
|
|
12
|
+
|
|
13
|
+
function FluidBackground() {
|
|
14
|
+
const [objectX, setObjectX] = React.useState(window.innerWidth / 2); // Initial position
|
|
15
|
+
const [objectY, setObjectY] = React.useState(window.innerHeight / 2);
|
|
16
|
+
const [brightness, setBrightness] = React.useState(1);
|
|
17
|
+
const maxBrightness = 1.5;
|
|
18
|
+
const minBrightness = 0.5;
|
|
19
|
+
const minSize = Math.sqrt(window.innerWidth ** 2 + window.innerHeight ** 2) / 6;
|
|
20
|
+
const maxSize = Math.sqrt(window.innerWidth ** 2 + window.innerHeight ** 2) / 2;
|
|
21
|
+
const [ObjectSize, setObjectSize] = React.useState(maxSize); // Initial size
|
|
22
|
+
let transitionInterval = null; // Declare transitionInterval variable
|
|
23
|
+
|
|
24
|
+
const handleMove = (x, y) => {
|
|
25
|
+
setObjectX(x);
|
|
26
|
+
setObjectY(y);
|
|
27
|
+
};
|
|
28
|
+
const handleStart = () => {
|
|
29
|
+
const duration = 3000; // duration in milliseconds
|
|
30
|
+
const steps = 180; // number of steps for the transition
|
|
31
|
+
const stepDuration = duration / steps; // duration of each step
|
|
32
|
+
|
|
33
|
+
let currentBrightness = brightness;
|
|
34
|
+
let targetBrightness = maxBrightness;
|
|
35
|
+
let currentSize = ObjectSize;
|
|
36
|
+
let targetSize = minSize;
|
|
37
|
+
let step = 0;
|
|
38
|
+
|
|
39
|
+
// Clear any existing transition interval
|
|
40
|
+
if (transitionInterval) {
|
|
41
|
+
clearInterval(transitionInterval);
|
|
42
|
+
}
|
|
43
|
+
transitionInterval = setInterval(() => {
|
|
44
|
+
step++;
|
|
45
|
+
currentBrightness = currentBrightness - (currentBrightness - targetBrightness) / steps;
|
|
46
|
+
currentSize = currentSize - (currentSize - targetSize) / steps;
|
|
47
|
+
setBrightness(currentBrightness);
|
|
48
|
+
setObjectSize(currentSize);
|
|
49
|
+
if (step === steps) {
|
|
50
|
+
if (transitionInterval) {
|
|
51
|
+
clearInterval(transitionInterval);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, stepDuration);
|
|
55
|
+
};
|
|
56
|
+
const handleEnd = () => {
|
|
57
|
+
const duration = 3000; // duration in milliseconds
|
|
58
|
+
const steps = 180; // number of steps for the transition
|
|
59
|
+
const stepDuration = duration / steps; // duration of each step
|
|
60
|
+
|
|
61
|
+
let currentBrightness = brightness;
|
|
62
|
+
let targetBrightness = minBrightness;
|
|
63
|
+
let currentSize = ObjectSize;
|
|
64
|
+
let targetSize = maxSize;
|
|
65
|
+
let step = 0;
|
|
66
|
+
|
|
67
|
+
// Clear any existing transition interval
|
|
68
|
+
if (transitionInterval) {
|
|
69
|
+
clearInterval(transitionInterval);
|
|
70
|
+
}
|
|
71
|
+
transitionInterval = setInterval(() => {
|
|
72
|
+
step++;
|
|
73
|
+
currentBrightness = currentBrightness - (currentBrightness - targetBrightness) / steps;
|
|
74
|
+
currentSize = currentSize - (currentSize - targetSize) / steps;
|
|
75
|
+
setBrightness(currentBrightness);
|
|
76
|
+
setObjectSize(currentSize);
|
|
77
|
+
if (step === steps) {
|
|
78
|
+
if (transitionInterval) {
|
|
79
|
+
clearInterval(transitionInterval);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}, stepDuration);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Add event listeners to trigger handleEnd on touch end or mouse up
|
|
86
|
+
React.useEffect(() => {
|
|
87
|
+
const handleEndEvent = () => {
|
|
88
|
+
handleEnd();
|
|
89
|
+
};
|
|
90
|
+
window.addEventListener("touchend", handleEndEvent);
|
|
91
|
+
window.addEventListener("mouseup", handleEndEvent);
|
|
92
|
+
return () => {
|
|
93
|
+
window.removeEventListener("touchend", handleEndEvent);
|
|
94
|
+
window.removeEventListener("mouseup", handleEndEvent);
|
|
95
|
+
};
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
// Add event listeners to trigger handleStart on touch start or mouse down
|
|
99
|
+
React.useEffect(() => {
|
|
100
|
+
const handleStartEvent = () => {
|
|
101
|
+
handleStart();
|
|
102
|
+
};
|
|
103
|
+
window.addEventListener("touchstart", handleStartEvent);
|
|
104
|
+
window.addEventListener("mousedown", handleStartEvent);
|
|
105
|
+
return () => {
|
|
106
|
+
window.removeEventListener("touchstart", handleStartEvent);
|
|
107
|
+
window.removeEventListener("mousedown", handleStartEvent);
|
|
108
|
+
};
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
// Add event listeners to trigger handleMove on touch move or mouse move
|
|
112
|
+
React.useEffect(() => {
|
|
113
|
+
const handleMoveEvent = e => {
|
|
114
|
+
const x = e instanceof TouchEvent ? e.touches[0].clientX : e.clientX;
|
|
115
|
+
const y = e instanceof TouchEvent ? e.touches[0].clientY : e.clientY;
|
|
116
|
+
handleMove(x, y);
|
|
117
|
+
};
|
|
118
|
+
window.addEventListener("touchmove", handleMoveEvent);
|
|
119
|
+
window.addEventListener("mousemove", handleMoveEvent);
|
|
120
|
+
return () => {
|
|
121
|
+
window.removeEventListener("touchmove", handleMoveEvent);
|
|
122
|
+
window.removeEventListener("mousemove", handleMoveEvent);
|
|
123
|
+
};
|
|
124
|
+
}, []);
|
|
125
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
126
|
+
style: {
|
|
127
|
+
position: "fixed",
|
|
128
|
+
top: 0,
|
|
129
|
+
left: 0,
|
|
130
|
+
width: "100vw",
|
|
131
|
+
height: "100vh",
|
|
132
|
+
zIndex: -1,
|
|
133
|
+
pointerEvents: "none",
|
|
134
|
+
isolation: "isolate"
|
|
135
|
+
}
|
|
136
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
137
|
+
id: "background",
|
|
138
|
+
style: {
|
|
139
|
+
position: "absolute",
|
|
140
|
+
top: 0,
|
|
141
|
+
left: 0,
|
|
142
|
+
display: "Block",
|
|
143
|
+
width: "100%",
|
|
144
|
+
height: "100%",
|
|
145
|
+
background: "#2d2d2d",
|
|
146
|
+
zIndex: -1
|
|
147
|
+
}
|
|
148
|
+
}), /*#__PURE__*/React.createElement("svg", {
|
|
149
|
+
id: "object",
|
|
150
|
+
width: "".concat(ObjectSize, "px"),
|
|
151
|
+
height: "".concat(ObjectSize, "px"),
|
|
152
|
+
style: {
|
|
153
|
+
position: "absolute",
|
|
154
|
+
top: "".concat(objectY, "px"),
|
|
155
|
+
left: "".concat(objectX, "px"),
|
|
156
|
+
transform: "translate(-50%, -50%)"
|
|
157
|
+
}
|
|
158
|
+
}, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("mask", {
|
|
159
|
+
id: "radial-gradient-mask"
|
|
160
|
+
}, /*#__PURE__*/React.createElement("radialGradient", {
|
|
161
|
+
id: "gradient",
|
|
162
|
+
cx: "50%",
|
|
163
|
+
cy: "50%",
|
|
164
|
+
r: "50%",
|
|
165
|
+
fx: "50%",
|
|
166
|
+
fy: "50%"
|
|
167
|
+
}, /*#__PURE__*/React.createElement("stop", {
|
|
168
|
+
offset: "0%",
|
|
169
|
+
stopColor: "white"
|
|
170
|
+
}), /*#__PURE__*/React.createElement("stop", {
|
|
171
|
+
offset: "100%",
|
|
172
|
+
stopColor: "black"
|
|
173
|
+
})), /*#__PURE__*/React.createElement("rect", {
|
|
174
|
+
width: "100%",
|
|
175
|
+
height: "100%",
|
|
176
|
+
fill: "url(#gradient)"
|
|
177
|
+
}))), /*#__PURE__*/React.createElement("rect", {
|
|
178
|
+
width: "100%",
|
|
179
|
+
height: "100%",
|
|
180
|
+
fill: "#439392",
|
|
181
|
+
mask: "url(#radial-gradient-mask)",
|
|
182
|
+
style: {
|
|
183
|
+
filter: "brightness(".concat(brightness, ")")
|
|
184
|
+
}
|
|
185
|
+
})), /*#__PURE__*/React.createElement("svg", {
|
|
186
|
+
id: "foreground",
|
|
187
|
+
style: {
|
|
188
|
+
position: "absolute",
|
|
189
|
+
minWidth: "100%",
|
|
190
|
+
minHeight: "100%"
|
|
191
|
+
},
|
|
192
|
+
viewBox: "0 0 7680 4320 "
|
|
193
|
+
}, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("mask", {
|
|
194
|
+
id: "mask"
|
|
195
|
+
}, /*#__PURE__*/React.createElement("rect", {
|
|
196
|
+
width: "100%",
|
|
197
|
+
height: "100%",
|
|
198
|
+
fill: "white"
|
|
199
|
+
}), /*#__PURE__*/React.createElement("text", {
|
|
200
|
+
transform: "translate(-1000 200) rotate(-15)",
|
|
201
|
+
style: {
|
|
202
|
+
fill: "#000",
|
|
203
|
+
fontFamily: "Merriweather-Bold, Merriweather",
|
|
204
|
+
fontSize: "360px",
|
|
205
|
+
fontWeight: 700,
|
|
206
|
+
letterSpacing: ".055em"
|
|
207
|
+
}
|
|
208
|
+
}, /*#__PURE__*/React.createElement("tspan", {
|
|
209
|
+
x: "0",
|
|
210
|
+
y: "0"
|
|
211
|
+
}, "JELLE PAULUS IS A TALENTED WEB DEVELOPER AND", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
212
|
+
x: "0",
|
|
213
|
+
y: "432"
|
|
214
|
+
}, "DESIGNER WITH A PASSION FOR CREATING VISUALLY", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
215
|
+
x: "0",
|
|
216
|
+
y: "864"
|
|
217
|
+
}, "STUNNING AND USER-FRIENDLY WEBSITES. WITH A", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
218
|
+
x: "0",
|
|
219
|
+
y: "1296"
|
|
220
|
+
}, "KEEN EYE FOR DETAIL AND A FOCUS ON CREATING", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
221
|
+
x: "0",
|
|
222
|
+
y: "1728"
|
|
223
|
+
}, "CLEAN, FUNCTIONAL DESIGNS, JELLE HAS A", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
224
|
+
x: "0",
|
|
225
|
+
y: "2160"
|
|
226
|
+
}, "REPUTATION FOR DELIVERING HIGH-QUALITY WORK", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
227
|
+
x: "0",
|
|
228
|
+
y: "2592"
|
|
229
|
+
}, "THAT EXCEEDS HIS CLIENTS' EXPECTATIONS. HE HAS A", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
230
|
+
x: "0",
|
|
231
|
+
y: "3024"
|
|
232
|
+
}, "DEEP UNDERSTANDING OF THE LATEST WEB", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
233
|
+
x: "0",
|
|
234
|
+
y: "3456"
|
|
235
|
+
}, "DEVELOPMENT TECHNOLOGIES, AND IS ABLE TO", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
236
|
+
x: "0",
|
|
237
|
+
y: "3888"
|
|
238
|
+
}, "SEAMLESSLY INTEGRATE FUNCTIONALITY AND", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
239
|
+
x: "0",
|
|
240
|
+
y: "4320"
|
|
241
|
+
}, "AESTHETICS TO CREATE WEBSITES THAT ARE BOTH", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
242
|
+
x: "0",
|
|
243
|
+
y: "4752"
|
|
244
|
+
}, "FUNCTIONAL AND VISUALLY APPEALING. WHETHER", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
245
|
+
x: "0",
|
|
246
|
+
y: "5184"
|
|
247
|
+
}, "YOU'RE LOOKING TO ESTABLISH AN ONLINE PRESENCE", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
248
|
+
x: "0",
|
|
249
|
+
y: "5616"
|
|
250
|
+
}, "OR REVAMP AN EXISTING WEBSITE, JELLE HAS THE", " "), /*#__PURE__*/React.createElement("tspan", {
|
|
251
|
+
x: "0",
|
|
252
|
+
y: "6048"
|
|
253
|
+
}, "SKILLS AND EXPERTISE TO BRING YOUR VISION TO LIFE.")))), /*#__PURE__*/React.createElement("rect", {
|
|
254
|
+
width: "100%",
|
|
255
|
+
height: "100%",
|
|
256
|
+
fill: "#222",
|
|
257
|
+
mask: "url(#mask)"
|
|
258
|
+
})));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
exports.default = FluidBackground;
|
package/dist/cjs/index.js
CHANGED
|
@@ -18,6 +18,7 @@ var BulletList = require('./components/BulletList.js');
|
|
|
18
18
|
var WhatsAppClickToChatButton = require('./components/WhatsAppClickToChatButton.js');
|
|
19
19
|
var ScrollLink = require('./components/ScrollLink.js');
|
|
20
20
|
var ScrollNavbar = require('./components/ScrollNavbar.js');
|
|
21
|
+
var FluidBackground = require('./components/FluidBackground.js');
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
|
|
@@ -33,3 +34,4 @@ exports.BulletList = BulletList.default;
|
|
|
33
34
|
exports.WhatsAppClickToChatButton = WhatsAppClickToChatButton.default;
|
|
34
35
|
exports.ScrollLink = ScrollLink.default;
|
|
35
36
|
exports.ScrollNavbar = ScrollNavbar.default;
|
|
37
|
+
exports.FluidBackground = FluidBackground.default;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UMWD-Components
|
|
3
|
+
* @copyright Jelle Paulus
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React__default, { useState, useEffect } from 'react';
|
|
8
|
+
|
|
9
|
+
function FluidBackground() {
|
|
10
|
+
const [objectX, setObjectX] = useState(window.innerWidth / 2); // Initial position
|
|
11
|
+
const [objectY, setObjectY] = useState(window.innerHeight / 2);
|
|
12
|
+
const [brightness, setBrightness] = useState(1);
|
|
13
|
+
const maxBrightness = 1.5;
|
|
14
|
+
const minBrightness = 0.5;
|
|
15
|
+
const minSize = Math.sqrt(window.innerWidth ** 2 + window.innerHeight ** 2) / 6;
|
|
16
|
+
const maxSize = Math.sqrt(window.innerWidth ** 2 + window.innerHeight ** 2) / 2;
|
|
17
|
+
const [ObjectSize, setObjectSize] = useState(maxSize); // Initial size
|
|
18
|
+
let transitionInterval = null; // Declare transitionInterval variable
|
|
19
|
+
|
|
20
|
+
const handleMove = (x, y) => {
|
|
21
|
+
setObjectX(x);
|
|
22
|
+
setObjectY(y);
|
|
23
|
+
};
|
|
24
|
+
const handleStart = () => {
|
|
25
|
+
const duration = 3000; // duration in milliseconds
|
|
26
|
+
const steps = 180; // number of steps for the transition
|
|
27
|
+
const stepDuration = duration / steps; // duration of each step
|
|
28
|
+
|
|
29
|
+
let currentBrightness = brightness;
|
|
30
|
+
let targetBrightness = maxBrightness;
|
|
31
|
+
let currentSize = ObjectSize;
|
|
32
|
+
let targetSize = minSize;
|
|
33
|
+
let step = 0;
|
|
34
|
+
|
|
35
|
+
// Clear any existing transition interval
|
|
36
|
+
if (transitionInterval) {
|
|
37
|
+
clearInterval(transitionInterval);
|
|
38
|
+
}
|
|
39
|
+
transitionInterval = setInterval(() => {
|
|
40
|
+
step++;
|
|
41
|
+
currentBrightness = currentBrightness - (currentBrightness - targetBrightness) / steps;
|
|
42
|
+
currentSize = currentSize - (currentSize - targetSize) / steps;
|
|
43
|
+
setBrightness(currentBrightness);
|
|
44
|
+
setObjectSize(currentSize);
|
|
45
|
+
if (step === steps) {
|
|
46
|
+
if (transitionInterval) {
|
|
47
|
+
clearInterval(transitionInterval);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, stepDuration);
|
|
51
|
+
};
|
|
52
|
+
const handleEnd = () => {
|
|
53
|
+
const duration = 3000; // duration in milliseconds
|
|
54
|
+
const steps = 180; // number of steps for the transition
|
|
55
|
+
const stepDuration = duration / steps; // duration of each step
|
|
56
|
+
|
|
57
|
+
let currentBrightness = brightness;
|
|
58
|
+
let targetBrightness = minBrightness;
|
|
59
|
+
let currentSize = ObjectSize;
|
|
60
|
+
let targetSize = maxSize;
|
|
61
|
+
let step = 0;
|
|
62
|
+
|
|
63
|
+
// Clear any existing transition interval
|
|
64
|
+
if (transitionInterval) {
|
|
65
|
+
clearInterval(transitionInterval);
|
|
66
|
+
}
|
|
67
|
+
transitionInterval = setInterval(() => {
|
|
68
|
+
step++;
|
|
69
|
+
currentBrightness = currentBrightness - (currentBrightness - targetBrightness) / steps;
|
|
70
|
+
currentSize = currentSize - (currentSize - targetSize) / steps;
|
|
71
|
+
setBrightness(currentBrightness);
|
|
72
|
+
setObjectSize(currentSize);
|
|
73
|
+
if (step === steps) {
|
|
74
|
+
if (transitionInterval) {
|
|
75
|
+
clearInterval(transitionInterval);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, stepDuration);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Add event listeners to trigger handleEnd on touch end or mouse up
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
const handleEndEvent = () => {
|
|
84
|
+
handleEnd();
|
|
85
|
+
};
|
|
86
|
+
window.addEventListener("touchend", handleEndEvent);
|
|
87
|
+
window.addEventListener("mouseup", handleEndEvent);
|
|
88
|
+
return () => {
|
|
89
|
+
window.removeEventListener("touchend", handleEndEvent);
|
|
90
|
+
window.removeEventListener("mouseup", handleEndEvent);
|
|
91
|
+
};
|
|
92
|
+
}, []);
|
|
93
|
+
|
|
94
|
+
// Add event listeners to trigger handleStart on touch start or mouse down
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const handleStartEvent = () => {
|
|
97
|
+
handleStart();
|
|
98
|
+
};
|
|
99
|
+
window.addEventListener("touchstart", handleStartEvent);
|
|
100
|
+
window.addEventListener("mousedown", handleStartEvent);
|
|
101
|
+
return () => {
|
|
102
|
+
window.removeEventListener("touchstart", handleStartEvent);
|
|
103
|
+
window.removeEventListener("mousedown", handleStartEvent);
|
|
104
|
+
};
|
|
105
|
+
}, []);
|
|
106
|
+
|
|
107
|
+
// Add event listeners to trigger handleMove on touch move or mouse move
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
const handleMoveEvent = e => {
|
|
110
|
+
const x = e instanceof TouchEvent ? e.touches[0].clientX : e.clientX;
|
|
111
|
+
const y = e instanceof TouchEvent ? e.touches[0].clientY : e.clientY;
|
|
112
|
+
handleMove(x, y);
|
|
113
|
+
};
|
|
114
|
+
window.addEventListener("touchmove", handleMoveEvent);
|
|
115
|
+
window.addEventListener("mousemove", handleMoveEvent);
|
|
116
|
+
return () => {
|
|
117
|
+
window.removeEventListener("touchmove", handleMoveEvent);
|
|
118
|
+
window.removeEventListener("mousemove", handleMoveEvent);
|
|
119
|
+
};
|
|
120
|
+
}, []);
|
|
121
|
+
return /*#__PURE__*/React__default.createElement("div", {
|
|
122
|
+
style: {
|
|
123
|
+
position: "fixed",
|
|
124
|
+
top: 0,
|
|
125
|
+
left: 0,
|
|
126
|
+
width: "100vw",
|
|
127
|
+
height: "100vh",
|
|
128
|
+
zIndex: -1,
|
|
129
|
+
pointerEvents: "none",
|
|
130
|
+
isolation: "isolate"
|
|
131
|
+
}
|
|
132
|
+
}, /*#__PURE__*/React__default.createElement("div", {
|
|
133
|
+
id: "background",
|
|
134
|
+
style: {
|
|
135
|
+
position: "absolute",
|
|
136
|
+
top: 0,
|
|
137
|
+
left: 0,
|
|
138
|
+
display: "Block",
|
|
139
|
+
width: "100%",
|
|
140
|
+
height: "100%",
|
|
141
|
+
background: "#2d2d2d",
|
|
142
|
+
zIndex: -1
|
|
143
|
+
}
|
|
144
|
+
}), /*#__PURE__*/React__default.createElement("svg", {
|
|
145
|
+
id: "object",
|
|
146
|
+
width: "".concat(ObjectSize, "px"),
|
|
147
|
+
height: "".concat(ObjectSize, "px"),
|
|
148
|
+
style: {
|
|
149
|
+
position: "absolute",
|
|
150
|
+
top: "".concat(objectY, "px"),
|
|
151
|
+
left: "".concat(objectX, "px"),
|
|
152
|
+
transform: "translate(-50%, -50%)"
|
|
153
|
+
}
|
|
154
|
+
}, /*#__PURE__*/React__default.createElement("defs", null, /*#__PURE__*/React__default.createElement("mask", {
|
|
155
|
+
id: "radial-gradient-mask"
|
|
156
|
+
}, /*#__PURE__*/React__default.createElement("radialGradient", {
|
|
157
|
+
id: "gradient",
|
|
158
|
+
cx: "50%",
|
|
159
|
+
cy: "50%",
|
|
160
|
+
r: "50%",
|
|
161
|
+
fx: "50%",
|
|
162
|
+
fy: "50%"
|
|
163
|
+
}, /*#__PURE__*/React__default.createElement("stop", {
|
|
164
|
+
offset: "0%",
|
|
165
|
+
stopColor: "white"
|
|
166
|
+
}), /*#__PURE__*/React__default.createElement("stop", {
|
|
167
|
+
offset: "100%",
|
|
168
|
+
stopColor: "black"
|
|
169
|
+
})), /*#__PURE__*/React__default.createElement("rect", {
|
|
170
|
+
width: "100%",
|
|
171
|
+
height: "100%",
|
|
172
|
+
fill: "url(#gradient)"
|
|
173
|
+
}))), /*#__PURE__*/React__default.createElement("rect", {
|
|
174
|
+
width: "100%",
|
|
175
|
+
height: "100%",
|
|
176
|
+
fill: "#439392",
|
|
177
|
+
mask: "url(#radial-gradient-mask)",
|
|
178
|
+
style: {
|
|
179
|
+
filter: "brightness(".concat(brightness, ")")
|
|
180
|
+
}
|
|
181
|
+
})), /*#__PURE__*/React__default.createElement("svg", {
|
|
182
|
+
id: "foreground",
|
|
183
|
+
style: {
|
|
184
|
+
position: "absolute",
|
|
185
|
+
minWidth: "100%",
|
|
186
|
+
minHeight: "100%"
|
|
187
|
+
},
|
|
188
|
+
viewBox: "0 0 7680 4320 "
|
|
189
|
+
}, /*#__PURE__*/React__default.createElement("defs", null, /*#__PURE__*/React__default.createElement("mask", {
|
|
190
|
+
id: "mask"
|
|
191
|
+
}, /*#__PURE__*/React__default.createElement("rect", {
|
|
192
|
+
width: "100%",
|
|
193
|
+
height: "100%",
|
|
194
|
+
fill: "white"
|
|
195
|
+
}), /*#__PURE__*/React__default.createElement("text", {
|
|
196
|
+
transform: "translate(-1000 200) rotate(-15)",
|
|
197
|
+
style: {
|
|
198
|
+
fill: "#000",
|
|
199
|
+
fontFamily: "Merriweather-Bold, Merriweather",
|
|
200
|
+
fontSize: "360px",
|
|
201
|
+
fontWeight: 700,
|
|
202
|
+
letterSpacing: ".055em"
|
|
203
|
+
}
|
|
204
|
+
}, /*#__PURE__*/React__default.createElement("tspan", {
|
|
205
|
+
x: "0",
|
|
206
|
+
y: "0"
|
|
207
|
+
}, "JELLE PAULUS IS A TALENTED WEB DEVELOPER AND", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
208
|
+
x: "0",
|
|
209
|
+
y: "432"
|
|
210
|
+
}, "DESIGNER WITH A PASSION FOR CREATING VISUALLY", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
211
|
+
x: "0",
|
|
212
|
+
y: "864"
|
|
213
|
+
}, "STUNNING AND USER-FRIENDLY WEBSITES. WITH A", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
214
|
+
x: "0",
|
|
215
|
+
y: "1296"
|
|
216
|
+
}, "KEEN EYE FOR DETAIL AND A FOCUS ON CREATING", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
217
|
+
x: "0",
|
|
218
|
+
y: "1728"
|
|
219
|
+
}, "CLEAN, FUNCTIONAL DESIGNS, JELLE HAS A", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
220
|
+
x: "0",
|
|
221
|
+
y: "2160"
|
|
222
|
+
}, "REPUTATION FOR DELIVERING HIGH-QUALITY WORK", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
223
|
+
x: "0",
|
|
224
|
+
y: "2592"
|
|
225
|
+
}, "THAT EXCEEDS HIS CLIENTS' EXPECTATIONS. HE HAS A", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
226
|
+
x: "0",
|
|
227
|
+
y: "3024"
|
|
228
|
+
}, "DEEP UNDERSTANDING OF THE LATEST WEB", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
229
|
+
x: "0",
|
|
230
|
+
y: "3456"
|
|
231
|
+
}, "DEVELOPMENT TECHNOLOGIES, AND IS ABLE TO", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
232
|
+
x: "0",
|
|
233
|
+
y: "3888"
|
|
234
|
+
}, "SEAMLESSLY INTEGRATE FUNCTIONALITY AND", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
235
|
+
x: "0",
|
|
236
|
+
y: "4320"
|
|
237
|
+
}, "AESTHETICS TO CREATE WEBSITES THAT ARE BOTH", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
238
|
+
x: "0",
|
|
239
|
+
y: "4752"
|
|
240
|
+
}, "FUNCTIONAL AND VISUALLY APPEALING. WHETHER", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
241
|
+
x: "0",
|
|
242
|
+
y: "5184"
|
|
243
|
+
}, "YOU'RE LOOKING TO ESTABLISH AN ONLINE PRESENCE", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
244
|
+
x: "0",
|
|
245
|
+
y: "5616"
|
|
246
|
+
}, "OR REVAMP AN EXISTING WEBSITE, JELLE HAS THE", " "), /*#__PURE__*/React__default.createElement("tspan", {
|
|
247
|
+
x: "0",
|
|
248
|
+
y: "6048"
|
|
249
|
+
}, "SKILLS AND EXPERTISE TO BRING YOUR VISION TO LIFE.")))), /*#__PURE__*/React__default.createElement("rect", {
|
|
250
|
+
width: "100%",
|
|
251
|
+
height: "100%",
|
|
252
|
+
fill: "#222",
|
|
253
|
+
mask: "url(#mask)"
|
|
254
|
+
})));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export { FluidBackground as default };
|
package/dist/esm/index.js
CHANGED
|
@@ -16,3 +16,4 @@ export { default as BulletList } from './components/BulletList.js';
|
|
|
16
16
|
export { default as WhatsAppClickToChatButton } from './components/WhatsAppClickToChatButton.js';
|
|
17
17
|
export { default as ScrollLink } from './components/ScrollLink.js';
|
|
18
18
|
export { default as ScrollNavbar } from './components/ScrollNavbar.js';
|
|
19
|
+
export { default as FluidBackground } from './components/FluidBackground.js';
|
package/package.json
CHANGED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
function FluidBackground() {
|
|
4
|
+
const [objectX, setObjectX] = useState(window.innerWidth / 2); // Initial position
|
|
5
|
+
const [objectY, setObjectY] = useState(window.innerHeight / 2);
|
|
6
|
+
const [brightness, setBrightness] = useState(1);
|
|
7
|
+
const maxBrightness = 1.5;
|
|
8
|
+
const minBrightness = 0.5;
|
|
9
|
+
const minSize =
|
|
10
|
+
Math.sqrt(window.innerWidth ** 2 + window.innerHeight ** 2) / 6;
|
|
11
|
+
const maxSize =
|
|
12
|
+
Math.sqrt(window.innerWidth ** 2 + window.innerHeight ** 2) / 2;
|
|
13
|
+
const [ObjectSize, setObjectSize] = useState(maxSize); // Initial size
|
|
14
|
+
let transitionInterval: NodeJS.Timeout | null = null; // Declare transitionInterval variable
|
|
15
|
+
|
|
16
|
+
const handleMove = (x: number, y: number) => {
|
|
17
|
+
setObjectX(x);
|
|
18
|
+
setObjectY(y);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleStart = () => {
|
|
22
|
+
const duration = 3000; // duration in milliseconds
|
|
23
|
+
const steps = 180; // number of steps for the transition
|
|
24
|
+
const stepDuration = duration / steps; // duration of each step
|
|
25
|
+
|
|
26
|
+
let currentBrightness = brightness;
|
|
27
|
+
let targetBrightness = maxBrightness;
|
|
28
|
+
let currentSize = ObjectSize;
|
|
29
|
+
let targetSize = minSize;
|
|
30
|
+
let step = 0;
|
|
31
|
+
|
|
32
|
+
// Clear any existing transition interval
|
|
33
|
+
if (transitionInterval) {
|
|
34
|
+
clearInterval(transitionInterval);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
transitionInterval = setInterval(() => {
|
|
38
|
+
step++;
|
|
39
|
+
currentBrightness =
|
|
40
|
+
currentBrightness - (currentBrightness - targetBrightness) / steps;
|
|
41
|
+
currentSize = currentSize - (currentSize - targetSize) / steps;
|
|
42
|
+
setBrightness(currentBrightness);
|
|
43
|
+
setObjectSize(currentSize);
|
|
44
|
+
|
|
45
|
+
if (step === steps) {
|
|
46
|
+
if (transitionInterval) {
|
|
47
|
+
clearInterval(transitionInterval);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, stepDuration);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const handleEnd = () => {
|
|
54
|
+
const duration = 3000; // duration in milliseconds
|
|
55
|
+
const steps = 180; // number of steps for the transition
|
|
56
|
+
const stepDuration = duration / steps; // duration of each step
|
|
57
|
+
|
|
58
|
+
let currentBrightness = brightness;
|
|
59
|
+
let targetBrightness = minBrightness;
|
|
60
|
+
let currentSize = ObjectSize;
|
|
61
|
+
let targetSize = maxSize;
|
|
62
|
+
let step = 0;
|
|
63
|
+
|
|
64
|
+
// Clear any existing transition interval
|
|
65
|
+
if (transitionInterval) {
|
|
66
|
+
clearInterval(transitionInterval);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
transitionInterval = setInterval(() => {
|
|
70
|
+
step++;
|
|
71
|
+
currentBrightness =
|
|
72
|
+
currentBrightness - (currentBrightness - targetBrightness) / steps;
|
|
73
|
+
currentSize = currentSize - (currentSize - targetSize) / steps;
|
|
74
|
+
setBrightness(currentBrightness);
|
|
75
|
+
setObjectSize(currentSize);
|
|
76
|
+
|
|
77
|
+
if (step === steps) {
|
|
78
|
+
if (transitionInterval) {
|
|
79
|
+
clearInterval(transitionInterval);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}, stepDuration);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Add event listeners to trigger handleEnd on touch end or mouse up
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
const handleEndEvent = () => {
|
|
88
|
+
handleEnd();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
window.addEventListener("touchend", handleEndEvent);
|
|
92
|
+
window.addEventListener("mouseup", handleEndEvent);
|
|
93
|
+
|
|
94
|
+
return () => {
|
|
95
|
+
window.removeEventListener("touchend", handleEndEvent);
|
|
96
|
+
window.removeEventListener("mouseup", handleEndEvent);
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
// Add event listeners to trigger handleStart on touch start or mouse down
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const handleStartEvent = () => {
|
|
103
|
+
handleStart();
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
window.addEventListener("touchstart", handleStartEvent);
|
|
107
|
+
window.addEventListener("mousedown", handleStartEvent);
|
|
108
|
+
|
|
109
|
+
return () => {
|
|
110
|
+
window.removeEventListener("touchstart", handleStartEvent);
|
|
111
|
+
window.removeEventListener("mousedown", handleStartEvent);
|
|
112
|
+
};
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
// Add event listeners to trigger handleMove on touch move or mouse move
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
const handleMoveEvent = (e: TouchEvent | MouseEvent) => {
|
|
118
|
+
const x = e instanceof TouchEvent ? e.touches[0].clientX : e.clientX;
|
|
119
|
+
const y = e instanceof TouchEvent ? e.touches[0].clientY : e.clientY;
|
|
120
|
+
handleMove(x, y);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
window.addEventListener("touchmove", handleMoveEvent);
|
|
124
|
+
window.addEventListener("mousemove", handleMoveEvent);
|
|
125
|
+
|
|
126
|
+
return () => {
|
|
127
|
+
window.removeEventListener("touchmove", handleMoveEvent);
|
|
128
|
+
window.removeEventListener("mousemove", handleMoveEvent);
|
|
129
|
+
};
|
|
130
|
+
}, []);
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div
|
|
134
|
+
style={{
|
|
135
|
+
position: "fixed",
|
|
136
|
+
top: 0,
|
|
137
|
+
left: 0,
|
|
138
|
+
width: "100vw",
|
|
139
|
+
height: "100vh",
|
|
140
|
+
zIndex: -1,
|
|
141
|
+
pointerEvents: "none",
|
|
142
|
+
isolation: "isolate",
|
|
143
|
+
}}
|
|
144
|
+
>
|
|
145
|
+
<div
|
|
146
|
+
id="background"
|
|
147
|
+
style={{
|
|
148
|
+
position: "absolute",
|
|
149
|
+
top: 0,
|
|
150
|
+
left: 0,
|
|
151
|
+
display: "Block",
|
|
152
|
+
width: "100%",
|
|
153
|
+
height: "100%",
|
|
154
|
+
background: "#2d2d2d",
|
|
155
|
+
zIndex: -1,
|
|
156
|
+
}}
|
|
157
|
+
/>
|
|
158
|
+
<svg
|
|
159
|
+
id="object"
|
|
160
|
+
width={`${ObjectSize}px`}
|
|
161
|
+
height={`${ObjectSize}px`}
|
|
162
|
+
style={{
|
|
163
|
+
position: "absolute",
|
|
164
|
+
top: `${objectY}px`,
|
|
165
|
+
left: `${objectX}px`,
|
|
166
|
+
transform: "translate(-50%, -50%)",
|
|
167
|
+
}}
|
|
168
|
+
>
|
|
169
|
+
<defs>
|
|
170
|
+
<mask id="radial-gradient-mask">
|
|
171
|
+
<radialGradient
|
|
172
|
+
id="gradient"
|
|
173
|
+
cx="50%"
|
|
174
|
+
cy="50%"
|
|
175
|
+
r="50%"
|
|
176
|
+
fx="50%"
|
|
177
|
+
fy="50%"
|
|
178
|
+
>
|
|
179
|
+
<stop offset="0%" stopColor="white" />
|
|
180
|
+
<stop offset="100%" stopColor="black" />
|
|
181
|
+
</radialGradient>
|
|
182
|
+
<rect width="100%" height="100%" fill="url(#gradient)" />
|
|
183
|
+
</mask>
|
|
184
|
+
</defs>
|
|
185
|
+
<rect
|
|
186
|
+
width="100%"
|
|
187
|
+
height="100%"
|
|
188
|
+
fill="#439392"
|
|
189
|
+
mask="url(#radial-gradient-mask)"
|
|
190
|
+
style={{ filter: `brightness(${brightness})` }}
|
|
191
|
+
/>
|
|
192
|
+
</svg>
|
|
193
|
+
|
|
194
|
+
<svg
|
|
195
|
+
id="foreground"
|
|
196
|
+
style={{ position: "absolute", minWidth: "100%", minHeight: "100%" }}
|
|
197
|
+
viewBox="0 0 7680 4320 "
|
|
198
|
+
>
|
|
199
|
+
<defs>
|
|
200
|
+
<mask id="mask">
|
|
201
|
+
<rect width={"100%"} height={"100%"} fill="white" />
|
|
202
|
+
<text
|
|
203
|
+
transform="translate(-1000 200) rotate(-15)"
|
|
204
|
+
style={{
|
|
205
|
+
fill: "#000",
|
|
206
|
+
fontFamily: "Merriweather-Bold, Merriweather",
|
|
207
|
+
fontSize: "360px",
|
|
208
|
+
fontWeight: 700,
|
|
209
|
+
letterSpacing: ".055em",
|
|
210
|
+
}}
|
|
211
|
+
>
|
|
212
|
+
<tspan x="0" y="0">
|
|
213
|
+
JELLE PAULUS IS A TALENTED WEB DEVELOPER AND{" "}
|
|
214
|
+
</tspan>
|
|
215
|
+
<tspan x="0" y="432">
|
|
216
|
+
DESIGNER WITH A PASSION FOR CREATING VISUALLY{" "}
|
|
217
|
+
</tspan>
|
|
218
|
+
<tspan x="0" y="864">
|
|
219
|
+
STUNNING AND USER-FRIENDLY WEBSITES. WITH A{" "}
|
|
220
|
+
</tspan>
|
|
221
|
+
<tspan x="0" y="1296">
|
|
222
|
+
KEEN EYE FOR DETAIL AND A FOCUS ON CREATING{" "}
|
|
223
|
+
</tspan>
|
|
224
|
+
<tspan x="0" y="1728">
|
|
225
|
+
CLEAN, FUNCTIONAL DESIGNS, JELLE HAS A{" "}
|
|
226
|
+
</tspan>
|
|
227
|
+
<tspan x="0" y="2160">
|
|
228
|
+
REPUTATION FOR DELIVERING HIGH-QUALITY WORK{" "}
|
|
229
|
+
</tspan>
|
|
230
|
+
<tspan x="0" y="2592">
|
|
231
|
+
THAT EXCEEDS HIS CLIENTS' EXPECTATIONS. HE HAS A{" "}
|
|
232
|
+
</tspan>
|
|
233
|
+
<tspan x="0" y="3024">
|
|
234
|
+
DEEP UNDERSTANDING OF THE LATEST WEB{" "}
|
|
235
|
+
</tspan>
|
|
236
|
+
<tspan x="0" y="3456">
|
|
237
|
+
DEVELOPMENT TECHNOLOGIES, AND IS ABLE TO{" "}
|
|
238
|
+
</tspan>
|
|
239
|
+
<tspan x="0" y="3888">
|
|
240
|
+
SEAMLESSLY INTEGRATE FUNCTIONALITY AND{" "}
|
|
241
|
+
</tspan>
|
|
242
|
+
<tspan x="0" y="4320">
|
|
243
|
+
AESTHETICS TO CREATE WEBSITES THAT ARE BOTH{" "}
|
|
244
|
+
</tspan>
|
|
245
|
+
<tspan x="0" y="4752">
|
|
246
|
+
FUNCTIONAL AND VISUALLY APPEALING. WHETHER{" "}
|
|
247
|
+
</tspan>
|
|
248
|
+
<tspan x="0" y="5184">
|
|
249
|
+
YOU'RE LOOKING TO ESTABLISH AN ONLINE PRESENCE{" "}
|
|
250
|
+
</tspan>
|
|
251
|
+
<tspan x="0" y="5616">
|
|
252
|
+
OR REVAMP AN EXISTING WEBSITE, JELLE HAS THE{" "}
|
|
253
|
+
</tspan>
|
|
254
|
+
<tspan x="0" y="6048">
|
|
255
|
+
SKILLS AND EXPERTISE TO BRING YOUR VISION TO LIFE.
|
|
256
|
+
</tspan>
|
|
257
|
+
</text>
|
|
258
|
+
</mask>
|
|
259
|
+
</defs>
|
|
260
|
+
<rect
|
|
261
|
+
width={"100%"}
|
|
262
|
+
height={"100%"}
|
|
263
|
+
fill="#222"
|
|
264
|
+
mask="url(#mask)"
|
|
265
|
+
></rect>
|
|
266
|
+
</svg>
|
|
267
|
+
</div>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export default FluidBackground;
|
package/src/index.js
CHANGED
|
@@ -10,3 +10,4 @@ export { default as BulletList } from "./components/BulletList";
|
|
|
10
10
|
export { default as WhatsAppClickToChatButton } from "./components/WhatsAppClickToChatButton.tsx";
|
|
11
11
|
export { default as ScrollLink } from "./components/ScrollLink.tsx";
|
|
12
12
|
export { default as ScrollNavbar } from "./components/ScrollNavbar.tsx";
|
|
13
|
+
export { default as FluidBackground } from "./components/FluidBackground.tsx";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import FluidBackground from "../components/FluidBackground.tsx";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "UMWD/FluidBackground",
|
|
6
|
+
component: FluidBackground,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const Template = ({ ...args }) => {
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
<FluidBackground {...args} />
|
|
13
|
+
</>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/* export const Orefs = Template.bind({});
|
|
18
|
+
|
|
19
|
+
Orefs.args = {};
|
|
20
|
+
|
|
21
|
+
export const UMWD = Template.bind({});
|
|
22
|
+
|
|
23
|
+
UMWD.args = {}; */
|
|
24
|
+
|
|
25
|
+
export const AMH = Template.bind({});
|
|
26
|
+
|
|
27
|
+
AMH.args = {
|
|
28
|
+
data: {},
|
|
29
|
+
};
|