Add a cinema page

pull/21/head
Ivan Reshetnikov 2023-12-03 19:31:02 +05:00
parent fb42067538
commit da07f51dd2
No known key found for this signature in database
GPG Key ID: 56C7BAAE859B302C
25 changed files with 192 additions and 18 deletions

View File

@ -7,5 +7,5 @@ charset = utf-8
indent_style = space
indent_size = 2
[nginx.conf]
[{nginx.conf,*.py}]
indent_size = 4

63
convert-images.py Normal file
View File

@ -0,0 +1,63 @@
import subprocess
from os import listdir, path, makedirs
from os.path import isfile, join, splitext, exists
def main():
convert_favicon()
convert_images('public-src', 'public')
def convert_favicon():
root = 'public/favicon'
src = f'{root}/vector.svg'
sizes = [512, 192, 180, 32, 16]
for size in sizes:
dest = f'{root}/{size}.png'
if exists(dest):
continue
cmd = ['convert', src, '-resize', f'{size}x{size}', f'{root}/{size}.png']
print(' '.join(cmd))
subprocess.run(cmd)
dest = f'{root}/shortcut.ico'
if exists(dest):
return
cmd = [
'convert', src,
'(', '-clone', '0', '-resize', '16x16', ')',
'(', '-clone', '0', '-resize', '32x32', ')',
'(', '-clone', '0', '-resize', '48x48', ')',
'-delete', '0', '-alpha', 'remove', '-colors', '256',
f'{root}/shortcut.ico',
]
print(' '.join(cmd))
subprocess.run(cmd)
def convert_images(src, dest):
for i in listdir(src):
entry = join(src, i)
if isfile(entry):
if splitext(i.lower())[1] not in ['.png', '.jpg', '.jpeg']:
continue
dest_file = join(dest, i)
dest_file = splitext(dest_file)[0] + '.avif'
if exists(dest_file):
continue
cmd = ['convert', entry, '-resize', '800x', '-quality', '80', dest_file]
print(' '.join(cmd))
subprocess.run(cmd)
else:
target_dir = join(dest, i)
makedirs(target_dir, exist_ok=True)
convert_images(entry, target_dir)
if __name__ == '__main__':
main()

View File

@ -1,17 +0,0 @@
#!/bin/sh
cd public/favicon
convert vector.svg -resize 512x512 512.png
convert vector.svg -resize 192x192 192.png
convert vector.svg -resize 180x180 180.png
convert vector.svg -resize 32x32 32.png
convert vector.svg -resize 16x16 16.png
convert vector.svg \
\( -clone 0 -resize 16x16 \) \
\( -clone 0 -resize 32x32 \) \
\( -clone 0 -resize 48x48 \) \
-delete 0 -alpha remove -colors 256 shortcut.ico
cd -

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

1
public-src/readme.md Normal file
View File

@ -0,0 +1 @@
A collection of original images in high resolution.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,103 @@
---
interface Image {
src: string
alt: string
}
interface Props {
images: Image[]
}
const { images } = Astro.props
const rowCount = Math.round(images.length/3)
---
<div>
<div id="gallery" style={`grid-template-rows: repeat(${rowCount}, 263px);`}>
{images.map(img => (
<img src={img.src} alt={img.alt} loading="lazy" />
))}
</div>
<div id="fullscreenGallery" style="opacity: 0;">
<img id="fullscreenImage" />
<div id="fullscreenAlt"></div>
</div>
</div>
<style>
#gallery {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 5px;
width: 100%;
}
#gallery img {
width: 100%;
height: 100%;
object-fit: cover;
cursor: pointer;
}
#fullscreenGallery {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: flex;
background-color: #0008;
padding: 1em;
backdrop-filter: blur(42px);
justify-content: center;
align-items: center;
flex-direction: column;
gap: 1em;
pointer-events: none;
transition: opacity 0.1s ease-in-out;
}
#fullscreenAlt {
font-style: italic;
text-shadow: 0 0 4px rgba(0,0,0,.5);
}
#fullscreenImage {
width: 100%;
max-width: 800px;
display: block;
object-fit: cover;
}
</style>
<script>
window.onload = () => {
const gallery = document.getElementById("gallery")
if (!gallery) return
const fsContainer = document.getElementById("fullscreenGallery")
if (!fsContainer) return
const fsImg = document.getElementById("fullscreenImage") as HTMLImageElement
if (!fsImg) return
const fsAlt = document.getElementById("fullscreenAlt")
if (!fsAlt) return
fsContainer.addEventListener("click", () => {
fsContainer.style.opacity = "0"
fsContainer.style.pointerEvents = "none"
})
for (const img of Array.from(gallery.children) as HTMLImageElement[]) {
img.addEventListener("click", () => {
if (fsContainer.style.opacity === "0") {
fsContainer.style.opacity = "1"
fsContainer.style.pointerEvents = "auto"
fsImg.src = img.src
fsAlt.innerHTML = img.alt
} else {
fsContainer.style.opacity = "0"
fsContainer.style.pointerEvents = "none"
}
})
}
}
</script>

View File

@ -1,6 +1,7 @@
<nav>
<a href="/">Главная</a>
<a href="/services/">Сервисы</a>
<a href="/cinema/">Кинотеатр</a>
</nav>
<style>

23
src/pages/cinema.astro Normal file
View File

@ -0,0 +1,23 @@
---
import Layout from '../layouts/Layout.astro'
import Gallery from '../components/Gallery.astro'
---
<Layout
title="Кинотеатр"
description="Мои любимые кадры из кино и сериалов."
>
<h1>Кинотеатр</h1>
<p>Мои любимые кадры из кино, сериалов и игр.</p>
<Gallery images={[
{src: "/cinema/scott-pilgrim-takes-off/1.avif", alt: "Scott Pilgrim Takes Off"},
{src: "/cinema/angels-egg/1.avif", alt: "Angel's egg"},
{src: "/cinema/spider-man-across-the-spider-verse/1.avif", alt: "Spider-Man: Across the Spider-Verse"},
{src: "/cinema/yokohama-kaidashi-kikou/1.avif", alt: "Yokohama Kaidashi Kikou"},
{src: "/cinema/yokohama-kaidashi-kikou/2.avif", alt: "Yokohama Kaidashi Kikou"},
{src: "/cinema/yokohama-kaidashi-kikou/3.avif", alt: "Yokohama Kaidashi Kikou"},
{src: "/cinema/john-wick-chapter-4/1.avif", alt: "John Wick: Chapter 4"},
{src: "/cinema/night-in-the-woods/1.avif", alt: "Night in the Woods"},
{src: "/cinema/night-in-the-woods/2.avif", alt: "Night in the Woods"},
]} />
</Layout>