Skip to content

Commit

Permalink
feat: ✨ added dotwave & starfield
Browse files Browse the repository at this point in the history
  • Loading branch information
MikhaD committed Jun 17, 2023
1 parent 6dfb6d6 commit 5c2e8f1
Show file tree
Hide file tree
Showing 9 changed files with 640 additions and 409 deletions.
749 changes: 350 additions & 399 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
"preview": "histoire preview"
},
"devDependencies": {
"histoire": "^0.15.8",
"@histoire/plugin-svelte": "^0.15.8",
"@sveltejs/vite-plugin-svelte": "^2.0.2",
"@tsconfig/svelte": "^3.0.0",
"sass": "^1.58.3",
"svelte": "^3.55.1",
"svelte-check": "^2.10.3",
"tslib": "^2.5.0",
"typescript": "^4.9.3",
"vite": "^4.1.0"
"histoire": "^0.16.2",
"@histoire/plugin-svelte": "^0.16.1",
"@sveltejs/vite-plugin-svelte": "^2.4.1",
"@tsconfig/svelte": "^4.0.1",
"sass": "^1.63.4",
"svelte": "^3.59.1",
"svelte-check": "^3.4.3",
"tslib": "^2.5.3",
"typescript": "^5.1.3",
"vite": "^4.3.9"
}
}
88 changes: 88 additions & 0 deletions src/components/Canvas/Starfield.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<script lang="ts">
import { onMount } from "svelte";
export let width = 500;
export let height = 500;
export let stars = 500;
export let speed = 0.3;
let canvas: HTMLCanvasElement;
let stars_array: Star[] = [];
const vanishing_point = {
x: width / 2,
y: height / 2,
};
// x and y need to be in the range of the canvas
class Star {
static readonly MAX_X = width / 2;
static readonly MIN_X = -width / 2;
static readonly MAX_Y = height / 2;
static readonly MIN_Y = -height / 2;
static readonly MAX_Z = 500;
static readonly MIN_Z = 0;
public x: number;
public y: number;
public z: number;
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = z;
}
draw(ctx: CanvasRenderingContext2D) {
const x = vanishing_point.x + this.x / (this.z / 1000);
const y = vanishing_point.y + this.y / (this.z / 1000);
if (x < 0 || x > width || y < 0 || y > height) return;
const color = Math.floor((1 - (this.z / Star.MAX_Z) ** 2) * 255);
ctx.fillStyle = `rgb(${color}, ${color}, ${color})`;
ctx.fillRect(x, y, 1, 1);
}
move(distance: number) {
this.z -= distance;
if (this.z <= 0) {
this.z = Star.MAX_Z;
}
}
static create() {
return new Star(
Math.random() * (Star.MAX_X - Star.MIN_X) + Star.MIN_X,
Math.random() * (Star.MAX_Y - Star.MIN_Y) + Star.MIN_Y,
Math.random() * (Star.MAX_Z - Star.MIN_Z) + Star.MIN_Z
);
}
}
function clear(ctx: CanvasRenderingContext2D) {
ctx.fillStyle = "#0005";
ctx.fillRect(0, 0, width, height);
}
for (let i = 0; i < stars; ++i) {
stars_array.push(Star.create());
}
onMount(() => {
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d")!;
let previous_time = 0;
function tick(time: number) {
clear(ctx);
const duration = time - previous_time;
for (const star of stars_array) {
star.move(duration * speed);
star.draw(ctx);
}
previous_time = time;
requestAnimationFrame(tick);
}
tick(0);
});
</script>

<canvas bind:this={canvas} />
75 changes: 75 additions & 0 deletions src/components/Experiment.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<section>
<span class="rotate">
<div class="circle" />
<div class="circle" />
<div class="circle" />
<div class="circle" />
<div class="circle" />
<div class="circle" />
<div class="circle" />
<div class="circle" />
<div class="center" />
</span>
</section>

