Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions src/_data/arts.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 переменные с цветами тоже вроде должны быть уже с подходящими названиями. Если какие-то отдельные не будут подходить - поправь

"height": "xxl_H45u",
"showInMain": true
},
{
"artId":"flushed-emoji",
"bgColor":"Bgc-$artFlushedEmoji",
"height": "xxl_H45u",
"showInMain": true
},
{
"artId":"corgi",
"bgColor":"Bgc-$artCorgi",
"height": "xxl_H75u",
"showInMain": true
},
{
"artId":"penrose-triangle",
"bgColor":"Bgc-$artPenroseTriangle",
"height": "xxl_H35u",
"showInMain": true
},
{
"artId":"exploding-head",
"bgColor":"Bgc-$artExplodingHead",
"height": "xxl_H75u",
"showInMain": true
},
{
"artId":"clown-emoji",
"bgColor":"Bgc-$artClownEmoji",
"showInMain": false
},
{
"artId":"mushroom",
"bgColor":"Bgc-$artMushroom",
"showInMain": false
},
{
"artId":"robot-hare",
"bgColor":"Bgc-$artRobotHare",
"height": "xxl_H55u",
"showInMain": true
},
{
"artId":"funny-cake",
"bgColor":"Bgc-$artFunnyCake",
"artId":"clown-emoji",
"bgColor":"Bgc-$artClownEmoji",
"height": "xxl_H70u",
"showInMain": false
},
{
"artId":"cat",
"bgColor":"Bgc-$artCat",
"height": "xxl_H60u",
"showInMain": false
},
{
"artId":"corgi",
"bgColor":"Bgc-$artCorgi",
"showInMain": true
"artId":"mushroom",
"bgColor":"Bgc-$artMushroom",
"height": "xxl_H75u",
"showInMain": false
},
{
"artId":"funny-cake",
"bgColor":"Bgc-$artFunnyCake",
"height": "xxl_H70u",
"showInMain": false
}

]
31 changes: 31 additions & 0 deletions src/_includes/components/embedded/modal.ejs

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.

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="art-modal-overlay Ps-f T0 L0 W100vw H100vh Bgc-$overlay Zi20 O0 Pne -Ts">
<div class="Ps-a T15p L50p Tf -Tr-50p;0 W85p md_W60p xl_W50p Apcr3/2 Bdrd8 Ov-h Bd0.5u;s;$brand D-f Fld-c @:o-l:w<768_H80vh">
<button class="art-modal-close btn Ps-a Zi20 T4u R4u C-$white100 md_C-$brand_h C-$brand_a -Ts">
<svg class="xxl_-Sz24" width="16" height="16">
<use href="/assets/img/icons.svg#close-menu"></use>
</svg>
</button>
<div class="art-modal-content -Sz100p <%= it.artBgc %>">

</div>
<div class="Ps-a Zi10 L0 B3u D-f Ai-c Jc-c Gap8u W100p H50 sm_H40 P0;3u">
<div class="art-modal-sandbox W100p Mxw240 H100p">
<%- include('../link-button.ejs',{
url: `http://play.mlut.style/?art=${it.artId}`,
text: "Open in sandbox",
variant: "brand"
})
%>
</div>
<div class="art-modal-share W100p Mxw240 H100p">
<%- include('../link-button.ejs',{
text: "Share",
variant: "white",
icon: "share",
iconClass: "C-$brand W20 H20"
})
%>
</div>
</div>
</div>
</div>
107 changes: 62 additions & 45 deletions src/arts.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,73 @@
layout: 'base.ejs'
area: Arts
---

<%
const artsPageCSS = {
card:"W100p H20gg Tsd-$shortTs @:hv_Tsd-$longTs",
artWrapper:"-Sz100p Ov-h Plcc-c Plci-c D-f",
button: "W12gg lg_W9gg Mxw50u xl_Mxw55u Ai-str"
card:"W100p H46u Ov-h Bdrd3u Bgc-$core815 Bd3;s;$brand Tf -S104p_h O50p O1_h sm_H50u md_H60u -Ts",
color: "C-$white100 C-$brand500_h C-$brand200_a -Ts"
}

function setCtaLength(){
return it.arts.length % 2 != 0 ? 'md_W50p' : ''
}
const position = it.arts.length % 2 != 0 ? 'md_Gc2' : 'md_Gc1/3';

const decorCss = {
gradientEclipse: "Ps-a_af Ct_af W90p_af Apcr1_af B-4p_af L50p_af Tf_af -Tr-50p;0_af Bdrd100p_af -Gdl180d,$core725;0,$core735;100p_af Ft_af -Blr100_af",
gradientPlanet: "Ps-a_b Ct_b W70p_b Apcr1_b T1p_b L50p_b Tf_b -Tr-50p;0_b Bdrd100p_b -Gdl180d,$core725;0,$core740;100p,$core745;100p_b Ft_b -Blr50_b"
}
%>
<section class="W100p Bgc-$core800 Pt-$headerH">
<div>
<h1 class="M0 Bgc-$core500 C-$accent900 Txa-c Fns7u P10u;0"> Pure CSS art</h1>

<div class="M-a W100p D-f Fld-r Flw-w Jc-c Ai-c">
<% it.arts.forEach((art, index) => {%>
<art-panel class="D Ps -Ctx W100p H20gg -Ts md_W50p" id="<%= art.artId %>">
<div class="-Sz100p Ov-h Plcc-c Plci-c D-f <%= art.bgColor %>">
<%- include(`./arts/${art.artId}.ejs`) %>
</div>
<div class="Ps-a Zi15 P4u T0 L0 M0 D-f Jc-fe Fld-c -Sz100p O0 Vs-h ^:h_Vs-v ^:h_O1 Bd1;s;tp Bgc-$core355 ^:h_Bdc-$brand Tsd500ms">
<div class="Mt-a D-f Jc-c Gap3u">
<div class="<%= artsPageCSS.button %> ">
<%- include(`./_includes/components/link-button.ejs`, {
url:`http://play.mlut.style/?art=${art.artId}`,
text: "Open in sandbox",
variant: "light"
}) %>
</div>
<div class="<%= artsPageCSS.button %> link-button" >
<%- include(`./_includes/components/link-button.ejs`, {
tag:"button",
text: "Share",
variant: "light"
}) %>
</div>
</div>

<section class="D-f Fld-c W100p Bgc-$core830 Mt-$headerH P5u;4u;10u md_P8u;8u;10u">
<div class="Ps-a W58p Apcr1 T-$headerH L50p Tf -Tr-50p;0 <%= decorCss.gradientEclipse %> <%= decorCss.gradientPlanet %>"></div>

<h1 class="M0 P2.5u Fnf-SN;Pro Fns6u sm_Fns7u Fnw700 Fnst-n Lnh150p Lts0 Txt C-$brand Txa-c">Pure css art</h1>
<p class="M0 Fns4u Fnst-n Fnw300 Lnh150p Lts0 C-$accent900 Txa-c">Created entirely with mlut utility classes</p>

<div class="Mt8.5u D-g Gtc-t1 Gap4u md_Gap6u md_Gtc-t2 xxl_Gtc-t3 xxl_D masonry">
<% it.arts.forEach((art, index) => {%>
<art-panel class="breakIns D Ps Bdrd2u Ov-h -Ctx W100p H46u sm_H50u md_H60u xxl_H-a -Ts <%= art.height %> md_Tf md_-S104p_h" id="<%= art.artId %>">
<div class="art -Sz100p Ov-h Plcc-c Plci-c <%= art.bgColor %>">
<%- include(`./arts/${art.artId}.ejs`) %>
</div>
<div class="Ps-a B0 L0 W100p H15u Zi15 P4u M0 D-f Fld-c Jc-fe O0 Pne md_^:h_Pne-a md_^:h_O1 Bgc-$gray250 Bcf -Blr15 -Ts">
<div class="Mt-a D-f Jc-sb Ai-c">
<a
class="Txd-n M0 P1u;0.5u Bdb1;s;$white100 Bdbc-$brand500_h Bdbc- Fns4u Fnst-n Fnw400 Lnh-n <%= artsPageCSS.color %>"
href="http://play.mlut.style/?art=<%= art.artId %>"
>
Open in sandbox
</a>
<button class="btn D-f <%= artsPageCSS.color %> link-button">
<svg class="copy-icon" width="24" height="24">
<use href="/assets/img/icons.svg#share"></use>
</svg>
<span class="copy-text D-n">Copied!</span>
</button>
</div>
</art-panel>
<% }) %>

<div class="<%= artsPageCSS.card %> <%= setCtaLength() %> -Ctx P3u">
<a href="https://github.com/mlutcss/website/fork" target="_blank"
class="-Sz100p Bd1u;d;$brand205 Bdc-$brand_a @:hv_Bdc-$brand205 @:hv_^:h_Bdc-$brand Bdrd5u Tsd-ih D-f Fld-c Jc-c Ai-c C-$brand Txd-n">
<svg class="M0;0;5u @:hv_O0.5 @:hv_^:h_O1 Tsd-ih H40p Stw2">
<use href="/assets/img/icons.svg#add-art"></use>
</svg>
<p class="@:hv_O0.5 @:hv_^:h_O1 M0 Tsd-ih Fns5u md_Fns7u"> Add your own art! </p>
</a>
</div>
</div>
</art-panel>
<% }) %>
</div>


<div class="<%= artsPageCSS.card %> <%= position %> Mt4u md_Mt6u">
<a
href="https://github.com/mlutcss/website/fork" target="_blank"
class="-Sz100p D-f Fld-c Jc-c Ai-c Gap5u C-$brand Txd-n -Ts"
>
<svg class="md_-Sz25u" width="57" height="57">
<use href="/assets/img/icons.svg#add-art"></use>
</svg>
<p class="M0 Tsd-ih Fns4u Fnst-n Fnw300 Lnh150p Lts0 Txa-c C-$accent900">
Want to see your work here? <br/>
Submit your CSS art
</p>
</a>
</div>

</section>



<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 (до объявления класса), и добавляешь ее в поле инстанса. Там дальше с ней работаешь

<%- include(`./_includes/components/embedded/modal.ejs`) %>
</template>
66 changes: 66 additions & 0 deletions src/assets/script/art-modal.js
Original file line number Diff line number Diff line change
@@ -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.

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


constructor() {
this.template = document.getElementById("art-card");
if (!this.template) return;

const clone = this.template.content.cloneNode(true);
this.overlay = clone.querySelector(".art-modal-overlay");
this.contentContainer = clone.querySelector(".art-modal-content");
this.closeBtn = clone.querySelector(".art-modal-close");
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 на клаве

if (e.target === this.overlay) this.close();
});
this.closeBtn.addEventListener("click", () => this.close());
this.shareBtn.addEventListener("click", () => this.copyArtLink());

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

if (!this.currentArtId) return;

const link = window.location.href.split("#")[0] + "#" + this.currentArtId;
navigator.clipboard
.writeText(link)
.then(() => {
const span = this.shareBtn.querySelector(".button-text");
const svg = this.shareBtn.querySelector("svg");

if (span) span.textContent = "Copied!";
if (svg) svg.classList.add("D-n");

setTimeout(() => {
if (span) span.textContent = "Share";
if (svg) svg.classList.remove("D-n");
}, 2000);
})
.catch((err) => console.error("Copy failed", err));
}

open(artElement, artId) {
if (!this.contentContainer) return;
this.currentArtId = artId;
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.

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

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?

this.contentContainer.appendChild(artClone);
this.overlay.classList.remove("O0", "Pne");
this.overlay.classList.add("O1", "Pne-a");
}

close() {
if (this.overlay) {
this.overlay.classList.remove("O1", "Pne-a");
this.overlay.classList.add("O0", "Pne");
if (this.contentContainer) this.contentContainer.textContent = "";
}
}
}

export const artModal = new ArtModal();
41 changes: 27 additions & 14 deletions src/assets/script/art-panel.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,48 @@
const hightlightCss = ["Bd1;s;$brand", "Bxsd1;1;10;2;$brand", "Zi19"]
import { artModal } from "./art-modal.js";

const hightlightCss = "Bxsd1;1;10;2;$brand";

export class ArtPanel extends HTMLElement {
constructor() {
super();
this.link = window.location.href
this.link = window.location.href;
}

connectedCallback() {
if (location.hash.slice(1) === this.id){
if (location.hash.slice(1) === this.id) {
this.highlightTargetArt();
}
this.button = this.querySelector(`.link-button`);
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 цепляться не стоит - лучше более специфичный селектор

artModal.open(this, this.id);
});
}

copyArtLink() {
const span = this.button.querySelector('.button-text')
this.link = this.link.split('#')[0] + `#${this.id}`
navigator.clipboard.writeText(this.link)
span.textContent = 'Copied!'
const icon = this.button.querySelector(".copy-icon");
const text = this.button.querySelector(".copy-text");
if (!icon || !text) return;

this.link = this.link.split("#")[0] + `#${this.id}`;
navigator.clipboard.writeText(this.link);

icon.classList.add("D-n");
text.classList.remove("D-n");

setTimeout(() => {
span.textContent = 'Share';
}, 2000)
icon.classList.remove("D-n");
text.classList.add("D-n");
}, 2000);
}

highlightTargetArt() {
this.classList.add(...hightlightCss)
this.classList.add(hightlightCss);
setTimeout(() => {
this.classList.remove(...hightlightCss)
},5000)
this.classList.remove(hightlightCss);
}, 5000);
}
}

customElements.define('art-panel', ArtPanel);
customElements.define("art-panel", ArtPanel);
Loading