+102
src/components/blog/Balloon.astro
+102
src/components/blog/Balloon.astro
···
1
+
---
2
+
import { blog, utils } from "@/config";
3
+
4
+
interface Props {
5
+
id: number;
6
+
of: number;
7
+
}
8
+
9
+
const { id, of } = Astro.props;
10
+
11
+
const length = utils.getRandom(blog.balloons.size);
12
+
const offset = utils.getRandom(blog.balloons.offset);
13
+
const rotation = new Array(5)
14
+
.fill(0)
15
+
.map((_) => utils.getRandom(blog.balloons.rotation));
16
+
---
17
+
18
+
<div
19
+
style={`--length: ${length}rem;
20
+
--id: ${id};
21
+
--of: ${of};
22
+
--offset: ${offset}rem;
23
+
${rotation.map((x, i) => `--rot-${i}: ${x}deg;`).join(" ")}
24
+
--timing: ${utils.getRandom(blog.balloons.timing)}s;
25
+
`}
26
+
>
27
+
</div>
28
+
29
+
<style>
30
+
@property --rot-0 {
31
+
syntax: "<angle>";
32
+
inherits: false;
33
+
initial-value: 0px;
34
+
}
35
+
36
+
@property --rot-1 {
37
+
syntax: "<angle>";
38
+
inherits: false;
39
+
initial-value: 0px;
40
+
}
41
+
42
+
@property --rot-2 {
43
+
syntax: "<angle>";
44
+
inherits: false;
45
+
initial-value: 0px;
46
+
}
47
+
48
+
@property --rot-3 {
49
+
syntax: "<angle>";
50
+
inherits: false;
51
+
initial-value: 0px;
52
+
}
53
+
54
+
@property --rot-4 {
55
+
syntax: "<angle>";
56
+
inherits: false;
57
+
initial-value: 0px;
58
+
}
59
+
60
+
@keyframes tilt {
61
+
from,
62
+
to {
63
+
rotate: var(--rot-0);
64
+
}
65
+
66
+
20% {
67
+
rotate: var(--rot-1);
68
+
}
69
+
70
+
40% {
71
+
rotate: var(--rot-2);
72
+
}
73
+
74
+
60% {
75
+
rotate: var(--rot-3);
76
+
}
77
+
78
+
80% {
79
+
rotate: var(--rot-4);
80
+
}
81
+
}
82
+
83
+
div {
84
+
position: absolute;
85
+
86
+
width: 0.5rem;
87
+
height: var(--length);
88
+
background: black;
89
+
90
+
top: calc(-1 * var(--length));
91
+
left: calc(
92
+
100% / var(--of) * var(--id) + 100% / 2 / var(--of) + var(--offset)
93
+
);
94
+
95
+
transform-origin: bottom;
96
+
rotate: var(--rot-0);
97
+
98
+
@media (prefers-reduced-motion: no-preference) {
99
+
animation: infinite var(--timing) linear tilt;
100
+
}
101
+
}
102
+
</style>
+13
-1
src/components/blog/Post.astro
+13
-1
src/components/blog/Post.astro
···
2
2
import type { InferEntrySchema } from "astro:content";
3
3
import { Image } from "astro:assets";
4
4
5
-
import { blog } from "@/config";
5
+
import { blog, utils } from "@/config";
6
+
import Balloon from "./Balloon.astro";
6
7
7
8
interface Props {
8
9
id: string;
···
76
77
--y-gap: ${blog.post.yGap}rem;
77
78
`}
78
79
>
80
+
{
81
+
// new Array(Math.floor(utils.getRandom(blog.balloons.numBalloons)))
82
+
// .fill(0)
83
+
// .map((_, i) => <Balloon id={i} of={this?.length} />)
84
+
85
+
(() => {
86
+
const len = Math.round(utils.getRandom(blog.balloons.numBalloons));
87
+
const arr = new Array(len).fill(0);
88
+
return arr.map((_, i) => <Balloon id={i} of={len} />);
89
+
})()
90
+
}
79
91
<Image src={image} alt="" />
80
92
<div>
81
93
<a href={`/blog/${id}/`}>({id}) {data.title}</a>