Вёрстка резюме и карточек проектов в теме Matrix/cacto
Резюме: ASCII-кактус, glitch-заголовок, таймлайн опыта, скилл-теги, контакты. Проекты: карточки-терминалы (home_automatization, cactoz.su) со ссылками на git.cactoz.su. Canvas-дождь на цифровых/катакана символах, пиксельный SVG-кактус как лого/favicon.
This commit is contained in:
@@ -1,11 +1,45 @@
|
||||
// TODO: полноценный canvas-эффект цифрового дождя — этап 2
|
||||
const canvas = document.getElementById('matrix-rain');
|
||||
if (canvas) {
|
||||
|
||||
if (canvas && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
const ctx = canvas.getContext('2d');
|
||||
const resize = () => {
|
||||
const chars = 'アカサタナハマヤラワ0123456789ABCDEFcacto$#@%&*'.split('');
|
||||
const fontSize = 15;
|
||||
const bg = getComputedStyle(document.documentElement).getPropertyValue('--color-bg').trim();
|
||||
const accent = getComputedStyle(document.documentElement).getPropertyValue('--color-accent').trim();
|
||||
const silver = getComputedStyle(document.documentElement).getPropertyValue('--color-silver').trim();
|
||||
|
||||
let columns = 0;
|
||||
let drops = [];
|
||||
|
||||
function setup() {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
};
|
||||
resize();
|
||||
window.addEventListener('resize', resize);
|
||||
columns = Math.floor(canvas.width / fontSize);
|
||||
drops = new Array(columns).fill(0).map(() => Math.floor((Math.random() * canvas.height) / fontSize));
|
||||
}
|
||||
|
||||
function draw() {
|
||||
ctx.fillStyle = `${bg}cc`;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.font = `${fontSize}px monospace`;
|
||||
|
||||
for (let i = 0; i < columns; i++) {
|
||||
const char = chars[Math.floor(Math.random() * chars.length)];
|
||||
const x = i * fontSize;
|
||||
const y = drops[i] * fontSize;
|
||||
|
||||
ctx.fillStyle = Math.random() > 0.98 ? silver : accent;
|
||||
ctx.fillText(char, x, y);
|
||||
|
||||
if (y > canvas.height && Math.random() > 0.975) {
|
||||
drops[i] = 0;
|
||||
} else {
|
||||
drops[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup();
|
||||
window.addEventListener('resize', setup);
|
||||
setInterval(draw, 50);
|
||||
}
|
||||
|
||||
+39
-1
@@ -1 +1,39 @@
|
||||
// TODO: рендер карточек проектов из данных — этап 2
|
||||
const projects = [
|
||||
{
|
||||
name: 'home_automatization',
|
||||
title: 'Home Automation Platform',
|
||||
description:
|
||||
'Микросервисная платформа умного дома на Go и Laravel. Первая зона — гроубокс (полив, свет, климат), дальше — весь дом.',
|
||||
tags: ['Go', 'Laravel', 'Docker', 'RabbitMQ', 'ClickHouse', 'gRPC', 'MQTT'],
|
||||
url: 'https://git.cactoz.su/cacto/home_automatization',
|
||||
},
|
||||
{
|
||||
name: 'cactoz.su',
|
||||
title: 'cactoz.su — этот сайт',
|
||||
description:
|
||||
'Личный сайт-визитка: резюме, проекты и мультиплеерный клон BattleCity. Тема — Матрица.',
|
||||
tags: ['HTML/CSS/JS', 'C++', 'uWebSockets', 'Quintus.js', 'nginx', 'Docker'],
|
||||
url: 'https://git.cactoz.su/cacto/cactoz.su',
|
||||
},
|
||||
];
|
||||
|
||||
const list = document.getElementById('project-list');
|
||||
|
||||
if (list) {
|
||||
list.innerHTML = projects
|
||||
.map(
|
||||
(p) => `
|
||||
<li class="project-card">
|
||||
<div class="project-card__bar"><span></span>${p.name}/README.md</div>
|
||||
<div class="project-card__body">
|
||||
<h3 class="project-card__title">${p.title}</h3>
|
||||
<p class="project-card__desc">${p.description}</p>
|
||||
<ul class="tag-list">
|
||||
${p.tags.map((t) => `<li class="tag">${t}</li>`).join('')}
|
||||
</ul>
|
||||
<a class="project-card__link" href="${p.url}" target="_blank" rel="noopener">${p.url.replace('https://', '')}</a>
|
||||
</div>
|
||||
</li>`
|
||||
)
|
||||
.join('');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user