image zoom
This commit is contained in:
parent
a891f1087a
commit
56db1b365d
5 changed files with 130 additions and 1 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
transition: transform 0.3s, box-shadow 0.3s;
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > *:hover {
|
& > *:hover {
|
||||||
|
|
@ -41,3 +42,68 @@
|
||||||
grid-row: span 2;
|
grid-row: span 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#lightbox {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
-webkit-backdrop-filter: blur(8px);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
max-width: min(90vw, 1200px);
|
||||||
|
max-height: 85vh;
|
||||||
|
border-radius: var(--small-radius);
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > button {
|
||||||
|
position: absolute;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& #lb-close {
|
||||||
|
top: 1.5rem;
|
||||||
|
right: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& #lb-prev {
|
||||||
|
left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& #lb-next {
|
||||||
|
right: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,6 @@ templ Portfolio(images []string) {
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
<script defer src="portfolio.js"></script>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ func Portfolio(images []string) templ.Component {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</div></section></main>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</div></section></main><script defer src=\"portfolio.js\"></script>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
61
js/portfolio.js
Normal file
61
js/portfolio.js
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
(function () {
|
||||||
|
var grid = document.getElementById('portfolio-grid');
|
||||||
|
if (!grid) return;
|
||||||
|
|
||||||
|
var items = Array.from(grid.querySelectorAll(':scope > div'));
|
||||||
|
if (!items.length) return;
|
||||||
|
|
||||||
|
var lb = document.createElement('div');
|
||||||
|
lb.id = 'lightbox';
|
||||||
|
lb.innerHTML =
|
||||||
|
'<button id="lb-close" aria-label="Zamknij"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button>' +
|
||||||
|
'<button id="lb-prev" aria-label="Poprzednie"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg></button>' +
|
||||||
|
'<img src="" alt="">' +
|
||||||
|
'<button id="lb-next" aria-label="Następne"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></button>';
|
||||||
|
document.body.appendChild(lb);
|
||||||
|
|
||||||
|
var lbImg = lb.querySelector('img');
|
||||||
|
var current = -1;
|
||||||
|
|
||||||
|
function open(idx) {
|
||||||
|
current = idx;
|
||||||
|
var img = items[current].querySelector('img');
|
||||||
|
lbImg.src = img.src;
|
||||||
|
lbImg.alt = img.alt;
|
||||||
|
lb.classList.add('open');
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
lb.classList.remove('open');
|
||||||
|
current = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prev() {
|
||||||
|
if (current < 0) return;
|
||||||
|
open((current - 1 + items.length) % items.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (current < 0) return;
|
||||||
|
open((current + 1) % items.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
items.forEach(function (item, i) {
|
||||||
|
item.addEventListener('click', function () { open(i); });
|
||||||
|
});
|
||||||
|
|
||||||
|
lb.querySelector('#lb-close').addEventListener('click', close);
|
||||||
|
lb.querySelector('#lb-prev').addEventListener('click', function (e) { e.stopPropagation(); prev(); });
|
||||||
|
lb.querySelector('#lb-next').addEventListener('click', function (e) { e.stopPropagation(); next(); });
|
||||||
|
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
if (!lb.classList.contains('open')) return;
|
||||||
|
if (e.key === 'Escape') { close(); e.preventDefault(); }
|
||||||
|
if (e.key === 'ArrowLeft') { prev(); e.preventDefault(); }
|
||||||
|
if (e.key === 'ArrowRight') { next(); e.preventDefault(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
lb.addEventListener('click', function (e) {
|
||||||
|
if (e.target === lb) close();
|
||||||
|
});
|
||||||
|
})();
|
||||||
1
main.go
1
main.go
|
|
@ -105,6 +105,7 @@ func main() {
|
||||||
mergeStyles()
|
mergeStyles()
|
||||||
utils.CopyFile("img/favicon.avif", "www/images/favicon.avif")
|
utils.CopyFile("img/favicon.avif", "www/images/favicon.avif")
|
||||||
utils.CopyFile("img/logo.svg", "www/images/logo.svg")
|
utils.CopyFile("img/logo.svg", "www/images/logo.svg")
|
||||||
|
utils.CopyFile("js/portfolio.js", "www/portfolio.js")
|
||||||
log.Println("listening on :8000")
|
log.Println("listening on :8000")
|
||||||
log.Fatal(http.ListenAndServe(":8000", http.FileServer(http.Dir("www"))))
|
log.Fatal(http.ListenAndServe(":8000", http.FileServer(http.Dir("www"))))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue