This commit is contained in:
2025-11-06 01:40:00 +01:00
parent de5f54f4bc
commit 602c5a40f1
108 changed files with 9859 additions and 1382 deletions

View File

@@ -0,0 +1,90 @@
import React, { useEffect, useRef } from "react"
import styles from "./drone.module.css"
export default function Drone() {
const videoRef = useRef<HTMLVideoElement | null>(null)
const sourceRef = useRef<HTMLSourceElement | null>(null)
useEffect(() => {
function setVideoDroneQuality() {
if (!sourceRef.current || !videoRef.current) return
const videoSources = {
fullHD: "static/home/video/drone-background-video-1080p.mp4", // For desktops (1920x1080)
hd: "static/home/video/drone-background-video-720p.mp4", // For tablets/smaller screens (1280x720)
lowRes: "static/home/video/drone-background-video-480p.mp4" // For mobile devices or low performance (854x480)
}
const screenWidth = window.innerWidth
// Pick appropriate source
if (screenWidth >= 1920) {
sourceRef.current.src =
"https://vontor-cz.s3.eu-central-1.amazonaws.com/" + videoSources.fullHD
} else if (screenWidth >= 1280) {
sourceRef.current.src =
"https://vontor-cz.s3.eu-central-1.amazonaws.com/" + videoSources.hd
} else {
sourceRef.current.src =
"https://vontor-cz.s3.eu-central-1.amazonaws.com/" + videoSources.lowRes
}
// Reload video
videoRef.current.load()
console.log("Drone video set!")
}
// Run once on mount
setVideoDroneQuality()
// Optional: rerun on resize
window.addEventListener("resize", setVideoDroneQuality)
return () => {
window.removeEventListener("resize", setVideoDroneQuality)
}
}, [])
return (
<div className={`${styles.drone}`}>
<video
ref={videoRef}
id="drone-video"
className={styles.videoBackground}
autoPlay
muted
loop
playsInline
>
<source ref={sourceRef} id="video-source" type="video/mp4" />
Your browser does not support video.
</video>
<article>
<header>
<h1>Letecké záběry, co zaujmou</h1>
</header>
<main>
<section>
<h2>Oprávnění</h2>
<p>Oprávnění A1/A2/A3 + radiostanice. Bezpečný provoz i v omezených zónách, povolení zajistím.</p>
</section>
<section>
<h2>Cena</h2>
<p>Paušál 3000. Ostrava zdarma; mimo 10/km. Cena se může lišit dle povolení.</p>
</section>
<section>
<h2>Výstup</h2>
<p>Krátký sestřih nebo surové záběry podle potřeby.</p>
</section>
</main>
<div>
<a href="#contacts">Zájem?</a>
</div>
</article>
</div>
)
}

View File

