Skip to content

Commit 13cb796

Browse files
authored
chore(ux): add animated header with anime.js in p2p sections (#3271)
feat(p2p): add animated header with anime.js Signed-off-by: Ettore Di Giacinto <[email protected]>
1 parent e4c696d commit 13cb796

File tree

5 files changed

+178
-56
lines changed

5 files changed

+178
-56
lines changed

core/http/static/p2panimation.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const canvas = document.getElementById('networkCanvas');
2+
const ctx = canvas.getContext('2d');
3+
4+
canvas.width = window.innerWidth;
5+
canvas.height = window.innerHeight;
6+
7+
const particles = [];
8+
const lines = [];
9+
10+
class Particle {
11+
constructor(x, y) {
12+
this.x = x;
13+
this.y = y;
14+
this.radius = 2 + Math.random() * 2;
15+
this.color = `rgba(0, 255, 204, ${Math.random()})`;
16+
this.speed = Math.random() * 2 + 1;
17+
this.angle = Math.random() * Math.PI * 2;
18+
}
19+
20+
update() {
21+
this.x += Math.cos(this.angle) * this.speed;
22+
this.y += Math.sin(this.angle) * this.speed;
23+
24+
if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) {
25+
this.x = Math.random() * canvas.width;
26+
this.y = Math.random() * canvas.height;
27+
}
28+
}
29+
30+
draw() {
31+
ctx.beginPath();
32+
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
33+
ctx.fillStyle = this.color;
34+
ctx.fill();
35+
}
36+
}
37+
38+
function connectParticles() {
39+
for (let i = 0; i < particles.length; i++) {
40+
for (let j = i + 1; j < particles.length; j++) {
41+
const distance = Math.hypot(particles[i].x - particles[j].x, particles[i].y - particles[j].y);
42+
if (distance < 150) {
43+
ctx.beginPath();
44+
ctx.moveTo(particles[i].x, particles[i].y);
45+
ctx.lineTo(particles[j].x, particles[j].y);
46+
ctx.strokeStyle = `rgba(0, 255, 204, ${1 - distance / 150})`;
47+
ctx.stroke();
48+
}
49+
}
50+
}
51+
}
52+
53+
function initParticles(num) {
54+
for (let i = 0; i < num; i++) {
55+
particles.push(new Particle(Math.random() * canvas.width, Math.random() * canvas.height));
56+
}
57+
}
58+
59+
function animate() {
60+
ctx.clearRect(0, 0, canvas.width, canvas.height);
61+
62+
particles.forEach(particle => {
63+
particle.update();
64+
particle.draw();
65+
});
66+
67+
connectParticles();
68+
69+
requestAnimationFrame(animate);
70+
}
71+
72+
initParticles(100);
73+
animate();

core/http/views/explorer.html

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -155,54 +155,29 @@
155155
right: 10px;
156156
color: #e2e8f0;
157157
}
158-
.fa-circle-nodes {
159-
/* font-size: 100px; /* Adjust the size as needed */
160-
animation: rotateCircleNodes 8s linear infinite; /* Slow and fluid rotation */
161-
display: inline-block;
162-
}
163-
164-
@keyframes rotateCircleNodes {
165-
0% { transform: rotate(0deg); }
166-
100% { transform: rotate(360deg); }
167-
}
168-
/* Animation for the warning box */
169-
.fa-flask {
170-
/* font-size: 100px; /* Adjust the size as needed */
171-
animation: shakeFlask 3s ease-in-out infinite; /* Smooth easing and longer duration for fluidity */
172-
transform-origin: bottom center;
173-
}
174-
175-
@keyframes shakeFlask {
176-
0%, 10% { transform: rotate(0deg); } /* Start and end still */
177-
20% { transform: rotate(-10deg); } /* Smooth transition to left */
178-
30% { transform: rotate(10deg); } /* Smooth transition to right */
179-
40% { transform: rotate(-8deg); } /* Smooth transition to left */
180-
50% { transform: rotate(8deg); } /* Smooth transition to right */
181-
60% { transform: rotate(-5deg); } /* Smooth transition to left */
182-
70% { transform: rotate(5deg); } /* Smooth transition to right */
183-
80% { transform: rotate(-2deg); } /* Smooth transition to left */
184-
90% { transform: rotate(2deg); } /* Smooth transition to right */
185-
100% { transform: rotate(0deg); } /* Return to center */
186-
}
187158
</style>
188159

