Add a cinema page
|
@ -7,5 +7,5 @@ charset = utf-8
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[nginx.conf]
|
[{nginx.conf,*.py}]
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
63
convert-images.py
Normal 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()
|
|
@ -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 -
|
|
BIN
public-src/cinema/angels-egg/1.jpg
Normal file
After Width: | Height: | Size: 424 KiB |
BIN
public-src/cinema/john-wick-chapter-4/1.jpg
Normal file
After Width: | Height: | Size: 307 KiB |
BIN
public-src/cinema/night-in-the-woods/1.jpg
Executable file
After Width: | Height: | Size: 66 KiB |
BIN
public-src/cinema/night-in-the-woods/2.jpg
Executable file
After Width: | Height: | Size: 94 KiB |
BIN
public-src/cinema/scott-pilgrim-takes-off/1.jpg
Normal file
After Width: | Height: | Size: 354 KiB |
BIN
public-src/cinema/spider-man-across-the-spider-verse/1.jpg
Normal file
After Width: | Height: | Size: 260 KiB |
BIN
public-src/cinema/yokohama-kaidashi-kikou/1.jpg
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
public-src/cinema/yokohama-kaidashi-kikou/2.jpg
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
public-src/cinema/yokohama-kaidashi-kikou/3.jpg
Normal file
After Width: | Height: | Size: 76 KiB |
1
public-src/readme.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
A collection of original images in high resolution.
|
BIN
public/cinema/angels-egg/1.avif
Normal file
BIN
public/cinema/john-wick-chapter-4/1.avif
Normal file
BIN
public/cinema/night-in-the-woods/1.avif
Normal file
BIN
public/cinema/night-in-the-woods/2.avif
Normal file
BIN
public/cinema/scott-pilgrim-takes-off/1.avif
Normal file
BIN
public/cinema/spider-man-across-the-spider-verse/1.avif
Normal file
BIN
public/cinema/yokohama-kaidashi-kikou/1.avif
Normal file
BIN
public/cinema/yokohama-kaidashi-kikou/2.avif
Normal file
BIN
public/cinema/yokohama-kaidashi-kikou/3.avif
Normal file
103
src/components/Gallery.astro
Normal 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>
|
|
@ -1,6 +1,7 @@
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/">Главная</a>
|
<a href="/">Главная</a>
|
||||||
<a href="/services/">Сервисы</a>
|
<a href="/services/">Сервисы</a>
|
||||||
|
<a href="/cinema/">Кинотеатр</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
23
src/pages/cinema.astro
Normal 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>
|