create-openfort 0.1.8 → 0.1.10
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/CHANGELOG.md +12 -0
- package/dist/index.js +16 -16
- package/package.json +1 -1
- package/template/backend/package.json +7 -1
- package/template/backend/pnpm-lock.yaml +187 -33
- package/template/backend/src/app.ts +1 -1
- package/template/openfort-templates/firebase/biome.json +3 -3
- package/template/openfort-templates/firebase/package.json +1 -1
- package/template/openfort-templates/firebase/src/App.tsx +10 -10
- package/template/openfort-templates/firebase/src/components/cards/head.tsx +157 -145
- package/template/openfort-templates/firebase/src/components/cards/main.tsx +63 -52
- package/template/openfort-templates/firebase/src/components/ui/Sheet.tsx +14 -16
- package/template/openfort-templates/firebase/src/components/ui/Tabs.tsx +46 -36
- package/template/openfort-templates/firebase/src/components/ui/TruncateData.tsx +14 -8
- package/template/openfort-templates/firebase/src/integrations/firebase/client.ts +6 -6
- package/template/openfort-templates/firebase/src/integrations/firebase/components/FirebaseAuthCard.tsx +74 -46
- package/template/openfort-templates/firebase/src/integrations/firebase/errors.ts +57 -37
- package/template/openfort-templates/firebase/src/integrations/firebase/index.ts +3 -3
- package/template/openfort-templates/firebase/src/integrations/openfort/index.ts +1 -1
- package/template/openfort-templates/firebase/src/integrations/openfort/providers.tsx +23 -11
- package/template/openfort-templates/firebase/src/ui/openfort/blockchain/ActionsCard.tsx +47 -35
- package/template/openfort-templates/firebase/src/ui/openfort/blockchain/SignCard.tsx +30 -28
- package/template/openfort-templates/firebase/src/ui/openfort/index.ts +4 -6
- package/template/openfort-templates/firebase/src/ui/openfort/profile/UserProfileCard.tsx +32 -20
- package/template/openfort-templates/firebase/src/ui/openfort/wallets/WalletCreation.tsx +51 -27
- package/template/openfort-templates/firebase/src/ui/openfort/wallets/WalletListCard.tsx +66 -40
- package/template/openfort-templates/firebase/src/ui/openfort/wallets/WalletPasswordSheets.tsx +65 -41
- package/template/openfort-templates/firebase/vite.config.ts +3 -3
- package/template/openfort-templates/headless/biome.json +3 -3
- package/template/openfort-templates/headless/package.json +1 -1
- package/template/openfort-templates/headless/src/components/cards/auth.tsx +2 -2
- package/template/openfort-templates/headless/src/components/cards/profile.tsx +1 -3
- package/template/openfort-templates/headless/src/components/providers.tsx +4 -1
- package/template/openfort-templates/headless/src/index.css +10 -4
- package/template/openfort-templates/openfort-ui/biome.json +3 -3
- package/template/openfort-templates/openfort-ui/package.json +1 -1
- package/template/openfort-templates/openfort-ui/src/App.tsx +1 -3
- package/template/openfort-templates/openfort-ui/src/components/cards/auth.tsx +9 -11
- package/template/openfort-templates/openfort-ui/src/components/cards/head.tsx +157 -145
- package/template/openfort-templates/openfort-ui/src/components/cards/main.tsx +50 -41
- package/template/openfort-templates/openfort-ui/src/components/cards/profile.tsx +29 -35
- package/template/openfort-templates/openfort-ui/src/components/cards/sign.tsx +35 -49
- package/template/openfort-templates/openfort-ui/src/components/cards/wallets.tsx +51 -37
- package/template/openfort-templates/openfort-ui/src/components/createWallet.tsx +63 -30
- package/template/openfort-templates/openfort-ui/src/components/passwordRecovery.tsx +61 -56
- package/template/openfort-templates/openfort-ui/src/components/providers.tsx +14 -15
- package/template/openfort-templates/openfort-ui/src/components/ui/Sheet.tsx +14 -16
- package/template/openfort-templates/openfort-ui/src/components/ui/Tabs.tsx +46 -36
- package/template/openfort-templates/openfort-ui/src/components/ui/TruncateData.tsx +14 -8
- package/template/openfort-templates/openfort-ui/vite.config.ts +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://biomejs.dev/schemas/2.
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
|
|
3
3
|
"root": true,
|
|
4
4
|
"vcs": {
|
|
5
5
|
"enabled": true,
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
"useIgnoreFile": true
|
|
8
8
|
},
|
|
9
9
|
"files": {
|
|
10
|
-
"ignoreUnknown": true
|
|
10
|
+
"ignoreUnknown": true,
|
|
11
|
+
"includes": ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"]
|
|
11
12
|
},
|
|
12
13
|
"formatter": {
|
|
13
14
|
"enabled": true,
|
|
@@ -49,7 +50,6 @@
|
|
|
49
50
|
},
|
|
50
51
|
"overrides": [
|
|
51
52
|
{
|
|
52
|
-
"includes": ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
|
|
53
53
|
"linter": {
|
|
54
54
|
"rules": {
|
|
55
55
|
"correctness": {
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
+
import { useSignOut, useUser } from '@openfort/react'
|
|
1
2
|
import { useEffect } from 'react'
|
|
2
3
|
import { Main } from './components/cards/main'
|
|
3
4
|
import { auth } from './integrations/firebase'
|
|
4
|
-
import { useSignOut, useUser } from '@openfort/react'
|
|
5
5
|
|
|
6
6
|
function App() {
|
|
7
|
-
const { getAccessToken } = useUser()
|
|
8
|
-
const { signOut } = useSignOut()
|
|
7
|
+
const { getAccessToken } = useUser()
|
|
8
|
+
const { signOut } = useSignOut()
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
|
-
auth.onAuthStateChanged(user => {
|
|
12
|
-
console.log(
|
|
11
|
+
auth.onAuthStateChanged((user) => {
|
|
12
|
+
console.log('onAuthStateChanged')
|
|
13
13
|
if (user) {
|
|
14
|
-
console.log(
|
|
15
|
-
getAccessToken()
|
|
14
|
+
console.log('onAuthStateChanged - User is signed in:', user)
|
|
15
|
+
getAccessToken()
|
|
16
16
|
} else {
|
|
17
|
-
console.log(
|
|
18
|
-
signOut()
|
|
17
|
+
console.log('onAuthStateChanged - No user is signed in')
|
|
18
|
+
signOut()
|
|
19
19
|
}
|
|
20
|
-
})
|
|
20
|
+
})
|
|
21
21
|
}, [])
|
|
22
22
|
|
|
23
23
|
return (
|
|
@@ -1,68 +1,75 @@
|
|
|
1
|
-
import { useEffect, useMemo, useRef, useState } from
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
type RoutePoint = {
|
|
4
|
-
x: number
|
|
5
|
-
y: number
|
|
6
|
-
delay: number
|
|
7
|
-
}
|
|
4
|
+
x: number
|
|
5
|
+
y: number
|
|
6
|
+
delay: number
|
|
7
|
+
}
|
|
8
8
|
|
|
9
9
|
type Route = {
|
|
10
|
-
start: RoutePoint
|
|
11
|
-
end: RoutePoint
|
|
12
|
-
color: string
|
|
13
|
-
outDelay?: number
|
|
14
|
-
}
|
|
10
|
+
start: RoutePoint
|
|
11
|
+
end: RoutePoint
|
|
12
|
+
color: string
|
|
13
|
+
outDelay?: number
|
|
14
|
+
}
|
|
15
15
|
|
|
16
16
|
function withOpacity(color: string, opacity: number) {
|
|
17
|
-
if (color.startsWith(
|
|
18
|
-
const nums = color.match(/[\d.]+/g)?.map(Number)
|
|
19
|
-
if (!nums || nums.length < 3) throw new Error(
|
|
20
|
-
const [r, g, b] = nums
|
|
21
|
-
return `rgba(${r}, ${g}, ${b}, ${opacity})
|
|
17
|
+
if (color.startsWith('rgb')) {
|
|
18
|
+
const nums = color.match(/[\d.]+/g)?.map(Number)
|
|
19
|
+
if (!nums || nums.length < 3) throw new Error('Invalid rgb format')
|
|
20
|
+
const [r, g, b] = nums
|
|
21
|
+
return `rgba(${r}, ${g}, ${b}, ${opacity})`
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
throw new Error(
|
|
24
|
+
throw new Error(`Unsupported color format: ${color}`)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const GlowCanvas = ({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const GlowCanvas = ({
|
|
28
|
+
accentColor,
|
|
29
|
+
backgroundColor,
|
|
30
|
+
}: {
|
|
31
|
+
accentColor: string
|
|
32
|
+
backgroundColor: string
|
|
33
|
+
}) => {
|
|
34
|
+
const canvasRef = useRef<HTMLCanvasElement | null>(null)
|
|
35
|
+
const mousePosRef = useRef<{ x: number; y: number } | null>(null)
|
|
36
|
+
const animationRef = useRef<number | null>(null)
|
|
31
37
|
|
|
32
|
-
const [dimensions, setDimensions] = useState({ width: 0, height: 0 })
|
|
38
|
+
const [dimensions, setDimensions] = useState({ width: 0, height: 0 })
|
|
33
39
|
|
|
34
|
-
const color = useMemo(() => withOpacity(accentColor, 0.7), [accentColor])
|
|
40
|
+
const color = useMemo(() => withOpacity(accentColor, 0.7), [accentColor])
|
|
35
41
|
|
|
36
42
|
useEffect(() => {
|
|
37
|
-
const canvas = canvasRef.current
|
|
38
|
-
if (!canvas) return
|
|
43
|
+
const canvas = canvasRef.current
|
|
44
|
+
if (!canvas) return
|
|
39
45
|
|
|
40
|
-
const resizeObserver = new ResizeObserver(entries => {
|
|
41
|
-
const { width, height } = entries[0].contentRect
|
|
42
|
-
setDimensions({ width, height })
|
|
43
|
-
canvas.width = width
|
|
44
|
-
canvas.height = height
|
|
45
|
-
})
|
|
46
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
47
|
+
const { width, height } = entries[0].contentRect
|
|
48
|
+
setDimensions({ width, height })
|
|
49
|
+
canvas.width = width
|
|
50
|
+
canvas.height = height
|
|
51
|
+
})
|
|
46
52
|
|
|
47
|
-
resizeObserver.observe(canvas.parentElement as Element)
|
|
48
|
-
return () => resizeObserver.disconnect()
|
|
49
|
-
}, [])
|
|
53
|
+
resizeObserver.observe(canvas.parentElement as Element)
|
|
54
|
+
return () => resizeObserver.disconnect()
|
|
55
|
+
}, [])
|
|
50
56
|
|
|
51
57
|
useEffect(() => {
|
|
52
|
-
if (!dimensions.width || !dimensions.height) return
|
|
58
|
+
if (!dimensions.width || !dimensions.height) return
|
|
53
59
|
|
|
54
|
-
let startTime = Date.now()
|
|
60
|
+
let startTime = Date.now()
|
|
55
61
|
|
|
56
|
-
const canvas = canvasRef.current
|
|
57
|
-
if (!canvas) return
|
|
58
|
-
const ctx = canvas.getContext(
|
|
59
|
-
if (!ctx) return
|
|
62
|
+
const canvas = canvasRef.current
|
|
63
|
+
if (!canvas) return
|
|
64
|
+
const ctx = canvas.getContext('2d')
|
|
65
|
+
if (!ctx) return
|
|
60
66
|
|
|
61
|
-
const gap = 14
|
|
62
|
-
const dotRadius = 1.5
|
|
67
|
+
const gap = 14
|
|
68
|
+
const dotRadius = 1.5
|
|
63
69
|
|
|
64
70
|
const generateDots = (width: number, height: number) => {
|
|
65
|
-
const dots: { x: number; y: number; radius: number; opacity: number }[] =
|
|
71
|
+
const dots: { x: number; y: number; radius: number; opacity: number }[] =
|
|
72
|
+
[]
|
|
66
73
|
|
|
67
74
|
for (let x = 0; x < width; x += gap) {
|
|
68
75
|
for (let y = 0; y < height; y += gap) {
|
|
@@ -72,62 +79,63 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
|
|
|
72
79
|
y,
|
|
73
80
|
radius: dotRadius,
|
|
74
81
|
opacity: Math.random() * 0.4 + 0.1,
|
|
75
|
-
})
|
|
82
|
+
})
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
}
|
|
79
|
-
return dots
|
|
80
|
-
}
|
|
81
|
-
const dots = generateDots(dimensions.width, dimensions.height)
|
|
86
|
+
return dots
|
|
87
|
+
}
|
|
88
|
+
const dots = generateDots(dimensions.width, dimensions.height)
|
|
82
89
|
|
|
83
90
|
const draw = () => {
|
|
84
|
-
ctx.clearRect(0, 0, dimensions.width, dimensions.height)
|
|
91
|
+
ctx.clearRect(0, 0, dimensions.width, dimensions.height)
|
|
85
92
|
|
|
86
93
|
if (mousePosRef.current) {
|
|
87
|
-
const { x, y } = mousePosRef.current
|
|
94
|
+
const { x, y } = mousePosRef.current
|
|
88
95
|
|
|
89
|
-
ctx.shadowBlur = 25
|
|
90
|
-
ctx.shadowColor = backgroundColor
|
|
96
|
+
ctx.shadowBlur = 25
|
|
97
|
+
ctx.shadowColor = backgroundColor
|
|
91
98
|
|
|
92
|
-
dots.forEach(dot => {
|
|
93
|
-
const dx = dot.x - x
|
|
94
|
-
const dy = dot.y - y
|
|
95
|
-
const distance = Math.sqrt(dx * dx + dy * dy)
|
|
99
|
+
dots.forEach((dot) => {
|
|
100
|
+
const dx = dot.x - x
|
|
101
|
+
const dy = dot.y - y
|
|
102
|
+
const distance = Math.sqrt(dx * dx + dy * dy)
|
|
96
103
|
|
|
97
|
-
ctx.beginPath()
|
|
98
|
-
ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
|
|
104
|
+
ctx.beginPath()
|
|
105
|
+
ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
|
|
99
106
|
|
|
100
|
-
const opacityFactor = 1 - distance / 100
|
|
107
|
+
const opacityFactor = 1 - distance / 100
|
|
101
108
|
|
|
102
|
-
ctx.fillStyle = withOpacity(accentColor, opacityFactor)
|
|
103
|
-
ctx.fill()
|
|
104
|
-
})
|
|
109
|
+
ctx.fillStyle = withOpacity(accentColor, opacityFactor)
|
|
110
|
+
ctx.fill()
|
|
111
|
+
})
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
// Draw the dots
|
|
108
|
-
dots.forEach(dot => {
|
|
109
|
-
ctx.beginPath()
|
|
110
|
-
ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
|
|
111
|
-
ctx.fillStyle = withOpacity(backgroundColor, dot.opacity)
|
|
112
|
-
ctx.fill()
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
drawRoutes()
|
|
115
|
+
dots.forEach((dot) => {
|
|
116
|
+
ctx.beginPath()
|
|
117
|
+
ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2)
|
|
118
|
+
ctx.fillStyle = withOpacity(backgroundColor, dot.opacity)
|
|
119
|
+
ctx.fill()
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
drawRoutes()
|
|
116
123
|
// If all routes are complete, restart the animation
|
|
117
|
-
const currentTime = (Date.now() - startTime) / 1000
|
|
118
|
-
if (currentTime > 25) {
|
|
119
|
-
|
|
124
|
+
const currentTime = (Date.now() - startTime) / 1000
|
|
125
|
+
if (currentTime > 25) {
|
|
126
|
+
// Reset after 15 seconds
|
|
127
|
+
startTime = Date.now()
|
|
120
128
|
}
|
|
121
129
|
|
|
122
|
-
animationRef.current = requestAnimationFrame(draw)
|
|
123
|
-
}
|
|
130
|
+
animationRef.current = requestAnimationFrame(draw)
|
|
131
|
+
}
|
|
124
132
|
|
|
125
133
|
// Set up routes that will animate across the map
|
|
126
|
-
const yOffset = 50
|
|
127
|
-
const scale = 12
|
|
128
|
-
const h = 11 * scale
|
|
129
|
-
const w = 18 * scale
|
|
130
|
-
const xOffset = (dimensions.width - w) / 2
|
|
134
|
+
const yOffset = 50
|
|
135
|
+
const scale = 12
|
|
136
|
+
const h = 11 * scale
|
|
137
|
+
const w = 18 * scale
|
|
138
|
+
const xOffset = (dimensions.width - w) / 2
|
|
131
139
|
|
|
132
140
|
const routes: Route[] = [
|
|
133
141
|
{
|
|
@@ -156,26 +164,25 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
|
|
|
156
164
|
outDelay: 10,
|
|
157
165
|
},
|
|
158
166
|
{
|
|
159
|
-
start: { x: xOffset + 3 * w / 4, y: yOffset + h / 3, delay: 2 },
|
|
167
|
+
start: { x: xOffset + (3 * w) / 4, y: yOffset + h / 3, delay: 2 },
|
|
160
168
|
end: { x: xOffset + w / 4, y: yOffset + h / 3, delay: 4 },
|
|
161
169
|
color,
|
|
162
170
|
outDelay: 10,
|
|
163
171
|
},
|
|
164
172
|
{
|
|
165
|
-
start: { x: xOffset + 3 * w / 4, y: yOffset + h, delay: 0 },
|
|
166
|
-
end: { x: xOffset + 3 * w / 4, y: yOffset + h / 3, delay: 2 },
|
|
173
|
+
start: { x: xOffset + (3 * w) / 4, y: yOffset + h, delay: 0 },
|
|
174
|
+
end: { x: xOffset + (3 * w) / 4, y: yOffset + h / 3, delay: 2 },
|
|
167
175
|
color,
|
|
168
176
|
outDelay: 10,
|
|
169
177
|
},
|
|
170
178
|
|
|
171
179
|
{
|
|
172
|
-
start: { x: xOffset + 2 * w / 4, y: yOffset + h, delay: 6 },
|
|
173
|
-
end: { x: xOffset + 2 * w / 4, y: yOffset + 2 * h / 3, delay: 7 },
|
|
180
|
+
start: { x: xOffset + (2 * w) / 4, y: yOffset + h, delay: 6 },
|
|
181
|
+
end: { x: xOffset + (2 * w) / 4, y: yOffset + (2 * h) / 3, delay: 7 },
|
|
174
182
|
color,
|
|
175
183
|
outDelay: 10,
|
|
176
184
|
},
|
|
177
185
|
|
|
178
|
-
|
|
179
186
|
{
|
|
180
187
|
start: { x: 200, y: 280, delay: 2 },
|
|
181
188
|
end: { x: 260, y: 420, delay: 4 },
|
|
@@ -198,89 +205,96 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
|
|
|
198
205
|
end: { x: 180, y: 520, delay: 20 },
|
|
199
206
|
color,
|
|
200
207
|
},
|
|
201
|
-
]
|
|
208
|
+
]
|
|
202
209
|
|
|
203
210
|
function drawRoutes() {
|
|
204
|
-
if (!ctx) return
|
|
211
|
+
if (!ctx) return
|
|
205
212
|
|
|
206
|
-
const debug = false
|
|
213
|
+
const debug = false
|
|
207
214
|
// const debug = true;
|
|
208
215
|
|
|
209
|
-
const currentTime = (Date.now() - startTime) / 1000
|
|
210
|
-
routes.forEach(route => {
|
|
211
|
-
const elapsed = debug ? 100 : currentTime - route.start.delay
|
|
212
|
-
if (elapsed <= 0) return
|
|
216
|
+
const currentTime = (Date.now() - startTime) / 1000 // Time in seconds
|
|
217
|
+
routes.forEach((route) => {
|
|
218
|
+
const elapsed = debug ? 100 : currentTime - route.start.delay
|
|
219
|
+
if (elapsed <= 0) return
|
|
213
220
|
|
|
214
|
-
const duration = route.end.delay - route.start.delay
|
|
215
|
-
const progress = Math.min(elapsed / duration, 1)
|
|
221
|
+
const duration = route.end.delay - route.start.delay // animation duration
|
|
222
|
+
const progress = Math.min(elapsed / duration, 1) // normal progress
|
|
216
223
|
|
|
217
224
|
// Fade from end to start after the line is fully drawn
|
|
218
|
-
let startProgress = 0
|
|
219
|
-
const outDelay = route.outDelay || 0
|
|
225
|
+
let startProgress = 0 // the starting point along the line
|
|
226
|
+
const outDelay = route.outDelay || 0
|
|
220
227
|
if (elapsed > duration + outDelay) {
|
|
221
|
-
const fadeProgress = Math.min(
|
|
222
|
-
|
|
228
|
+
const fadeProgress = Math.min(
|
|
229
|
+
(elapsed - (duration + outDelay)) / duration,
|
|
230
|
+
1,
|
|
231
|
+
)
|
|
232
|
+
startProgress = fadeProgress // move the start point forward
|
|
223
233
|
}
|
|
224
234
|
|
|
225
235
|
// Line vector
|
|
226
|
-
const dx = route.end.x - route.start.x
|
|
227
|
-
const dy = route.end.y - route.start.y
|
|
236
|
+
const dx = route.end.x - route.start.x
|
|
237
|
+
const dy = route.end.y - route.start.y
|
|
228
238
|
|
|
229
239
|
for (let x = 0; x < dimensions.width; x += gap) {
|
|
230
240
|
for (let y = 0; y < dimensions.height; y += gap) {
|
|
231
|
-
const t =
|
|
232
|
-
|
|
241
|
+
const t =
|
|
242
|
+
((x - route.start.x) * dx + (y - route.start.y) * dy) /
|
|
243
|
+
(dx * dx + dy * dy)
|
|
244
|
+
if (t < startProgress || t > progress) continue // only show dots in the visible segment
|
|
233
245
|
|
|
234
|
-
const closestX = route.start.x + dx * t
|
|
235
|
-
const closestY = route.start.y + dy * t
|
|
236
|
-
const distance = Math.hypot(x - closestX, y - closestY)
|
|
246
|
+
const closestX = route.start.x + dx * t
|
|
247
|
+
const closestY = route.start.y + dy * t
|
|
248
|
+
const distance = Math.hypot(x - closestX, y - closestY)
|
|
237
249
|
|
|
238
250
|
if (distance < gap) {
|
|
239
|
-
ctx.beginPath()
|
|
240
|
-
ctx.arc(x, y, dotRadius, 0, Math.PI * 2)
|
|
251
|
+
ctx.beginPath()
|
|
252
|
+
ctx.arc(x, y, dotRadius, 0, Math.PI * 2)
|
|
241
253
|
|
|
242
254
|
// Fade in: opacity goes from 0 → 1 as `progress` grows
|
|
243
|
-
const opacity = Math.min(
|
|
244
|
-
|
|
255
|
+
const opacity = Math.min(
|
|
256
|
+
1,
|
|
257
|
+
Math.max(0, Math.min(t - startProgress, progress - t) * 5),
|
|
258
|
+
)
|
|
259
|
+
ctx.fillStyle = withOpacity(route.color, opacity)
|
|
245
260
|
|
|
246
|
-
ctx.fill()
|
|
261
|
+
ctx.fill()
|
|
247
262
|
}
|
|
248
263
|
}
|
|
249
264
|
}
|
|
250
265
|
|
|
251
266
|
if (debug) {
|
|
252
|
-
const xStart = route.start.x
|
|
253
|
-
const yStart = route.start.y
|
|
254
|
-
const xEnd = route.start.x + dx * progress
|
|
255
|
-
const yEnd = route.start.y + dy * progress
|
|
256
|
-
|
|
257
|
-
ctx.beginPath()
|
|
258
|
-
ctx.moveTo(xStart, yStart)
|
|
259
|
-
ctx.lineTo(xEnd, yEnd)
|
|
260
|
-
ctx.strokeStyle = route.color
|
|
261
|
-
ctx.lineWidth = 1.5
|
|
262
|
-
ctx.stroke()
|
|
263
|
-
|
|
264
|
-
ctx.beginPath()
|
|
265
|
-
ctx.arc(xEnd, yEnd, 3, 0, Math.PI * 2)
|
|
266
|
-
ctx.fillStyle = route.color
|
|
267
|
-
ctx.fill()
|
|
267
|
+
const xStart = route.start.x
|
|
268
|
+
const yStart = route.start.y
|
|
269
|
+
const xEnd = route.start.x + dx * progress
|
|
270
|
+
const yEnd = route.start.y + dy * progress
|
|
271
|
+
|
|
272
|
+
ctx.beginPath()
|
|
273
|
+
ctx.moveTo(xStart, yStart)
|
|
274
|
+
ctx.lineTo(xEnd, yEnd)
|
|
275
|
+
ctx.strokeStyle = route.color
|
|
276
|
+
ctx.lineWidth = 1.5
|
|
277
|
+
ctx.stroke()
|
|
278
|
+
|
|
279
|
+
ctx.beginPath()
|
|
280
|
+
ctx.arc(xEnd, yEnd, 3, 0, Math.PI * 2)
|
|
281
|
+
ctx.fillStyle = route.color
|
|
282
|
+
ctx.fill()
|
|
268
283
|
}
|
|
269
|
-
})
|
|
284
|
+
})
|
|
270
285
|
}
|
|
271
286
|
|
|
272
|
-
|
|
273
287
|
const handleMouseMove = (e: MouseEvent) => {
|
|
274
|
-
const rect = canvas.getBoundingClientRect()
|
|
288
|
+
const rect = canvas.getBoundingClientRect()
|
|
275
289
|
mousePosRef.current = {
|
|
276
290
|
x: e.x - rect.left,
|
|
277
291
|
y: e.y - rect.top,
|
|
278
|
-
}
|
|
279
|
-
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
280
294
|
|
|
281
|
-
document.addEventListener(
|
|
295
|
+
document.addEventListener('mousemove', handleMouseMove)
|
|
282
296
|
|
|
283
|
-
draw()
|
|
297
|
+
draw()
|
|
284
298
|
|
|
285
299
|
return () => {
|
|
286
300
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
@@ -293,8 +307,8 @@ const GlowCanvas = ({ accentColor, backgroundColor }: { accentColor: string, bac
|
|
|
293
307
|
ref={canvasRef}
|
|
294
308
|
className="absolute inset-0 w-full h-full pointer-events-none"
|
|
295
309
|
/>
|
|
296
|
-
)
|
|
297
|
-
}
|
|
310
|
+
)
|
|
311
|
+
}
|
|
298
312
|
|
|
299
313
|
export const Head = ({
|
|
300
314
|
onStart,
|
|
@@ -315,11 +329,11 @@ export const Head = ({
|
|
|
315
329
|
}) => {
|
|
316
330
|
return (
|
|
317
331
|
<div
|
|
318
|
-
className=
|
|
332
|
+
className="bg-zinc-900 w-(--card-width) flex flex-col items-center justify-center text-center relative"
|
|
319
333
|
style={{ '--color-sample': backgroundColor } as React.CSSProperties}
|
|
320
334
|
>
|
|
321
335
|
<div>
|
|
322
|
-
<a href="https://openfort.io/" target="_blank">
|
|
336
|
+
<a href="https://openfort.io/" target="_blank" rel="noopener">
|
|
323
337
|
<img src="/openfort.svg" className="logo" alt="Openfort logo" />
|
|
324
338
|
</a>
|
|
325
339
|
<a href={href} target="_blank">
|
|
@@ -327,22 +341,20 @@ export const Head = ({
|
|
|
327
341
|
</a>
|
|
328
342
|
</div>
|
|
329
343
|
<h1 className="text-4xl font-bold mb-4">
|
|
330
|
-
<span style={{ color: '#FC3627' }}>Openfort</span> +
|
|
344
|
+
<span style={{ color: '#FC3627' }}>Openfort</span> +{' '}
|
|
345
|
+
<span style={{ color }}>{sample}</span>
|
|
331
346
|
</h1>
|
|
332
|
-
{
|
|
333
|
-
subtitle && <p className="mb-6 text-sm max-w-2/3">{subtitle}</p>
|
|
334
|
-
}
|
|
347
|
+
{subtitle && <p className="mb-6 text-sm max-w-2/3">{subtitle}</p>}
|
|
335
348
|
<button
|
|
336
349
|
className="lg:hidden mt-4 px-6 py-2 border border-zinc-500 rounded hover:bg-zinc-500/10 transition-colors cursor-pointer"
|
|
337
350
|
onClick={onStart}
|
|
338
351
|
>
|
|
339
352
|
Click here to Start
|
|
340
353
|
</button>
|
|
341
|
-
<p className="absolute text-zinc-400 mb-6 text-sm bottom-0">
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
/>
|
|
354
|
+
<p className="absolute text-zinc-400 mb-6 text-sm bottom-0">
|
|
355
|
+
Sign in to explore openfort capabilities.
|
|
356
|
+
</p>
|
|
357
|
+
<GlowCanvas accentColor={color} backgroundColor={backgroundColor} />
|
|
346
358
|
</div>
|
|
347
359
|
)
|
|
348
360
|
}
|