189160
<body class="bg-gray-900 text-gray-200">
190161
<div class="flex flex-col min-h-screen" x-data="networkClusters()" x-init="init()">
191162
{{template "views/partials/navbar_explorer" .}}
192-
193-
<header class="text-center py-12">
194-
<h1 class="text-5xl font-bold text-gray-100">
195-
<i class="fa-solid fa-circle-nodes mr-2"></i> Network Clusters Explorer
196-
197-
</h1>
198-
<p class="mt-4 text-lg">
199-
View the clusters and workers available in each network.
200-
<a href="https://localai.io/features/distribute/" target="_blank">
201-
<i class="fas fa-circle-info pr-2"></i>
202-
</a>
203-
</p>
204-
205-
</header>
163+
<div class="animation-container">
164+
<canvas id="networkCanvas"></canvas>
165+
<div class="text-overlay">
166+
<header class="text-center py-12">
167+
<h1 class="text-5xl font-bold text-gray-100">
168+
<i class="fa-solid fa-circle-nodes mr-2"></i> Network Clusters Explorer
169+
170+
</h1>
171+
<p class="mt-4 text-lg">
172+
View the clusters and workers available in each network.
173+
<a href="https://localai.io/features/distribute/" target="_blank">
174+
<i class="fas fa-circle-info pr-2"></i>
175+
</a>
176+
</p>
177+
178+
</header>
179+
</div>
180+
</div>
206181

207182
<div class="container mx-auto px-4 flex-grow">
208183
<!-- Warning Box -->
@@ -395,6 +370,7 @@ <h2 class="text-3xl font-bold mb-4 mt-4">Available Clusters in this network</h2>
395370
}
396371
}
397372
</script>
373+
<script src="/static/p2panimation.js"></script>
398374

399375
{{template "views/partials/footer" .}}
400376
</div>

core/http/views/p2p.html

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,23 @@
88
{{template "views/partials/navbar" .}}
99
<div class="container mx-auto px-4 flex-grow">
1010
<div class="workers mt-12 text-center">
11-
12-
<h2 class="text-3xl font-semibold text-gray-100 mb-8">
13-
<i class="fa-solid fa-circle-nodes"></i> Distributed inference with P2P
14-
<a href="https://localai.io/features/distribute/" target="_blank">
15-
<i class="fas fa-circle-info pr-2"></i>
16-
</a>
17-
</h2>
11+
<div class="animation-container">
12+
<canvas id="networkCanvas"></canvas>
13+
<div class="text-overlay">
14+
<header class="text-center py-12">
15+
<h1 class="text-5xl font-bold text-gray-100">
16+
<i class="fa-solid fa-circle-nodes mr-2"></i> Distributed inference with P2P
17+
</h1>
18+
<p class="mt-4 text-lg">
19+
Distribute computation by sharing and loadbalancing instances or sharding model weights.
20+
<a href="https://localai.io/features/distribute/" target="_blank">
21+
<i class="fas fa-circle-info pr-2"></i>
22+
</a>
23+
</p>
24+
25+
</header>
26+
</div>
27+
</div>
1828
<h5 class="mb-4 text-justify">LocalAI uses P2P technologies to enable distribution of work between peers. It is possible to share an instance with Federation and/or split the weights of a model across peers (only available with llama.cpp models). You can now share computational resources between your devices or your friends!</h5>
1929
<!-- Warning box if p2p token is empty and p2p is enabled -->
2030
{{ if and .IsP2PEnabled (eq .P2PToken "") }}
@@ -144,7 +154,7 @@ <h3 class="text-2xl font-semibold text-gray-100 mb-6"><i class="fa-solid fa-book
144154

