Index > Fix vidéos non prise en charges dans le slider
All checks were successful
Deploy / Deploy to Production (push) Successful in 5s
All checks were successful
Deploy / Deploy to Production (push) Successful in 5s
This commit is contained in:
parent
c92e492fbc
commit
9a615bd92d
7 changed files with 97 additions and 81 deletions
|
|
@ -31,7 +31,7 @@ body[data-template="index"] {
|
||||||
|
|
||||||
section.toggle {
|
section.toggle {
|
||||||
.project-slideshow {
|
.project-slideshow {
|
||||||
picture:not(.active) {
|
.slide:not(.active) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,8 @@ button#mobile-menu-toggle {
|
||||||
right: 0;
|
right: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
picture img {
|
picture img,
|
||||||
|
video.slide {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: calc(100vh - var(--body-margin) * 2);
|
max-height: calc(100vh - var(--body-margin) * 2);
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,16 @@
|
||||||
inset: 0;
|
inset: 0;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
picture {
|
picture,
|
||||||
|
video.slide {
|
||||||
inset: 0;
|
inset: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
img {
|
}
|
||||||
width: 100%;
|
picture img,
|
||||||
height: 100%;
|
video.slide {
|
||||||
object-fit: cover;
|
width: 100%;
|
||||||
}
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,8 @@ button#mobile-menu-toggle {
|
||||||
right: 0;
|
right: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
.project-slideshow picture img {
|
.project-slideshow picture img,
|
||||||
|
.project-slideshow video.slide {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: calc(100vh - var(--body-margin) * 2);
|
max-height: calc(100vh - var(--body-margin) * 2);
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
|
|
@ -586,7 +587,7 @@ body[data-template=index] .filter-menu ul {
|
||||||
body[data-template=index] .projects-index li.filtered-out {
|
body[data-template=index] .projects-index li.filtered-out {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
body[data-template=index] .projects-index li section.toggle .project-slideshow picture:not(.active) {
|
body[data-template=index] .projects-index li section.toggle .project-slideshow .slide:not(.active) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
body[data-template=index] ul.projects-index {
|
body[data-template=index] ul.projects-index {
|
||||||
|
|
@ -621,11 +622,13 @@ body[data-template=index] ul.projects-index {
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.project-slideshow picture {
|
.project-slideshow picture,
|
||||||
|
.project-slideshow video.slide {
|
||||||
inset: 0;
|
inset: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
.project-slideshow picture img {
|
.project-slideshow picture img,
|
||||||
|
.project-slideshow video.slide {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
-o-object-fit: cover;
|
-o-object-fit: cover;
|
||||||
|
|
|
||||||
|
|
@ -7,116 +7,104 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
const firstProject = projects[0];
|
const firstProject = projects[0];
|
||||||
const lastProject = projects[projects.length - 1];
|
const lastProject = projects[projects.length - 1];
|
||||||
|
|
||||||
const firstPictureFirstProject = firstProject.querySelector(
|
// Première / dernière slide d'un projet (image OU vidéo).
|
||||||
".project-slideshow picture:first-of-type",
|
// On cible la classe « .slide » au lieu de la balise « picture »
|
||||||
);
|
// pour que les vidéos comptent comme des slides normales.
|
||||||
const firstPictureLastProject = lastProject.querySelector(
|
const firstSlide = (project) =>
|
||||||
".project-slideshow picture:first-of-type",
|
project.querySelector(".project-slideshow > .slide");
|
||||||
);
|
const lastSlide = (project) => {
|
||||||
const lastPictureLastProject = lastProject.querySelector(
|
const slides = project.querySelectorAll(".project-slideshow > .slide");
|
||||||
".project-slideshow picture:last-of-type",
|
return slides[slides.length - 1];
|
||||||
);
|
};
|
||||||
|
|
||||||
|
const firstSlideFirstProject = firstSlide(firstProject);
|
||||||
|
const firstSlideLastProject = firstSlide(lastProject);
|
||||||
|
const lastSlideLastProject = lastSlide(lastProject);
|
||||||
|
|
||||||
// Fonctions de navigation : les éléments « courants » sont re-requêtés
|
// Fonctions de navigation : les éléments « courants » sont re-requêtés
|
||||||
// à chaque appel pour refléter l'état actuel du DOM.
|
// à chaque appel pour refléter l'état actuel du DOM.
|
||||||
|
|
||||||
function goToNextPicture() {
|
function goToNextPicture() {
|
||||||
const activePicture = document.querySelector(
|
|
||||||
".project.selected .project-slideshow > picture.active",
|
|
||||||
);
|
|
||||||
const lastPicture = document.querySelector(
|
|
||||||
".project.selected .project-slideshow > picture:last-of-type",
|
|
||||||
);
|
|
||||||
const selectedProject = document.querySelector(".project.selected");
|
const selectedProject = document.querySelector(".project.selected");
|
||||||
const nextProject = selectedProject.nextElementSibling;
|
const activeSlide = selectedProject.querySelector(
|
||||||
const firstPictureNextProject = nextProject?.querySelector(
|
".project-slideshow > .slide.active",
|
||||||
".project-slideshow picture:first-of-type",
|
|
||||||
);
|
);
|
||||||
|
const lastSlideSelected = lastSlide(selectedProject);
|
||||||
|
const nextProject = selectedProject.nextElementSibling;
|
||||||
|
|
||||||
if (activePicture !== lastPicture) {
|
if (activeSlide !== lastSlideSelected) {
|
||||||
activePicture.classList.remove("active");
|
activeSlide.classList.remove("active");
|
||||||
activePicture.nextElementSibling.classList.add("active");
|
activeSlide.nextElementSibling.classList.add("active");
|
||||||
} else {
|
} else {
|
||||||
selectedProject.classList.remove("selected");
|
selectedProject.classList.remove("selected");
|
||||||
activePicture.classList.remove("active");
|
activeSlide.classList.remove("active");
|
||||||
if (selectedProject !== lastProject) {
|
if (selectedProject !== lastProject) {
|
||||||
nextProject.classList.add("selected");
|
nextProject.classList.add("selected");
|
||||||
firstPictureNextProject.classList.add("active");
|
firstSlide(nextProject).classList.add("active");
|
||||||
} else {
|
} else {
|
||||||
firstProject.classList.add("selected");
|
firstProject.classList.add("selected");
|
||||||
firstPictureFirstProject.classList.add("active");
|
firstSlideFirstProject.classList.add("active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPrevPicture() {
|
function goToPrevPicture() {
|
||||||
const activePicture = document.querySelector(
|
|
||||||
".project.selected .project-slideshow > picture.active",
|
|
||||||
);
|
|
||||||
const firstPicture = document.querySelector(
|
|
||||||
".project.selected .project-slideshow > picture:first-of-type",
|
|
||||||
);
|
|
||||||
const selectedProject = document.querySelector(".project.selected");
|
const selectedProject = document.querySelector(".project.selected");
|
||||||
const prevProject = selectedProject.previousElementSibling;
|
const activeSlide = selectedProject.querySelector(
|
||||||
const lastPicturePrevProject = prevProject?.querySelector(
|
".project-slideshow > .slide.active",
|
||||||
".project-slideshow picture:last-of-type",
|
|
||||||
);
|
);
|
||||||
|
const firstSlideSelected = firstSlide(selectedProject);
|
||||||
|
const prevProject = selectedProject.previousElementSibling;
|
||||||
|
|
||||||
if (activePicture !== firstPicture) {
|
if (activeSlide !== firstSlideSelected) {
|
||||||
activePicture.classList.remove("active");
|
activeSlide.classList.remove("active");
|
||||||
activePicture.previousElementSibling.classList.add("active");
|
activeSlide.previousElementSibling.classList.add("active");
|
||||||
} else {
|
} else {
|
||||||
selectedProject.classList.remove("selected");
|
selectedProject.classList.remove("selected");
|
||||||
activePicture.classList.remove("active");
|
activeSlide.classList.remove("active");
|
||||||
if (selectedProject !== firstProject) {
|
if (selectedProject !== firstProject) {
|
||||||
prevProject.classList.add("selected");
|
prevProject.classList.add("selected");
|
||||||
lastPicturePrevProject.classList.add("active");
|
lastSlide(prevProject).classList.add("active");
|
||||||
} else {
|
} else {
|
||||||
lastProject.classList.add("selected");
|
lastProject.classList.add("selected");
|
||||||
lastPictureLastProject.classList.add("active");
|
lastSlideLastProject.classList.add("active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPrevProject() {
|
function goToPrevProject() {
|
||||||
const activePicture = document.querySelector(
|
|
||||||
".project.selected .project-slideshow > picture.active",
|
|
||||||
);
|
|
||||||
const selectedProject = document.querySelector(".project.selected");
|
const selectedProject = document.querySelector(".project.selected");
|
||||||
const prevProject = selectedProject.previousElementSibling;
|
const activeSlide = selectedProject.querySelector(
|
||||||
const firstPicturePrevProject = prevProject?.querySelector(
|
".project-slideshow > .slide.active",
|
||||||
".project-slideshow picture:first-of-type",
|
|
||||||
);
|
);
|
||||||
|
const prevProject = selectedProject.previousElementSibling;
|
||||||
|
|
||||||
activePicture.classList.remove("active");
|
activeSlide.classList.remove("active");
|
||||||
selectedProject.classList.remove("selected");
|
selectedProject.classList.remove("selected");
|
||||||
if (selectedProject !== firstProject) {
|
if (selectedProject !== firstProject) {
|
||||||
prevProject.classList.add("selected");
|
prevProject.classList.add("selected");
|
||||||
firstPicturePrevProject.classList.add("active");
|
firstSlide(prevProject).classList.add("active");
|
||||||
} else {
|
} else {
|
||||||
lastProject.classList.add("selected");
|
lastProject.classList.add("selected");
|
||||||
firstPictureLastProject.classList.add("active");
|
firstSlideLastProject.classList.add("active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToNextProject() {
|
function goToNextProject() {
|
||||||
const activePicture = document.querySelector(
|
|
||||||
".project.selected .project-slideshow > picture.active",
|
|
||||||
);
|
|
||||||
const selectedProject = document.querySelector(".project.selected");
|
const selectedProject = document.querySelector(".project.selected");
|
||||||
const nextProject = selectedProject.nextElementSibling;
|
const activeSlide = selectedProject.querySelector(
|
||||||
const firstPictureNextProject = nextProject?.querySelector(
|
".project-slideshow > .slide.active",
|
||||||
".project-slideshow picture:first-of-type",
|
|
||||||
);
|
);
|
||||||
|
const nextProject = selectedProject.nextElementSibling;
|
||||||
|
|
||||||
activePicture.classList.remove("active");
|
activeSlide.classList.remove("active");
|
||||||
selectedProject.classList.remove("selected");
|
selectedProject.classList.remove("selected");
|
||||||
if (selectedProject !== lastProject) {
|
if (selectedProject !== lastProject) {
|
||||||
nextProject.classList.add("selected");
|
nextProject.classList.add("selected");
|
||||||
firstPictureNextProject.classList.add("active");
|
firstSlide(nextProject).classList.add("active");
|
||||||
} else {
|
} else {
|
||||||
firstProject.classList.add("selected");
|
firstProject.classList.add("selected");
|
||||||
firstPictureFirstProject.classList.add("active");
|
firstSlideFirstProject.classList.add("active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,11 @@ allProjects.forEach((currentProject) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
currentProject
|
currentProject
|
||||||
.querySelectorAll("picture")
|
.querySelectorAll(".project-slideshow > .slide")
|
||||||
.forEach((picture) => picture.classList.remove("active"));
|
.forEach((slide) => slide.classList.remove("active"));
|
||||||
currentProject.querySelector("picture:first-child").classList.add("active");
|
currentProject
|
||||||
|
.querySelector(".project-slideshow > .slide")
|
||||||
|
.classList.add("active");
|
||||||
currentProject.classList.toggle("selected");
|
currentProject.classList.toggle("selected");
|
||||||
|
|
||||||
Router.setParam("project", currentProject.dataset.slug);
|
Router.setParam("project", currentProject.dataset.slug);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<?php foreach ($page->children()->listed()->sortBy('date', 'desc') as $project): ?>
|
<?php foreach ($page->children()->listed()->sortBy('date', 'desc') as $project): ?>
|
||||||
|
<?php $slides = $project->slideshow()->toFiles(); ?>
|
||||||
<li class="project" data-category="<?= Str::slug($project->category()) ?>" data-slug="<?= $project->slug() ?>">
|
<li class="project" data-category="<?= Str::slug($project->category()) ?>" data-slug="<?= $project->slug() ?>">
|
||||||
<div class="fix">
|
<div class="fix">
|
||||||
<button class="project-toggler grid">
|
<button class="project-toggler grid">
|
||||||
|
|
@ -21,20 +22,39 @@
|
||||||
<span> <?= $project->tags() ?> </span>
|
<span> <?= $project->tags() ?> </span>
|
||||||
<span class="date"> <?= $project->date()->toDate('Y') ?> </span>
|
<span class="date"> <?= $project->date()->toDate('Y') ?> </span>
|
||||||
</button>
|
</button>
|
||||||
<span class="slide-number"><span class="current-image">1</span>/<?= $project->images()->count() ?></span>
|
<span class="slide-number"><span class="current-image">1</span>/<?= $slides->count() ?></span>
|
||||||
</div>
|
</div>
|
||||||
<section class="toggle">
|
<section class="toggle">
|
||||||
<div class= "project-slideshow-container">
|
<div class= "project-slideshow-container">
|
||||||
<button class="closer"></button>
|
<button class="closer"></button>
|
||||||
<div class="project-slideshow">
|
<div class="project-slideshow">
|
||||||
<?php foreach ($project->images() as $image): ?>
|
<?php foreach ($slides->values() as $i => $slide): ?>
|
||||||
<?php snippet('picture', [
|
<?php if ($slide->type() === 'video'): ?>
|
||||||
'file' => $image,
|
<?php
|
||||||
'srcsetName' => 'project-slideshow',
|
// Type web fiable basé sur l'extension : le mime() de Kirby
|
||||||
'sizes' => '(min-width: 1000px) 50vw, 100vw',
|
// peut renvoyer video/quicktime pour un .mp4 (fichier .mov
|
||||||
'lazy' => $image->indexOf() !== 0,
|
// renommé), ce que Chrome/Firefox refusent de lire.
|
||||||
'class' => $image->indexOf() === 0 ? 'active' : null,
|
$videoTypes = [
|
||||||
]) ?>
|
'mp4' => 'video/mp4',
|
||||||
|
'm4v' => 'video/mp4',
|
||||||
|
'mov' => 'video/mp4',
|
||||||
|
'webm' => 'video/webm',
|
||||||
|
'ogv' => 'video/ogg',
|
||||||
|
];
|
||||||
|
$videoType = $videoTypes[strtolower($slide->extension())] ?? $slide->mime();
|
||||||
|
?>
|
||||||
|
<video class="slide<?= $i === 0 ? ' active' : '' ?>" autoplay muted loop playsinline data-id="<?= $slide->uuid() ?>">
|
||||||
|
<source src="<?= $slide->url() ?>" type="<?= $videoType ?>">
|
||||||
|
</video>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php snippet('picture', [
|
||||||
|
'file' => $slide,
|
||||||
|
'srcsetName' => 'project-slideshow',
|
||||||
|
'sizes' => '(min-width: 1000px) 50vw, 100vw',
|
||||||
|
'lazy' => $i !== 0,
|
||||||
|
'class' => $i === 0 ? 'slide active' : 'slide',
|
||||||
|
]) ?>
|
||||||
|
<?php endif ?>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<button class="prev"></button>
|
<button class="prev"></button>
|
||||||
<button class="next"></button>
|
<button class="next"></button>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue