coomdev
2 years ago
5 changed files with 171 additions and 3 deletions
@ -0,0 +1,74 @@ |
|||||
|
<script context="module"> |
||||
|
export const DIAL = {}; |
||||
|
</script> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { |
||||
|
setContext, |
||||
|
onDestroy, |
||||
|
createEventDispatcher, |
||||
|
afterUpdate, |
||||
|
} from "svelte"; |
||||
|
import type { NailState } from "./Nail.svelte"; |
||||
|
import type { Writable } from "svelte/store"; |
||||
|
|
||||
|
let states: Writable<NailState>[] = []; |
||||
|
|
||||
|
let visible = false; |
||||
|
|
||||
|
export let dist = 82; |
||||
|
|
||||
|
export let angleRange = [0, 360]; |
||||
|
|
||||
|
let self; |
||||
|
|
||||
|
const updateNails = () => { |
||||
|
const pi = (angleRange[1] - angleRange[0]) / states.length; |
||||
|
for (let i = 0; i < states.length; ++i) { |
||||
|
states[i].set({ |
||||
|
angle: pi * i + angleRange[0], |
||||
|
length: dist, |
||||
|
visible, |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
setContext(DIAL, { |
||||
|
registerNail(nail: Writable<NailState>) { |
||||
|
states.push(nail); |
||||
|
updateNails(); |
||||
|
onDestroy(() => { |
||||
|
const i = states.indexOf(nail); |
||||
|
console.log("destroy at ", i); |
||||
|
states.splice(i, 1); |
||||
|
updateNails(); |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
afterUpdate(() => { |
||||
|
updateNails(); |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<div |
||||
|
bind:this={self} |
||||
|
on:click={() => { |
||||
|
visible = !visible; |
||||
|
updateNails(); |
||||
|
}} |
||||
|
class="dial" |
||||
|
> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.dial { |
||||
|
padding: 10px; |
||||
|
border: 1px solid; |
||||
|
border-radius: 99px; |
||||
|
width: 25px; |
||||
|
height: 25px; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,28 @@ |
|||||
|
<script lang="ts"> |
||||
|
import type { EmbeddedFile } from "../main"; |
||||
|
import { createEventDispatcher } from "svelte"; |
||||
|
import Embedding from "./Embedding.svelte"; |
||||
|
import Dial from "./Dial.svelte"; |
||||
|
import Nail from "./Nail.svelte"; |
||||
|
|
||||
|
export const dispatch = createEventDispatcher(); |
||||
|
|
||||
|
export let files: EmbeddedFile[]; |
||||
|
export let id: string = ""; |
||||
|
|
||||
|
let children: { [k in number]: Embedding } = {}; |
||||
|
export async function bepis(ev: MouseEvent) { |
||||
|
for (let child of Object.values(children)) child.bepis(ev); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<Dial dist={220}> |
||||
|
{#each files as file, i} |
||||
|
<Nail> |
||||
|
<Embedding on:fileinfo bind:this={children[i]} {id} {file} /> |
||||
|
</Nail> |
||||
|
{/each} |
||||
|
</Dial> |
||||
|
|
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,55 @@ |
|||||
|
<script lang="ts" context="module"> |
||||
|
export type NailState = { |
||||
|
angle: number; |
||||
|
length: number; |
||||
|
visible: boolean; |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { getContext } from "svelte"; |
||||
|
import { DIAL } from "./Dial.svelte"; |
||||
|
import { writable } from "svelte/store"; |
||||
|
import { elasticOut, elasticIn } from "svelte/easing"; |
||||
|
|
||||
|
const state = writable<NailState>({ |
||||
|
angle: 0, |
||||
|
length: 0, |
||||
|
visible: false, |
||||
|
}); |
||||
|
|
||||
|
function slide(node: any, { delay = 0, duration = 1000 }) { |
||||
|
return { |
||||
|
delay, |
||||
|
easing: elasticOut, |
||||
|
duration, |
||||
|
css: (t: number) => |
||||
|
`transform: rotate(${$state.angle}deg) translateX(${ |
||||
|
t * $state.length |
||||
|
}px) scale(${t}); opacity: ${t}`, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
const ctx: any = getContext(DIAL); |
||||
|
if (ctx) ctx.registerNail(state); |
||||
|
</script> |
||||
|
|
||||
|
{#if $state.visible} |
||||
|
<div |
||||
|
transition:slide |
||||
|
style="transform: rotate({$state.angle}deg) translateX({$state.length}px);" |
||||
|
class="rel" |
||||
|
> |
||||
|
<div style="transform: rotate({-$state.angle}deg)" class="abs"> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
</div> |
||||
|
{/if} |
||||
|
|
||||
|
<style> |
||||
|
.rel { |
||||
|
} |
||||
|
|
||||
|
.abs { |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,8 @@ |
|||||
|
<script lang="ts"> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<div></div> |
||||
|
|
||||
|
<style> |
||||
|
</style> |
Loading…
Reference in new issue