Add the buttons, add the background made my ari, add some basic css and basic index design.
44
assets/css/style.css
Normal file
@@ -0,0 +1,44 @@
|
||||
/* CSS Document */
|
||||
body {
|
||||
background-color: #0e0016;
|
||||
color: white;
|
||||
}
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.buttons img {
|
||||
width: 88px;
|
||||
height: 31px;
|
||||
border: none;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
-webkit-transition: none !important;
|
||||
-o-transition: none !important;
|
||||
transition: none !important;
|
||||
-webkit-animation: none !important;
|
||||
animation: none !important;
|
||||
-webkit-animation-play-state: paused !important;
|
||||
animation-play-state: paused !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
#night {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #0e0016;
|
||||
z-index: -9999;
|
||||
}
|
||||
BIN
assets/images/buttons/Purplebored_button.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
assets/images/buttons/aagaming.png
Normal file
|
After Width: | Height: | Size: 999 B |
BIN
assets/images/buttons/airvpn_userbar.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
assets/images/buttons/aleksey.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/images/buttons/any_browser.gif
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/images/buttons/ari.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/images/buttons/authen.gif
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
assets/images/buttons/dark-mode.gif
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
assets/images/buttons/eclipsecx.png
Normal file
|
After Width: | Height: | Size: 1001 B |
BIN
assets/images/buttons/firefox.gif
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
assets/images/buttons/freebsd.gif
Normal file
|
After Width: | Height: | Size: 965 B |
BIN
assets/images/buttons/fsky_night.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
assets/images/buttons/georgemoody.png
Normal file
|
After Width: | Height: | Size: 556 B |
BIN
assets/images/buttons/k327.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
assets/images/buttons/mcneb10.gif
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/images/buttons/midgard.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/images/buttons/telepath.png
Normal file
|
After Width: | Height: | Size: 510 B |
BIN
assets/images/buttons/tobskep.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/buttons/trace.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/images/buttons/unpato.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/buttons/valid-atom.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/buttons/valid-rss.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
assets/images/buttons/xameren.png
Normal file
|
After Width: | Height: | Size: 426 B |
164
assets/js/script.js
Normal file
@@ -0,0 +1,164 @@
|
||||
"use strict";
|
||||
function create_night(canvas_element) {
|
||||
const context = canvas_element.getContext("2d");
|
||||
const star_range = 0.7; /* Variation in star size */
|
||||
const star_spread = 0.002; /* Star density per pixel */
|
||||
const concentration_corner = "top-left"; /* Concentration corner position */
|
||||
const concentration_strength = 5.0; /* How much should it be concentrated? */
|
||||
const twinkle_intensity = 5.0; /* How noticeable should the twinkle be? */
|
||||
const interaction_radius = 150; /* Radius around mouse/touch where stars react */
|
||||
const interaction_brightness_factor = 5.0; /* How much brightness increases */
|
||||
const interaction_size_factor = 1.5; /* How much the stars should grow in size (only during interaction) */
|
||||
const magic = [
|
||||
16.31189, 32454.4619, 9371.1474, 6848, 1544, 6848, 2156,
|
||||
]; /* Just some magic numbers */
|
||||
/* Seeded "random" number */
|
||||
function seeded_random(seed) {
|
||||
const value = Math.sin(seed) * 10000;
|
||||
return value - Math.floor(value);
|
||||
}
|
||||
let stars = [];
|
||||
let time = 0;
|
||||
let mouse_x = -1,
|
||||
mouse_y = -1;
|
||||
/* Determine corner position for concentration */
|
||||
function get_corner(width, height) {
|
||||
switch (concentration_corner) {
|
||||
case "top-right":
|
||||
return { x: width, y: 0 };
|
||||
case "bottom-left":
|
||||
return { x: 0, y: height };
|
||||
case "bottom-right":
|
||||
return { x: width, y: height };
|
||||
default:
|
||||
return { x: 0, y: 0 }; /* top-left */
|
||||
}
|
||||
}
|
||||
/* Function to generate star shape */
|
||||
function draw_star(x, y, radius, alpha) {
|
||||
const num_points = 5 + Math.floor(Math.random() * 3);
|
||||
const angle = Math.PI / num_points;
|
||||
context.beginPath();
|
||||
for (let idx = 0; idx < num_points; idx++) {
|
||||
const angle_offset = (idx * 2 * Math.PI) / num_points;
|
||||
const outer_x = x + radius * Math.cos(angle_offset);
|
||||
const outer_y = y + radius * Math.sin(angle_offset);
|
||||
context.lineTo(outer_x, outer_y);
|
||||
/* Inner points for star shape */
|
||||
const inner_radius = radius / 2 + Math.random() * 0.2;
|
||||
const inner_x = x + inner_radius * Math.cos(angle_offset + angle);
|
||||
const inner_y = y + inner_radius * Math.sin(angle_offset + angle);
|
||||
context.lineTo(inner_x, inner_y);
|
||||
}
|
||||
context.closePath();
|
||||
context.fillStyle = `rgba(255, 255, 180, ${alpha})`;
|
||||
context.fill();
|
||||
}
|
||||
/* Function to generate star background */
|
||||
function generate_stars() {
|
||||
const { width, height } = canvas_element;
|
||||
const star_count = Math.floor(width * height * star_spread);
|
||||
const corner = get_corner(width, height);
|
||||
stars = [];
|
||||
for (let idx = 0; idx < star_count; idx++) {
|
||||
const base_random = seeded_random(idx * magic[0]);
|
||||
/* Uniform random position */
|
||||
const raw_x = seeded_random(base_random * magic[1]) * width;
|
||||
const raw_y = seeded_random(base_random * magic[2]) * height;
|
||||
/* Calculate distance from the corner to control concentration */
|
||||
const dx = raw_x - corner.x;
|
||||
const dy = raw_y - corner.y;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
/* Apply exponential falloff based on distance (closer = more likely to be drawn) */
|
||||
const max_distance = Math.sqrt(width * width + height * height);
|
||||
const weight = Math.exp(
|
||||
-concentration_strength * (distance / max_distance),
|
||||
);
|
||||
/* Skip stars that don't meet the concentration threshold */
|
||||
if (seeded_random(base_random * magic[3]) > weight) {
|
||||
continue;
|
||||
}
|
||||
/* Randomized star properties */
|
||||
const radius =
|
||||
seeded_random(base_random * magic[4]) * star_range +
|
||||
0.4 +
|
||||
Math.random() * 0.2;
|
||||
const twinkle_speed =
|
||||
seeded_random(base_random * magic[5]) * 1.5 + 0.3;
|
||||
const twinkle_phase =
|
||||
seeded_random(base_random * magic[6]) * Math.PI * 2;
|
||||
stars.push({
|
||||
x: raw_x,
|
||||
y: raw_y,
|
||||
radius,
|
||||
twinkle_speed,
|
||||
twinkle_phase,
|
||||
original_radius: radius,
|
||||
});
|
||||
}
|
||||
}
|
||||
/* Resize canvas and regenerate stars on window resize */
|
||||
function resize_canvas() {
|
||||
canvas_element.width = window.innerWidth;
|
||||
canvas_element.height = window.innerHeight;
|
||||
generate_stars();
|
||||
}
|
||||
window.addEventListener("resize", resize_canvas);
|
||||
resize_canvas();
|
||||
/* Handle mouse/touch movement effects */
|
||||
function handle_interaction(event) {
|
||||
if (event.touches) {
|
||||
mouse_x = event.touches[0].clientX;
|
||||
mouse_y = event.touches[0].clientY;
|
||||
} else {
|
||||
mouse_x = event.clientX;
|
||||
mouse_y = event.clientY;
|
||||
}
|
||||
}
|
||||
window.addEventListener("mousemove", handle_interaction);
|
||||
window.addEventListener("touchmove", handle_interaction);
|
||||
/* Animate stars (twinke) */
|
||||
function animate() {
|
||||
time += 0.01;
|
||||
const { width, height } = canvas_element;
|
||||
context.fillStyle = "#0e0016";
|
||||
context.fillRect(0, 0, width, height);
|
||||
for (const star of stars) {
|
||||
const twinkle = Math.sin(
|
||||
time * star.twinkle_speed + star.twinkle_phase,
|
||||
);
|
||||
let alpha = 0.6 + twinkle_intensity * (0.5 + 0.5 * twinkle);
|
||||
/* Interaction effect based on mouse/touch proximity */
|
||||
if (mouse_x !== -1 && mouse_y !== -1) {
|
||||
const dx = mouse_x - star.x;
|
||||
const dy = mouse_y - star.y;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
if (distance < interaction_radius) {
|
||||
const effect = Math.max(
|
||||
0,
|
||||
1 - distance / interaction_radius,
|
||||
);
|
||||
alpha *=
|
||||
1 +
|
||||
effect *
|
||||
interaction_brightness_factor; /* Make the star brighter */
|
||||
star.radius =
|
||||
star.original_radius *
|
||||
(1 +
|
||||
effect *
|
||||
interaction_size_factor); /* Grow the star size */
|
||||
}
|
||||
}
|
||||
draw_star(star.x, star.y, star.radius, alpha);
|
||||
}
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
animate();
|
||||
}
|
||||
function base_main() {
|
||||
const night = document.getElementById("night");
|
||||
create_night(night);
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
base_main();
|
||||
});
|
||||
74
index.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="og:url" content="https://purplebored.pl/" />
|
||||
<meta name="og:title" content="Purplebored.pl" />
|
||||
<meta name="og:description" content="Just my personal website where I share cool stuff, the things I like, and the things I do :D" />
|
||||
<meta name="description" content="Just my personal website :-)" />
|
||||
<meta name="keywords" content="purplebored, poland, polish, personal website, website, buttons, niko, self-hosted, open source, foss, murder drones, tobacco, md, nicotine" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<meta name="theme-color" content="black" />
|
||||
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<title>Purplebored</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Purplebored.pl</h1>
|
||||
<p>Hi, I am Purplebored, o/ also known as Niko. Right now you are on my own little website which I call my home on the World Wide Web! </p>
|
||||
|
||||
<p>I like making simple websites, and I am also a privacy advocate. I also love tobacco, and I am a big nicotine addict. I speak Polish and English, but I am also learning Russian. Regarding programming, I currently only know basic HTML. From other stuff, I also know some Linux and quite a lot about Windows — especially the older versions like Windows 7.</p>
|
||||
|
||||
<!-- Badges / Buttons / 88x31s -->
|
||||
<div class="buttons">
|
||||
<a href="https://purplebored.pl/" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/Purplebored_button.png" alt="Purplebored button" />
|
||||
</a>
|
||||
<a href="https://unpato.neocities.org/" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/unpato.png" alt="Unpato writing button" />
|
||||
</a>
|
||||
<a href="https://eclipse.cx" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/eclipsecx.png" alt="Eclipse Community button" />
|
||||
</a>
|
||||
<a href="https://aagaming.me/" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/aagaming.png" alt="AAgaming button" />
|
||||
</a>
|
||||
<a href="https://themcgovern.net" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/mcneb10.gif" alt="Mcneb10 button" />
|
||||
</a>
|
||||
<a href="https://moody.im/" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/georgemoody.png" alt="Georgemoody button" />
|
||||
</a>
|
||||
<a href="https://xameren.fsky.io" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/xameren.png" alt="Xameren button" />
|
||||
</a>
|
||||
<a href="https://fsky.io" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/fsky_night.png" alt="FSKY.io button" />
|
||||
</a>
|
||||
<a href="https://ari.lt/" title="ari-web badge" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/ari.png" alt="ari-web badge" />
|
||||
</a>
|
||||
<a href="https://telepath.im" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/telepath.png" alt="Telepath.im button" />
|
||||
</a>
|
||||
<a href="https://aleksey-kon-games.fsky.io/" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/aleksey.png" alt="Aleksey Kon Games button" />
|
||||
</a>
|
||||
<a href="https://k327.eu/" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/k327.png" alt="k327.eu button" />
|
||||
</a>
|
||||
<a href="https://vaporwavefox.neocities.org" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/trace.png" alt="Trace button" />
|
||||
</a>
|
||||
<a href="https://authenyo.xyz" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/authen.gif" alt="Authen button" />
|
||||
</a>
|
||||
<a href="http://[300:5506:25eb:d0d9::]" target="_blank" rel="noopener noreferrer">
|
||||
<img src="assets/images/buttons/midgard.png" alt="Midgard button" />
|
||||
</a>
|
||||
</div>
|
||||
<canvas id="night"></canvas>
|
||||
<script src="assets/js/script.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||