<style lang="scss">
section {
width: 500px;
height: 500px;
}
.rotate {
display: grid;
grid-template: 1fr / 1fr;
place-items: center;
width: 100%;
height: 100%;
animation: rotate 10s linear infinite;
&:hover {
animation-play-state: paused;
}
}
div {
grid-row: 1 / 2;
grid-column: 1 / 2;
border-radius: 50%;
position: relative;
transform-origin: center;
&::before {
content: "a";
position: absolute;
inset: 0;
display: grid;
place-items: center;
animation: rotate 10s linear reverse infinite;
}
}
.circle {
--offset: 150px;
width: 50px;
height: 50px;
background-color: #000;
transform: translate(
calc(cos(var(--angle)) * var(--offset)),
calc(sin(var(--angle)) * var(--offset))
);
}
.center {
width: 100px;
height: 100px;
background-color: currentcolor;
}
@keyframes rotate {
0% {
rotate: 0deg;
}
100% {
rotate: 360deg;
}
}
$count: 8;
@for $i from 1 through $count {
.circle:nth-child(#{$i}) {
--angle: #{calc(($i * 360) / $count)}deg;
}
}
</style>
46 changes: 46 additions & 0 deletions src/loading-animations/DotWave.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script lang="ts">
/**
* The number of spinning circles.
*
* Min: 1
* @default 1
*/
export let count = 1;
$: count = Math.max(1, count);
/**
* The speed of the animation in seconds.
* @default 1
*/
export let speed = 1;
/**
* Whether the animation should play in reverse.
* @default false
*/
export let reverse = false;
/**
* The radius of the dots.
* @default 15
*/
export let r = 15;
</script>

<svg viewBox="0 0 100 100" style:--speed="{speed}s" class:reverse style:--r="{r}px">
{#key count}
{#each new Array(count) as _, i}
<circle cx={((i + 1) * 100) / count - r} cy="50" />
{/each}
{/key}
</svg>

<style lang="scss">
circle {
r: var(--r);
fill: currentcolor;
transform-origin: center;
// animation: spin var(--speed) infinite ease-out;
}
.reverse circle {
animation-direction: reverse;
animation-timing-function: ease-in;
}
</style>
2 changes: 2 additions & 0 deletions src/loading-animations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import BlockWave from "./BlockWave.svelte";
import BlockShuffle from "./BlockShuffle.svelte";
import DotSlide from "./DotSlide.svelte";
import DotSpin from "./DotSpin.svelte";
import DotWave from "./DotWave.svelte";

export default {
Spin,
Expand All @@ -38,4 +39,5 @@ export default {
BlockShuffle,
DotSlide,
DotSpin,
DotWave,
};
17 changes: 17 additions & 0 deletions src/stories/components/Experiment.story.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import type { Hst } from "@histoire/plugin-svelte";
import Experiment from "../../components/Experiment.svelte";
export let Hst: Hst;
let colorType: ColorType = "hex";
let value = "#000000";
</script>

<Hst.Story
title="Components/.Experiment"
icon="tabler:test-pipe"
layout={{ type: "single", iframe: false }}
>
<Experiment />
</Hst.Story>
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,29 @@
let dotSpin_speed = 1;
let dotSpin_reverse = false;
let dotSpin_r = 15;
let dotWave_count = 2;
let dotWave_speed = 1;
let dotWave_r = 15;
let dotWave_reverse = true;
</script>

<Hst.Story title="Loading Animations" icon="mingcute:loading-fill" layout={{ type: "grid" }}>
<Hst.Variant title="Dot Spin" icon="ion:more">
<Loading.DotWave
bind:reverse={dotWave_reverse}
bind:count={dotWave_count}
bind:speed={dotWave_speed}
bind:r={dotWave_r}
/>
<svelte:fragment slot="controls">
<Range title="Count" min={2} max={12} step={2} bind:value={dotWave_count} />
<Range title="Speed" min={0.1} max={10} step={0.1} bind:value={dotWave_speed} />
<Range title="Radius" min={1} max={20} step={0.5} bind:value={dotWave_r} />
<Hst.Checkbox title="Reverse" bind:value={dotWave_reverse} />
</svelte:fragment>
</Hst.Variant>

<Hst.Variant title="Dot Spin" icon="ion:more">
<Loading.DotSpin
bind:count={dotSpin_count}
Expand Down
32 changes: 32 additions & 0 deletions src/stories/components/Starfield.story.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts">
import type { Hst } from "@histoire/plugin-svelte";
import Starfield from "../../components/Canvas/Starfield.svelte";
import Button from "../../lib/Button.svelte";
export let Hst: Hst;
let key = false;
let width = 500;
let height = 500;
let stars = 500;
let speed = 0.3;
function changed(...args: any[]) {
key = !key;
}
$: changed(width, height, stars);
</script>

<Hst.Story title="Canvas/Starfield" icon="ion:sparkles">
{#key key}
<Starfield bind:width bind:height bind:stars bind:speed />
{/key}
<svelte:fragment slot="controls">
<Button on:click={() => (key = !key)}>Reset</Button>
<Hst.Number title="Width" bind:value={width} />
<Hst.Number title="Height" bind:value={height} />
<Hst.Number title="Stars" bind:value={stars} step={100} />
<Hst.Number title="Speed" bind:value={speed} step={0.1} />
</svelte:fragment>
</Hst.Story>

0 comments on commit 5c2e8f1

Please sign in to comment.