Skip to content

feat(arts-page): add arts page and fix hero frame - #27

Open
oostap1985 wants to merge 4 commits into
mainfrom
feat/65099006_arts-page
Open

feat(arts-page): add arts page and fix hero frame#27
oostap1985 wants to merge 4 commits into
mainfrom
feat/65099006_arts-page

Conversation

@oostap1985

Copy link
Copy Markdown
Collaborator

Привет. Страницу артов сделал grid сеткой, при hover арты немного увеличиваются. Изменение grid позиции у арта, при наведении, сделать можно, но как-то криво смотрится. При клике по арту, модальное окно открывается. Жду комментов)

Comment thread src/_data/navLinks.json Outdated
Comment thread src/_data/arts.json
@@ -2,52 +2,61 @@
{
"artId":"ghost",
"bgColor":"Bgc-$artGhost",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут было бы неплохо сделать рефакторинг. Пусть название css переменной с цветом фона будет формироваться по схеме: $art${artId}. Только id надо будет перевести из cebab-case в camelCase

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет. Небольшой вопрос:
Если я переведу id в camelCase, то мне нужно будет переименовывать все файлы в папке arts (например: robotHare.ejs) и переименовать все переменные цвета (например: --ml-artrobotHare: #........). Делать так?

Пока не исправлял.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Существующий id не меняем. Переводим его только для получения названия CSS переменной. В шаблоне, вместо art.bgColor, будет что-то типа Bgc-$art${cebab2Camel(art.artId)}. CSS переменные с цветами тоже вроде должны быть уже с подходящими названиями. Если какие-то отдельные не будут подходить - поправь

Comment thread src/_data/arts.json Outdated
Comment thread src/arts-redesign.ejs Outdated
Comment thread src/arts-redesign.ejs Outdated

<%
const artsPageCSS = {
card:"W100p H46u Ov-h Bdrd12 Bgc-$core815 Bd3;s;$brand O0.5 O1_h sm_H50u md_H60u xxl_H-a -Ts",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для прозрачности лучше % использовать: O50p

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И опять же, px только в отдельных случаях: Bdrd12 -> Bdrd3u

@mr150

mr150 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

По стилю наведения карточек артов. Делаем вариант №5 из макета. При этом, backdrop-filter надо помутнее, чтобы текст кнопки хорошо читался

@oostap1985

Copy link
Copy Markdown
Collaborator Author

В последнем коммите, при xxl, арты автоматически выстраиваются в три колонки и занимают столько места по высоте, сколько передаем в "height": "....." в arts.json При добавлении нового арта, галерея сама перестроится и расположит арты так, чтобы три колонки были примерно одинаковой высоты.

Comment thread src/arts.ejs Outdated



<template id="art-card">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем здесь возиться с template? Просто делаешь кастомный элемент для модалки, в модуле art-panel получаешь модалку со страницы через querySelector (до объявления класса), и добавляешь ее в поле инстанса. Там дальше с ней работаешь

Comment thread src/assets/script/art-modal.js Outdated
@@ -0,0 +1,66 @@
export class ArtModal {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Переделываем на кастомный элемент, как писал ниже

Comment thread src/assets/script/art-modal.js Outdated
this.sandboxLink = clone.querySelector(".art-modal-sandbox a");
this.shareBtn = clone.querySelector(".art-modal-share");

this.overlay.addEventListener("click", (e) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

закрытие должно быть и по нажатию Esc на клаве

Comment thread src/assets/script/art-modal.js Outdated
document.body.appendChild(clone);
}

copyArtLink() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вместо дублирования логики надо модалке передавать колбэки из art-panel

Comment thread src/assets/script/art-modal.js Outdated
this.sandboxLink.href = `http://play.mlut.style/?art=${artId}`;
}
const artClone = artElement.querySelector(".art").cloneNode(true);
this.contentContainer.textContent = "";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему так очищается контент, а не через innerHTML?

Comment thread src/assets/script/art-modal.js Outdated
if (this.sandboxLink) {
this.sandboxLink.href = `http://play.mlut.style/?art=${artId}`;
}
const artClone = artElement.querySelector(".art").cloneNode(true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Модалка клонированием не занимается - туда уже готовый к отображению контент передаем

Comment thread src/assets/script/art-panel.js Outdated
this.button.addEventListener('click', () => this.copyArtLink())
this.button.addEventListener("click", () => this.copyArtLink());
this.addEventListener("click", (e) => {
if (e.target.closest(".link-button, a")) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На a цепляться не стоит - лучше более специфичный селектор

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В новой схеме вообще нет смысла в отдельном шаблоне. Это ведь не универсальная модалка, а только для артов

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И сейчас стили модалки не упорядочены. Некоторые арты залезают под кнопки

@mr150

mr150 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

В последнем коммите, при xxl, арты автоматически выстраиваются в три колонки и занимают столько места по высоте, сколько передаем в "height": "....." в arts.json При добавлении нового арта, галерея сама перестроится и расположит арты так, чтобы три колонки были примерно одинаковой высоты.

Уже лучше, но стоит попробовать настоящий masonry сделать, если не сильно долго будет. Наверняка есть готовые vanilla js библиотеки

@oostap1985
oostap1985 requested a review from mr150 July 28, 2026 15:29
@oostap1985

Copy link
Copy Markdown
Collaborator Author

Привет.
Написал функцию, которая переводит в PascalCase. Она работает, но получается что-то не понятное. Описываю:
Bgc динамически формируется правильно, но почему-то не работает. Магия в том, что если вернуть в массив данных поле "bgColor", все работает, хотя в компоненте я нигде не использую <%= art.bgColor %>.
Пока поле в массиве оставил.

По компоненту модального окна - вроде все исправил.

Насчет библиотеки masonry:
Также в кастомном компоненте подключается, но она не импортируется как модуль.

Нашел другую библиотеку, ее можно импортировать как модуль, но только через esm.sh (import Isotope from 'https://esm.sh/isotope-layout@3.0.6';), но работает как-то плохо. Когда заходишь на страницу артов, нужно ждать секунд 5-6, пока библиотека подгрузится. Решил не использовать ее.

@oostap1985

Copy link
Copy Markdown
Collaborator Author

И еще.
Могу убрать строгую высоту артов на мобилке и md разрешении и тогда получится как на фото (скинул в тг)

this.container = this.querySelector('.modal-container');
this.contentContainer = this.querySelector('.art-modal-content');
this.closeBtn = this.querySelector('.art-modal-close');
this.sandboxLink = this.querySelector('.art-modal-sandbox a');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Уже писал, что не надо цепляться на a

this.shareBtn = this.querySelector('.art-modal-share .btn');

document.body.appendChild(clone);
if (this.overlay) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем эти проверки? Элементы обязательные и если кто-то не добавит их - пусть компонент явно упадет

this.closeBtn = null;
this.sandboxLink = null;
this.shareBtn = null;
this._onShare = null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если уж делить на публичные и приватные свойства, то тогда все, что не вызывается из вне должно быть приватным. Тем более, внутренние элементы

this.overlay.classList.add("O0", "Pne");
if (this.contentContainer) this.contentContainer.textContent = "";
close() {
if (!this.overlay) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что-то не так с отступами


connectedCallback() {
if (!modal) {
this.modal = document.querySelector('art-modal');

@mr150 mr150 Jul 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем, если модалку получаем даже до объявления класса


const artDiv = this.querySelector('.art');
if (!artDiv) return;
const artHTML = artDiv.outerHTML;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artHtml - camelCase

const artDiv = this.querySelector('.art');
if (!artDiv) return;
const artHTML = artDiv.outerHTML;
const bgClass = this.getAttribute('data-bg-class');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это кастомный элемент, так что можно использовать кастомный атрибут, без data

icon.classList.remove("D-n");
text.classList.add("D-n");
}, 2000);
const svg = button.querySelector('svg');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На svg подвязываться не надо

const svg = button.querySelector('svg');
const span = button.querySelector('.button-text');
if (svg) svg.classList.add('D-n');
if (span) span.textContent = 'Copied!';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Перед тем, как менять текст, сохраняем исходный и его же потом восстанавливаем

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants