Play icon overlay for video thumbnails + responsive mobile design

pull/3/head
Toni Melisma 4 years ago
parent 2d0aacf211
commit a3553a4dc9
No known key found for this signature in database
GPG Key ID: FFF9A7EDDEA34756

@ -6,6 +6,7 @@
- Deals with any file formats (ncluding HEIC, HEVC)
- Only updates changed files, runs incrementally
- Uses relative paths (safe for using in subdirectory or S3)
- Minimal bloat (no third party frontend libraries, minimal CSS)
*Please note that fastgallery is still pre-alpha, I am actively working on it*
@ -34,3 +35,8 @@ Then, for dependencies, install libvips42 for images and optionally ffmpeg (if y
## Roadmap
For the prioritised roadmap, please see https://github.com/tonimelisma/fastgallery/projects/1
## Third party libraries
- (govips)[https://github.com/davidbyttow/govips], lightning fast image processing and resizing library
- (Feather)[https://github.com/feathericons/feather] icons, simple and beautiful
- (Primer)[https://github.com/primer/css] CSS, Github's in-house design system

@ -16,6 +16,9 @@ import (
"github.com/davidbyttow/govips/v2/vips"
)
// assets
const assetPlaybuttonImage = "/home/toni/go/src/github.com/tonimelisma/fastgallery/assets/playbutton.png"
// global defaults
const optSymlinkDir = "_original"
const optFullsizeDir = "_pictures"
@ -438,12 +441,30 @@ func resizeThumbnailVideo(source string, destination string) {
ffmpegCommand.Stdout = os.Stdout
ffmpegCommand.Stderr = os.Stderr
// TODO overlay triangle to thumbnail to implicate it's video instead of image
err := ffmpegCommand.Run()
if err != nil {
fmt.Fprintf(os.Stderr, "Could create thumbnail of video %s", source)
fmt.Fprintf(os.Stderr, "Could not create thumbnail of video %s", source)
}
// Take thumbnail and overlay triangle image on top of it
image, err := vips.NewImageFromFile(destination)
checkError(err)
// TODO don't load overlay separately
playbuttonOverlayImage, err := vips.NewImageFromFile(assetPlaybuttonImage)
checkError(err)
// overlay play button in the middle of thumbnail picture
err = image.Composite(playbuttonOverlayImage, vips.BlendModeSource, (thumbnailWidth/2)-(playbuttonOverlayImage.Width()/2), (thumbnailHeight/2)-(playbuttonOverlayImage.Height()/2))
checkError(err)
ep := vips.NewDefaultJPEGExportParams()
imageBytes, _, err := image.Export(ep)
checkError(err)
err = ioutil.WriteFile(destination, imageBytes, optFileMode)
checkError(err)
}
func resizeFullsizeVideo(source string, destination string) {
@ -453,7 +474,7 @@ func resizeFullsizeVideo(source string, destination string) {
err := ffmpegCommand.Run()
if err != nil {
fmt.Fprintf(os.Stderr, "Could create full-size video of %s", source)
fmt.Fprintf(os.Stderr, "Could not create full-size video of %s", source)
}
}

@ -9,7 +9,7 @@
#modalHeader,
#modalFooter {
width: 500px;
min-width: 300px;
}
.modalControl:hover,

@ -14,57 +14,81 @@
<!-- Thumbnail view. First subfolders, then media. -->
<div class="container-xl">
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0">
<a href="temp2">
<img class="width-fit" src="_thumbnails/temp2/2018-10-14 15.59.20.jpg" alt="diipadaapa">
</a>
<span class="width-fit css-truncate css-truncate-target p-1">temp2</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(0);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(0);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-03-31 16.48.28.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-03-31 16.48.28.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(1);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(1);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-07-16 17.28.12 -000.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(2);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(2);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-11-10 12.36.05.jpg" alt="2018-11-10 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(3);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(3);displayModal(true);">
<img class="width-fit" src="_thumbnails/2016-05-01 18.20.21.jpg" alt="2016-05-01 18.20.21.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2016-05-01 18.20.21</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(0);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(0);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-03-31 16.48.28.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-03-31 16.48.28.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(1);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(1);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-07-16 17.28.12 -000.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(2);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(2);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-11-10 12.36.05.jpg" alt="2018-11-10 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(3);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(3);displayModal(true);">
<img class="width-fit" src="_thumbnails/2016-05-01 18.20.21.jpg" alt="2016-05-01 18.20.21.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2016-05-01 18.20.21</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(0);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(0);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-03-31 16.48.28.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-03-31 16.48.28.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(1);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(1);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-07-16 17.28.12 -000.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(2);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(2);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-11-10 12.36.05.jpg" alt="2018-11-10 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-2 d-inline-block box border border-gray box-shadow m-3 p-0" onclick="changePicture(3);displayModal(true);">
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(0);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-03-31 16.48.28.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-03-31 16.48.28.jpg</span>
</div>
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(1);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-07-16 17.28.12 -000.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(2);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-11-10 12.36.05.jpg" alt="2018-11-10 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(0);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-03-31 16.48.28.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-03-31 16.48.28.jpg</span>
</div>
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(1);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-07-16 17.28.12 -000.jpg" alt="2018-03-31 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(2);displayModal(true);">
<img class="width-fit" src="_thumbnails/2018-11-10 12.36.05.jpg" alt="2018-11-10 16.48.28.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2018-07-16 17.28.12 -000.jpg</span>
</div>
<div class="col-sm-4 col-md-3 col-lg-2 d-inline-block box border border-gray box-shadow m-md-1 m-lg-2 p-0" onclick="changePicture(3);displayModal(true);">
<img class="width-fit" src="_thumbnails/2016-05-01 18.20.21.jpg" alt="2016-05-01 18.20.21.jpg">
<span class="width-fit css-truncate css-truncate-target p-1">2016-05-01 18.20.21</span>
</div>
@ -77,14 +101,14 @@
fix order of header icons, picture height -->
<div class="position-fixed top-0 left-0 width-full height-full d-flex flex-column flex-justify-center flex-items-center box border border-gray box-shadow p-0 bg-gray" id="modal" hidden>
<div class="bg-gray clearfix position-absolute top-0 " id="modalHeader">
<div class="float-right modalControl d-inline-block" onclick="displayModal(false);">
<i data-feather="x"></i>
</div>
<div class="float-right modalControl d-inline-block">
<a href="#" id="modalDownload" download>
<i data-feather="download"></i>
</a>
</div>
<div class="float-right modalControl d-inline-block" onclick="displayModal(false);">
<i data-feather="x"></i>
</div>
</div>
<img id="modalPicture">
<div class="bg-gray position-absolute bottom-0" id="modalFooter">

Loading…
Cancel
Save