mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-04-11 17:29:44 +00:00
feat: add globe component
This commit is contained in:
parent
5dbfab986a
commit
9bf35e7fb7
@ -84,6 +84,7 @@
|
|||||||
"@shikijs/themes": "^2.3.2",
|
"@shikijs/themes": "^2.3.2",
|
||||||
"@std/semver": "npm:@jsr/std__semver@^1.0.3",
|
"@std/semver": "npm:@jsr/std__semver@^1.0.3",
|
||||||
"@tanstack/svelte-virtual": "^3.13.2",
|
"@tanstack/svelte-virtual": "^3.13.2",
|
||||||
|
"cobe": "^0.6.3",
|
||||||
"dompurify": "^3.2.3",
|
"dompurify": "^3.2.3",
|
||||||
"fuse.js": "^7.1.0",
|
"fuse.js": "^7.1.0",
|
||||||
"gsap": "^3.12.7",
|
"gsap": "^3.12.7",
|
||||||
|
119
packages/ui/src/components/animation/Globe.svelte
Normal file
119
packages/ui/src/components/animation/Globe.svelte
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import createGlobe from "cobe"
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
import { Spring, spring } from "svelte/motion"
|
||||||
|
import { cn } from "../../utils"
|
||||||
|
|
||||||
|
let x = spring(0, {
|
||||||
|
stiffness: 0.04,
|
||||||
|
damping: 0.4,
|
||||||
|
precision: 0.005
|
||||||
|
})
|
||||||
|
|
||||||
|
// let className = ""
|
||||||
|
// export { className as class }
|
||||||
|
let { locations = [], class: className }: { class?: string; locations?: [number, number][] } =
|
||||||
|
$props()
|
||||||
|
let pointerInteracting: any = null
|
||||||
|
let pointerInteractionMovement = 0
|
||||||
|
let canvas: HTMLCanvasElement
|
||||||
|
|
||||||
|
let phi = 0
|
||||||
|
let width = 0
|
||||||
|
// $: console.log(width, "X")
|
||||||
|
let onResize = () => {
|
||||||
|
width = canvas.offsetWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
let onRender = (state: any) => {
|
||||||
|
if (!pointerInteracting) {
|
||||||
|
phi += 0.005
|
||||||
|
}
|
||||||
|
state.phi = phi + $x
|
||||||
|
state.width = width * 2
|
||||||
|
state.height = width * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
// Adds the resize event listener when the component is mounted
|
||||||
|
window.addEventListener("resize", onResize)
|
||||||
|
onResize()
|
||||||
|
|
||||||
|
// Initializes the globe with specific options
|
||||||
|
const globe = createGlobe(canvas, {
|
||||||
|
devicePixelRatio: 2,
|
||||||
|
width: width,
|
||||||
|
height: width,
|
||||||
|
phi: 0,
|
||||||
|
theta: 0.3,
|
||||||
|
dark: 1,
|
||||||
|
diffuse: 0.4, // 1.2
|
||||||
|
mapSamples: 16000,
|
||||||
|
mapBrightness: 1.2, // 6
|
||||||
|
baseColor: [0.3, 0.3, 0.3],
|
||||||
|
markerColor: [251 / 255, 100 / 255, 21 / 255],
|
||||||
|
glowColor: [1, 1, 1],
|
||||||
|
markers: locations.map((location) => {
|
||||||
|
return {
|
||||||
|
location: location,
|
||||||
|
size: 0.03
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
// [
|
||||||
|
// { location: [14.5995, 120.9842], size: 0.03 },
|
||||||
|
// { location: [19.076, 72.8777], size: 0.03 },
|
||||||
|
// { location: [23.8103, 90.4125], size: 0.05 },
|
||||||
|
// { location: [30.0444, 31.2357], size: 0.07 },
|
||||||
|
// { location: [39.9042, 116.4074], size: 0.08 },
|
||||||
|
// { location: [-23.5505, -46.6333], size: 0.05 },
|
||||||
|
// { location: [19.4326, -99.1332], size: 0.04 },
|
||||||
|
// { location: [40.7128, -74.006], size: 0.1 },
|
||||||
|
// { location: [34.6937, 135.5022], size: 0.05 },
|
||||||
|
// { location: [41.0082, 28.9784], size: 0.06 }
|
||||||
|
// ],
|
||||||
|
// onRender: (state) => {
|
||||||
|
// if (!pointerInteracting) {
|
||||||
|
// // Called on every animation frame.
|
||||||
|
// // `state` will be an empty object, return updated params.
|
||||||
|
// phi += 0.009;
|
||||||
|
// }
|
||||||
|
// state.phi = phi + $x;
|
||||||
|
|
||||||
|
// // phi += 0.01;
|
||||||
|
// },
|
||||||
|
onRender: onRender
|
||||||
|
})
|
||||||
|
|
||||||
|
// Removes the resize event listener when the component is unmounted to prevent memory leaks
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("resize", onResize)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main class={cn("absolute inset-0 mx-auto aspect-[1/1] w-full max-w-[600px]", className)}>
|
||||||
|
<canvas
|
||||||
|
class="h-full w-full [contain:layout_paint_size]"
|
||||||
|
bind:this={canvas}
|
||||||
|
onpointerdown={(e) => {
|
||||||
|
pointerInteracting = e.clientX - pointerInteractionMovement
|
||||||
|
canvas.style.cursor = "grabbing"
|
||||||
|
}}
|
||||||
|
onpointerup={() => {
|
||||||
|
pointerInteracting = null
|
||||||
|
canvas.style.cursor = "grab"
|
||||||
|
}}
|
||||||
|
onpointerout={() => {
|
||||||
|
pointerInteracting = null
|
||||||
|
canvas.style.cursor = "grab"
|
||||||
|
}}
|
||||||
|
onmousemove={(e) => {
|
||||||
|
if (pointerInteracting !== null) {
|
||||||
|
console.log("working")
|
||||||
|
const delta = e.clientX - pointerInteracting
|
||||||
|
pointerInteractionMovement = delta
|
||||||
|
x.set(delta / 200)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
></canvas>
|
||||||
|
</main>
|
@ -5,3 +5,4 @@ export { default as RetroGrid } from "./RetroGrid.svelte"
|
|||||||
export { default as AuroraText } from "./AuroraText.svelte"
|
export { default as AuroraText } from "./AuroraText.svelte"
|
||||||
export { default as WordRotate } from "./WordRotate.svelte"
|
export { default as WordRotate } from "./WordRotate.svelte"
|
||||||
export { default as MagicCard } from "./MagicCard.svelte"
|
export { default as MagicCard } from "./MagicCard.svelte"
|
||||||
|
export { default as Globe } from "./Globe.svelte"
|
||||||
|
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
@ -1232,6 +1232,9 @@ importers:
|
|||||||
'@tanstack/svelte-virtual':
|
'@tanstack/svelte-virtual':
|
||||||
specifier: ^3.13.2
|
specifier: ^3.13.2
|
||||||
version: 3.13.2(svelte@5.20.5)
|
version: 3.13.2(svelte@5.20.5)
|
||||||
|
cobe:
|
||||||
|
specifier: ^0.6.3
|
||||||
|
version: 0.6.3
|
||||||
dompurify:
|
dompurify:
|
||||||
specifier: ^3.2.3
|
specifier: ^3.2.3
|
||||||
version: 3.2.3
|
version: 3.2.3
|
||||||
@ -2602,6 +2605,7 @@ packages:
|
|||||||
'@faker-js/faker@9.5.1':
|
'@faker-js/faker@9.5.1':
|
||||||
resolution: {integrity: sha512-0fzMEDxkExR2cn731kpDaCCnBGBUOIXEi2S1N5l8Hltp6aPf4soTMJ+g4k8r2sI5oB+rpwIW8Uy/6jkwGpnWPg==}
|
resolution: {integrity: sha512-0fzMEDxkExR2cn731kpDaCCnBGBUOIXEi2S1N5l8Hltp6aPf4soTMJ+g4k8r2sI5oB+rpwIW8Uy/6jkwGpnWPg==}
|
||||||
engines: {node: '>=18.0.0', npm: '>=9.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=9.0.0'}
|
||||||
|
deprecated: Please update to a newer version
|
||||||
|
|
||||||
'@floating-ui/core@1.6.8':
|
'@floating-ui/core@1.6.8':
|
||||||
resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==}
|
resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==}
|
||||||
@ -6617,6 +6621,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
|
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
|
||||||
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
|
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
|
||||||
|
|
||||||
|
cobe@0.6.3:
|
||||||
|
resolution: {integrity: sha512-WHr7X4o1ym94GZ96h7b1pNemZJacbOzd02dZtnVwuC4oWBaLg96PBmp2rIS1SAhUDhhC/QyS9WEqkpZIs/ZBTg==}
|
||||||
|
|
||||||
color-convert@2.0.1:
|
color-convert@2.0.1:
|
||||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||||
engines: {node: '>=7.0.0'}
|
engines: {node: '>=7.0.0'}
|
||||||
@ -9875,6 +9882,9 @@ packages:
|
|||||||
performance-now@2.1.0:
|
performance-now@2.1.0:
|
||||||
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
|
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
|
||||||
|
|
||||||
|
phenomenon@1.6.0:
|
||||||
|
resolution: {integrity: sha512-7h9/fjPD3qNlgggzm88cY58l9sudZ6Ey+UmZsizfhtawO6E3srZQXywaNm2lBwT72TbpHYRPy7ytIHeBUD/G0A==}
|
||||||
|
|
||||||
picocolors@1.1.1:
|
picocolors@1.1.1:
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
@ -19215,6 +19225,10 @@ snapshots:
|
|||||||
|
|
||||||
co@4.6.0: {}
|
co@4.6.0: {}
|
||||||
|
|
||||||
|
cobe@0.6.3:
|
||||||
|
dependencies:
|
||||||
|
phenomenon: 1.6.0
|
||||||
|
|
||||||
color-convert@2.0.1:
|
color-convert@2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name: 1.1.4
|
color-name: 1.1.4
|
||||||
@ -23222,6 +23236,8 @@ snapshots:
|
|||||||
|
|
||||||
performance-now@2.1.0: {}
|
performance-now@2.1.0: {}
|
||||||
|
|
||||||
|
phenomenon@1.6.0: {}
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
picomatch@2.3.1: {}
|
picomatch@2.3.1: {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user