Skip to content

Commit 6e2f538

Browse files
committed
Окно-браузер превью с drag-to-scroll для 9 кейсов
Превью-скриншот в стиле «окна браузера» (флаг screenshotFramed) для aloemero, derevyannie-gryadki, ehomestroy, korea-motors, nutrilegal, retroznak, sandwich-ehomestroy, truedogage; для mike-vinogradov — два окна. - Высота окна адаптивная (max-height вместо жёсткого 4:3): короткие скриншоты целиком без пустот, длинные прокручиваются - Скриншоты подняты в начало кейса (над текстом), включая sibananda-retrit - Скрипт drag-to-scroll перенесён в layout Article.astro (работает и для ComplexArticle), курсор-«ручка» только при наличии прокрутки
1 parent 6af6479 commit 6e2f538

12 files changed

Lines changed: 123 additions & 78 deletions

src/components/SimpleArticle.astro

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,6 @@ const articleJsonLd = {
7474
</header>
7575

7676
<div class="article-body">
77-
<p set:html={localized.body} />
78-
79-
{article.tech && (
80-
<p><strong>{t('tech.label')}:</strong> {article.tech}</p>
81-
)}
82-
83-
{article.siteUrl && article.siteDisplay && (
84-
<a class="article-site-link" href={article.siteUrl} rel="nofollow noopener noreferrer" target="_blank">
85-
<ExternalLinkIcon />
86-
{article.siteDisplay}
87-
</a>
88-
)}
89-
9077
{article.screenshotUrl && article.siteUrl && (
9178
article.screenshotFramed ? (
9279
<figure class="screenshot-browser">
@@ -101,59 +88,18 @@ const articleJsonLd = {
10188
<a href={article.siteUrl} rel="nofollow noopener noreferrer" target="_blank"><img src={article.screenshotUrl} alt={localized.screenshotAlt} loading="lazy"></a>
10289
)
10390
)}
104-
</div>
105-
</Article>
106-
107-
<script>
108-
// Drag-to-scroll для превью-скриншота в «окне браузера»:
109-
// тянем мышью вверх-вниз прямо по картинке (колёсико и скроллбар тоже работают).
110-
function initDragScroll() {
111-
const containers = document.querySelectorAll<HTMLElement>('[data-drag-scroll]');
112-
containers.forEach((el) => {
113-
if (el.dataset.dragScrollReady === '1') return;
114-
el.dataset.dragScrollReady = '1';
11591

116-
let isDown = false;
117-
let startY = 0;
118-
let startScroll = 0;
119-
let moved = false;
120-
121-
const onPointerDown = (e: PointerEvent) => {
122-
if (e.button !== 0) return; // только ЛКМ
123-
isDown = true;
124-
moved = false;
125-
startY = e.clientY;
126-
startScroll = el.scrollTop;
127-
el.classList.add('is-grabbing');
128-
el.setPointerCapture(e.pointerId);
129-
};
130-
131-
const onPointerMove = (e: PointerEvent) => {
132-
if (!isDown) return;
133-
const delta = e.clientY - startY;
134-
if (Math.abs(delta) > 2) moved = true;
135-
el.scrollTop = startScroll - delta;
136-
e.preventDefault();
137-
};
138-
139-
const endDrag = (e: PointerEvent) => {
140-
if (!isDown) return;
141-
isDown = false;
142-
el.classList.remove('is-grabbing');
143-
try {
144-
el.releasePointerCapture(e.pointerId);
145-
} catch {}
146-
};
92+
<p set:html={localized.body} />
14793

148-
el.addEventListener('pointerdown', onPointerDown);
149-
el.addEventListener('pointermove', onPointerMove);
150-
el.addEventListener('pointerup', endDrag);
151-
el.addEventListener('pointercancel', endDrag);
152-
// не даём «улетать» выделению/перетаскиванию картинки
153-
el.addEventListener('dragstart', (e) => e.preventDefault());
154-
});
155-
}
94+
{article.tech && (
95+
<p><strong>{t('tech.label')}:</strong> {article.tech}</p>
96+
)}
15697

157-
initDragScroll();
158-
document.addEventListener('astro:after-swap', initDragScroll);
159-
</script>
98+
{article.siteUrl && article.siteDisplay && (
99+
<a class="article-site-link" href={article.siteUrl} rel="nofollow noopener noreferrer" target="_blank">
100+
<ExternalLinkIcon />
101+
{article.siteDisplay}
102+
</a>
103+
)}
104+
</div>
105+
</Article>

src/data/articles/aloemero.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const aloemero: Article = {
1313
siteUrl: 'https://roman-purtow.ru/aloemero/',
1414
siteDisplay: 'roman-purtow.ru/aloemero',
1515
screenshotUrl: '/images/articles/aloemero/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'ALOEMERO — лендинг скульптурной мастерской из Томска — Роман Пуртов',
1819
ogTitle: 'ALOEMERO — лендинг скульптурной мастерской из Томска',

src/data/articles/derevyannie-gryadki.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const derevyannieGryadki: Article = {
1313
siteUrl: 'https://derevyannie-gryadki.ru',
1414
siteDisplay: 'derevyannie-gryadki.ru',
1515
screenshotUrl: '/images/articles/derevyannie-gryadki/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'Деревянные грядки — лендинг производителя мини-теплиц «ДекорДом» — Роман Пуртов',
1819
ogTitle: 'Деревянные грядки — лендинг производителя мини-теплиц «ДекорДом»',

src/data/articles/ehomestroy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const ehomestroy: Article = {
1313
siteUrl: 'https://e-homestroy.ru',
1414
siteDisplay: 'e-homestroy.ru',
1515
screenshotUrl: '/images/articles/ehomestroy/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'ЭкоHomeСтрой 2.0 — редизайн сайта строительной компании — Роман Пуртов',
1819
ogTitle: 'ЭкоHomeСтрой 2.0 — редизайн сайта строительной компании',

src/data/articles/korea-motors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const koreaMotors: Article = {
1313
siteUrl: 'https://exportautorus.ru',
1414
siteDisplay: 'exportautorus.ru',
1515
screenshotUrl: '/images/articles/korea-motors/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'Korea Motors — лендинг по заказу авто из Южной Кореи — Роман Пуртов',
1819
ogTitle: 'Korea Motors — лендинг по заказу авто из Южной Кореи',

src/data/articles/mike-vinogradov.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,27 @@ export const mikeVinogradov: Article = {
1818
'Портфолио для travel-фотографа и видеографа: бенто-грид с галереями, лайтбокс, scroll-анимации, двуязычный интерфейс на Astro и Tailwind CSS v4.',
1919
h1: 'Михаил Виноградов — портфолио фотографа и&nbsp;видеографа',
2020
metaLine: 'Пуртов Роман &middot; 7 марта 2026',
21-
body: `<p>Портфолио для travel-фотографа и&nbsp;видеографа Михаила Виноградова. Бенто-грид с&nbsp;фото и&nbsp;видео-галереями, лайтбоксом и&nbsp;scroll-анимациями, двуязычный интерфейс (RU/EN), self-hosted шрифты и&nbsp;деплой на&nbsp;GitHub Pages.</p>
21+
body: `<figure class="screenshot-browser">
22+
<div class="screenshot-browser__bar" aria-hidden="true"><span></span><span></span><span></span></div>
23+
<div class="screenshot-browser__scroll" data-drag-scroll>
24+
<img src="/images/articles/mike-vinogradov/screenshot-1.jpg" alt="Скриншот портфолио Михаила Виноградова" loading="lazy" draggable="false">
25+
</div>
26+
</figure>
27+
<figure class="screenshot-browser">
28+
<div class="screenshot-browser__bar" aria-hidden="true"><span></span><span></span><span></span></div>
29+
<div class="screenshot-browser__scroll" data-drag-scroll>
30+
<img src="/images/articles/mike-vinogradov/screenshot-2.jpg" alt="Скриншот портфолио Михаила Виноградова" loading="lazy" draggable="false">
31+
</div>
32+
</figure>
33+
34+
<p>Портфолио для travel-фотографа и&nbsp;видеографа Михаила Виноградова. Бенто-грид с&nbsp;фото и&nbsp;видео-галереями, лайтбоксом и&nbsp;scroll-анимациями, двуязычный интерфейс (RU/EN), self-hosted шрифты и&nbsp;деплой на&nbsp;GitHub Pages.</p>
2235
2336
<p><strong>Технологии:</strong> Astro, TypeScript, Tailwind CSS v4, self-hosted fonts</p>
2437
2538
<a class="article-site-link" href="https://roman-purtow.ru/mike-vinogradov/" rel="nofollow noopener noreferrer" target="_blank">
2639
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" x2="21" y1="14" y2="3"/></svg>
2740
roman-purtow.ru/mike-vinogradov
28-
</a>
29-
30-
<a href="https://roman-purtow.ru/mike-vinogradov/" rel="nofollow noopener noreferrer" target="_blank"><img src="/images/articles/mike-vinogradov/screenshot-1.jpg" alt="Скриншот портфолио Михаила Виноградова" loading="lazy"></a>
31-
<a href="https://roman-purtow.ru/mike-vinogradov/" rel="nofollow noopener noreferrer" target="_blank"><img src="/images/articles/mike-vinogradov/screenshot-2.jpg" alt="Скриншот портфолио Михаила Виноградова" loading="lazy"></a>`,
41+
</a>`,
3242
screenshotAlt: 'Скриншот портфолио Михаила Виноградова',
3343
dateLabel: '7 марта 2026',
3444
},
@@ -41,17 +51,27 @@ export const mikeVinogradov: Article = {
4151
'Portfolio for a travel photographer and videographer. Bento grid with galleries, lightbox and scroll animations, bilingual interface (RU/EN), self-hosted fonts and GitHub Pages deployment.',
4252
h1: 'Mike Vinogradov — Photographer & Videographer Portfolio',
4353
metaLine: 'Roman Purtov &middot; March 7, 2026',
44-
body: `<p>Portfolio for travel photographer and videographer Mike Vinogradov. Bento grid with photo and video galleries, lightbox and scroll animations, bilingual interface (RU/EN), self-hosted fonts and GitHub Pages deployment.</p>
54+
body: `<figure class="screenshot-browser">
55+
<div class="screenshot-browser__bar" aria-hidden="true"><span></span><span></span><span></span></div>
56+
<div class="screenshot-browser__scroll" data-drag-scroll>
57+
<img src="/images/articles/mike-vinogradov/screenshot-1.jpg" alt="Mike Vinogradov portfolio screenshot" loading="lazy" draggable="false">
58+
</div>
59+
</figure>
60+
<figure class="screenshot-browser">
61+
<div class="screenshot-browser__bar" aria-hidden="true"><span></span><span></span><span></span></div>
62+
<div class="screenshot-browser__scroll" data-drag-scroll>
63+
<img src="/images/articles/mike-vinogradov/screenshot-2.jpg" alt="Mike Vinogradov portfolio screenshot" loading="lazy" draggable="false">
64+
</div>
65+
</figure>
66+
67+
<p>Portfolio for travel photographer and videographer Mike Vinogradov. Bento grid with photo and video galleries, lightbox and scroll animations, bilingual interface (RU/EN), self-hosted fonts and GitHub Pages deployment.</p>
4568
4669
<p><strong>Technologies:</strong> Astro, TypeScript, Tailwind CSS v4, self-hosted fonts</p>
4770
4871
<a class="article-site-link" href="https://roman-purtow.ru/mike-vinogradov/" rel="nofollow noopener noreferrer" target="_blank">
4972
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" x2="21" y1="14" y2="3"/></svg>
5073
roman-purtow.ru/mike-vinogradov
51-
</a>
52-
53-
<a href="https://roman-purtow.ru/mike-vinogradov/" rel="nofollow noopener noreferrer" target="_blank"><img src="/images/articles/mike-vinogradov/screenshot-1.jpg" alt="Mike Vinogradov portfolio screenshot" loading="lazy"></a>
54-
<a href="https://roman-purtow.ru/mike-vinogradov/" rel="nofollow noopener noreferrer" target="_blank"><img src="/images/articles/mike-vinogradov/screenshot-2.jpg" alt="Mike Vinogradov portfolio screenshot" loading="lazy"></a>`,
74+
</a>`,
5575
screenshotAlt: 'Mike Vinogradov portfolio screenshot',
5676
dateLabel: 'March 7, 2026',
5777
},

src/data/articles/nutrilegal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const nutrilegal: Article = {
1313
siteUrl: 'https://nutrilegal.ru',
1414
siteDisplay: 'nutrilegal.ru',
1515
screenshotUrl: '/images/articles/nutrilegal/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'Нутрилигал — сайт по регистрации БАД и СГР — Роман Пуртов',
1819
ogTitle: 'Нутрилигал — сайт консалтинговой компании по регистрации продукции',

src/data/articles/retroznak.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const retroznak: Article = {
1313
siteUrl: 'https://roman-purtow.ru/land.retroznak.ru',
1414
siteDisplay: 'roman-purtow.ru/land.retroznak.ru',
1515
screenshotUrl: '/images/articles/retroznak/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'Ретрознак — лендинг производителя адресных табличек — Роман Пуртов',
1819
ogTitle: 'Ретрознак — лендинг производителя адресных табличек',

src/data/articles/sandwich-ehomestroy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const sandwichEhomestroy: Article = {
1313
siteUrl: 'https://sandwich.e-homestroy.ru',
1414
siteDisplay: 'sandwich.e-homestroy.ru',
1515
screenshotUrl: '/images/articles/sandwich-ehomestroy/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'ЭкоHomeСтрой — лендинг строительной компании — Роман Пуртов',
1819
ogTitle: 'ЭкоHomeСтрой — лендинг строительной компании',

src/data/articles/truedogage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const truedogage: Article = {
1313
siteUrl: 'https://truedogage.com',
1414
siteDisplay: 'truedogage.com',
1515
screenshotUrl: '/images/articles/truedogage/screenshot.jpg',
16+
screenshotFramed: true,
1617
ru: {
1718
title: 'TrueDogAge — калькулятор возраста собаки по научной формуле — Роман Пуртов',
1819
ogTitle: 'TrueDogAge — калькулятор возраста собаки по научной формуле',

0 commit comments

Comments
 (0)