145155
{{template "views/partials/footer" .}}
146156
</div>
147-
157+
<script src="/static/p2panimation.js"></script>
148158
<style>
149159
.token {
150160
word-break: break-all;

core/http/views/partials/head.html

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
rel="stylesheet"
77
href="/static/assets/highlightjs.css"
88
/>
9+
<script defer src="/static/assets/anime.min.js"></script>
910
<script
1011
defer
1112
src="/static/assets/highlightjs.js"
@@ -47,8 +48,68 @@
4748
},
4849
};
4950
</script>
50-
<link href="/static/assets/fontawesome/css/fontawesome.css" rel="stylesheet" />
51-
<link href="/static/assets/fontawesome/css/brands.css" rel="stylesheet" />
52-
<link href="/static/assets/fontawesome/css/solid.css" rel="stylesheet" />
53-
<script src="/static/assets/htmx.js" crossorigin="anonymous"></script>
51+
<link href="/static/assets/fontawesome/css/fontawesome.css" rel="stylesheet" />
52+
<link href="/static/assets/fontawesome/css/brands.css" rel="stylesheet" />
53+
<link href="/static/assets/fontawesome/css/solid.css" rel="stylesheet" />
54+
<script src="/static/assets/htmx.js" crossorigin="anonymous"></script>
55+
<!-- P2P Animation START -->
56+
<style>
57+
.animation-container {
58+
position: relative;
59+
width: 100%;
60+
height: 25vh;
61+
display: flex;
62+
justify-content: center;
63+
align-items: center;
64+
overflow: hidden;
65+
}
66+
67+
canvas {
68+
position: absolute;
69+
top: 0;
70+
left: 0;
71+
}
72+
73+
.text-overlay {
74+
position: absolute;
75+
top: 50%;
76+
left: 50%;
77+
transform: translate(-50%, -50%);
78+
text-align: center;
79+
z-index: 1;
80+
}
81+
</style>
82+
<!-- P2P Animation END -->
83+
<!-- Flask and node animation -->
84+
<style>
85+
.fa-circle-nodes {
86+
/* font-size: 100px; /* Adjust the size as needed */
87+
animation: rotateCircleNodes 8s linear infinite; /* Slow and fluid rotation */
88+
display: inline-block;
89+
}
90+
91+
@keyframes rotateCircleNodes {
92+
0% { transform: rotate(0deg); }
93+
100% { transform: rotate(360deg); }
94+
}
95+
/* Animation for the warning box */
96+
.fa-flask {
97+
/* font-size: 100px; /* Adjust the size as needed */
98+
animation: shakeFlask 3s ease-in-out infinite; /* Smooth easing and longer duration for fluidity */
99+
transform-origin: bottom center;
100+
}
101+
102+
@keyframes shakeFlask {
103+
0%, 10% { transform: rotate(0deg); } /* Start and end still */
104+
20% { transform: rotate(-10deg); } /* Smooth transition to left */
105+
30% { transform: rotate(10deg); } /* Smooth transition to right */
106+
40% { transform: rotate(-8deg); } /* Smooth transition to left */
107+
50% { transform: rotate(8deg); } /* Smooth transition to right */
108+
60% { transform: rotate(-5deg); } /* Smooth transition to left */
109+
70% { transform: rotate(5deg); } /* Smooth transition to right */
110+
80% { transform: rotate(-2deg); } /* Smooth transition to left */
111+
90% { transform: rotate(2deg); } /* Smooth transition to right */
112+
100% { transform: rotate(0deg); } /* Return to center */
113+
}
114+
</style>
54115
</head>

embedded/webui_static.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@
5757
- filename: "KFOlCnqEu92Fr1MmYUtfBBc9.ttf"
5858
url: "https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmYUtfBBc9.ttf"
5959
sha: "361a50f8a6c816ba4306c5290b7e487a726e1b4dcc3d8d7e4acf1fc2dae9f551"
60-
60+
- filename: "anime.js"
61+
url: "https://raw.githubusercontent.com/juliangarnier/anime/master/lib/anime.min.js"
62+
sha: "bceef94f964481f7680d95e7fbbe5a8c20d3945a926a754874898a578db7c7ab"

0 commit comments

Comments
 (0)