@@ -0,0 +1,103 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
.drone{
margin-top: -4em;
font-style: normal;
width: 100%;
position: relative;
color: white;
}
.drone .videoBackground {
height: 100%;
width: 100%;
position: absolute;
object-fit: cover;
z-index: -1;
clip-path: polygon(0 3%, 15% 0, 30% 7%, 42% 3%, 61% 1%, 82% 5%, 100% 1%, 100% 94%, 82% 100%, 65% 96%, 47% 99%, 30% 90%, 14% 98%, 0 94%);
}
.drone article{
padding: 5em;
display: flex;
border-radius: 2em;
padding: 3em;
gap: 2em;
position: relative;
align-items: center;
flex-direction: column;
justify-content: space-evenly;
}
.drone article header h1{
font-size: 4em;
font-weight: 300;
}
.drone article header{
flex: 1;
}
.drone article main{
width: 90%;
display: flex;
font-size: 1em;
/* width: 60%; */
flex: 2;
flex-direction: row;
font-weight: 400;
gap: 2em;
/* flex-wrap: wrap; */
justify-content: space-evenly;
}
.drone a{
color: white;
}
.drone article div{
display: flex;
flex: 1;
font-size: 1.25em;
margin-top: 1em;
margin-bottom: 1em;
flex-direction: column;
align-items: center;
font-weight: 400;
}
@media only screen and (max-width: 990px) {
.drone article header h1{
font-size: 2.3em;
font-weight: 200;
}
.drone article header{
text-align: center;
}
.drone article main{
flex-direction: column;
font-size: 1em;
}
.drone article{
height: auto;
}
.drone article div{
margin: 2em;
text-align: center;
}
.drone video{
display: none;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -0,0 +1,168 @@
.portfolio {
margin: auto;
margin-top: 10em;
width: 80%;
display: flex;
flex-wrap: wrap;
align-content: center;
color: white;
position: relative;
}
.portfolio div .door {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
bottom: 0;
left: 0;
height: 100%;
width: 100%;
background-color: #c2a67d;
color: #5e5747;
border-radius: 1em;
transform-origin: bottom;
transition: transform 0.5s ease-in-out;
transform: skew(-5deg);
z-index: 3;
box-shadow: #000000 5px 5px 15px;
}
.portfolio div span svg{
font-size: 5em;
cursor: pointer;
animation: shake 0.4s ease-in-out infinite;
}
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(-2px) rotate(-8deg); }
50% { transform: translateX(2px) rotate(4deg); }
75% { transform: translateX(-1px) rotate(-2deg); }
100% { transform: translateX(0); }
}
.door i{
color: #5e5747;
font-size: 5em;
display: inline-block;
animation: shake 0.4s ease-in-out infinite;
animation-delay: 2s;
animation-iteration-count: infinite;
}
.portfolio .door-open{
transform: rotateX(90deg) skew(-2deg) !important;
}
.portfolio>header {
width: fit-content;
position: absolute;
z-index: 0;
top: -3.7em;
left: 0;
padding: 1em 3em;
padding-bottom: 0;
background-color: #cdc19c;
color: #5e5747;
border-top-left-radius: 1em;
border-top-right-radius: 1em;
}
.portfolio>header h1 {
font-size: 2.5em;
padding: 0;
}
.portfolio>header i {
font-size: 6em;
}
.portfolio article{
position: relative;
}
.portfolio article::after{
clip-path: polygon(0% 0%, 11% 12.5%, 0% 25%, 11% 37.5%, 0% 50%, 11% 62.5%, 0% 75%, 11% 87.5%, 0% 100%, 100% 100%, 84% 87.5%, 98% 75%, 86% 62.5%, 100% 50%, 86% 37.5%, 100% 25%, 93% 12.5%, 100% 0%);
content: "";
bottom: 0;
right: -2em;
height: 2em;
width: 6em;
transform: rotate(-45deg);
position: absolute;
background-color: rgba(255, 255, 255, 0.5);
}
.portfolio article::before{
clip-path: polygon(0% 0%, 11% 12.5%, 0% 25%, 11% 37.5%, 0% 50%, 11% 62.5%, 0% 75%, 11% 87.5%, 0% 100%, 100% 100%, 84% 87.5%, 98% 75%, 86% 62.5%, 100% 50%, 86% 37.5%, 100% 25%, 93% 12.5%, 100% 0%);
content: "";
top: 0;
left: -2em;
height: 2em;
width: 6em;
transform: rotate(-45deg);
position: absolute;
background-color: rgba(255, 255, 255, 0.5);
}
.portfolio article header {
display: flex;
flex-direction: column;
align-items: center;
}
.portfolio div {
width: 100%;
padding: 3em;
background-color: #cdc19c;
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 5em;
border-radius: 1em;
border-top-left-radius: 0;
aspect-ratio: 16 / 9;
}
.portfolio div article {
display: flex;
border-radius: 0em;
background-color: #9c885c;
width: 30%;
text-align: center;
flex-direction: column;
justify-content: center;
align-items: center;
}
.portfolio div article header a img {
width: 80%;
margin: auto;
}
@media only screen and (max-width: 990px) {
.portfolio div{
flex-direction: column;
align-items: center;
}
.portfolio div article{
width: 100%;
}
}

View File

@@ -0,0 +1,86 @@
import React, { useState } from "react"
import styles from "./Portfolio.module.css"
import { LuMousePointerClick } from "react-icons/lu";
interface PortfolioItem {
href: string
src: string
alt: string
// Optional per-item styling (prefer Tailwind utility classes in className/imgClassName)
className?: string
imgClassName?: string
style?: React.CSSProperties
imgStyle?: React.CSSProperties
}
const portfolioItems: PortfolioItem[] = [
{
href: "https://davo1.cz",
src: "/portfolio/davo1.png",
alt: "davo1.cz logo",
imgClassName: "bg-black rounded-lg p-4",
//className: "bg-white/5 rounded-lg p-4",
},
{
href: "https://perlica.cz",
src: "/portfolio/perlica.png",
alt: "Perlica logo",
imgClassName: "rounded-lg",
// imgClassName: "max-h-12",
},
{
href: "http://epinger2.cz",
src: "/portfolio/epinger.png",
alt: "Epinger2 logo",
imgClassName: "bg-white rounded-lg",
// imgClassName: "max-h-12",
},
]
export default function Portfolio() {
const [doorOpen, setDoorOpen] = useState(false)
const toggleDoor = () => setDoorOpen((prev) => !prev)
return (
<div className={styles.portfolio} id="portfolio">
<header>
<h1>Portfolio</h1>
</header>
<div>
<span
className={
doorOpen
? `${styles.door} ${styles["door-open"]}`
: styles.door
}
onClick={toggleDoor}
>
<LuMousePointerClick/>
</span>
{portfolioItems.map((item, index) => (
<article
key={index}
className={`${styles.article} ${item.className ?? ""}`}
style={item.style}
>
<header>
<a href={item.href} target="_blank" rel="noopener noreferrer">
<img
src={item.src}
alt={item.alt}
className={item.imgClassName}
style={item.imgStyle}
/>
</a>
</header>
<main></main>
</article>
))}
</div>
</div>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB