From f808d39c85050d34b1ab33abf4ba49806283fa8f Mon Sep 17 00:00:00 2001 From: Betsy Castro Date: Mon, 15 Jul 2024 18:12:31 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20homepage=20video=20play/pa?= =?UTF-8?q?use=20bug=20and=20refactor=20code=20(#149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 Fix homepage video play/pause bug and refactor code --------- Co-authored-by: Wun Chiou --- public/css/app.css | 26 ++---- public/js/app.js | 140 +++++++++++-------------------- public/mix-manifest.json | 4 +- resources/assets/js/app.js | 129 ++++++++++------------------ resources/assets/sass/_home.scss | 25 ++---- resources/views/home.blade.php | 8 +- 6 files changed, 115 insertions(+), 217 deletions(-) diff --git a/public/css/app.css b/public/css/app.css index e5d02272..48bc5819 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -10309,7 +10309,7 @@ footer > ul > li { z-index: -100; } -.control-bt { +button.video-control { position: absolute; height: 45px; width: 45px; @@ -10322,32 +10322,20 @@ footer > ul > li { border-radius: 50%; cursor: pointer; transition: opacity 0.3s ease-in-out; + display: flex; + justify-content: center; + align-items: center; } -.control-bt span { +button.video-control .video-control-icon { width: 24px; height: 24px; fill: #fff; - margin-top: -0.1rem; } -.control-bt span:first-of-type { +button.video-control .fa-play { margin-left: 0.1rem; } -@media (max-width: 1199.98px) and (hover: none) { - .control-bt span { - margin-left: -11px; - } - .control-bt span:first-of-type { - margin-left: -9px; - } -} -.control-bt.pause span:first-of-type { - display: none; -} -.control-bt.play span:last-of-type { - display: none; -} @media (max-width: 991.98px) { - .control-bt { + button.video-control { display: none; } } diff --git a/public/js/app.js b/public/js/app.js index f7966366..8b9b4d0a 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -560,6 +560,49 @@ var profiles = function ($, undefined) { } }); }; + + /** + * Register playPauseVideo function for video control button(s) + * + * @return {void} + */ + var registerVideoControls = function registerVideoControls() { + var play_pause_buttons = document.querySelectorAll('button.video-control.play-pause'); + var prefers_reduced_motion = window.matchMedia("(prefers-reduced-motion: reduce)"); + play_pause_buttons.forEach(function (bt) { + return bt.addEventListener('click', function (evt) { + var button = evt.currentTarget; + var video = document.getElementById(button === null || button === void 0 ? void 0 : button.getAttribute('aria-controls')); + if (video instanceof HTMLVideoElement && button instanceof HTMLButtonElement) { + toggleVideoPlay(video, button); + } + }); + }); + if (prefers_reduced_motion.matches) { + play_pause_buttons.forEach(function (bt) { + return bt.click(); + }); + } + }; + + /** + * Play/pause video and controls the video and button attributes + * @param {HTMLVideoElement} vid + * @param {HTMLButtonElement} btn + * @return {void} + */ + var toggleVideoPlay = function toggleVideoPlay(vid, btn) { + var icon = btn.querySelector('[data-fa-i2svg],.fas'); + if (vid.paused) { + vid.play(); + btn.ariaPressed = "true"; + icon.className = "fas fa-pause"; + } else { + vid.pause(); + btn.ariaPressed = "false"; + icon.className = "fas fa-play"; + } + }; return { add_row: add_row, clear_row: clear_row, @@ -573,7 +616,8 @@ var profiles = function ($, undefined) { toast: toast, toggle_class: toggle_class, toggle_show: toggle_show, - wait_when_submitting: wait_when_submitting + wait_when_submitting: wait_when_submitting, + registerVideoControls: registerVideoControls }; }(jQuery); window.profiles = profiles; @@ -650,6 +694,9 @@ $(function () { return typeof content === 'string' && $(content).length ? $(content).html() : ''; } }); + if (document.querySelectorAll('.video-cover video').length > 0 && document.querySelectorAll('.video-cover .video-control').length > 0) { + profiles.registerVideoControls(); + } }); // Livewire global hooks @@ -673,97 +720,6 @@ if ((typeof Livewire === "undefined" ? "undefined" : _typeof(Livewire)) === 'obj }); } -//Reduced motion enabled -var isReduced = window.matchMedia("(prefers-reduced-motion: reduce)") === true || window.matchMedia("(prefers-reduced-motion: reduce)").matches === true; - -//Play/Pause Toggle - on any click inside the cover, if not a link, initiate the play/pause toggle -var covers = document.querySelectorAll('.video-cover'); -var clickCount; -if (!isReduced) { - clickCount = 0; -} else { - clickCount = 1; - var coversWithVideo = document.querySelectorAll('.video-cover'); - coversWithVideo.forEach(function (el) { - var button = el.parentNode.children.item(4); - if (button.classList.contains('pause')) { - button.classList.remove('pause'); - button.classList.add('play'); - button.setAttribute('aria-label', 'Video Paused.'); - el.pause(); - } - }); -} -covers.forEach(function (cover) { - cover.addEventListener('click', playpause); -}); - -//play pause toggle for video covers -function playpause(el) { - //Check to see if the target element is the cover block, - var target = typeof el.target !== 'undefined' ? el.target : el; - if (target.classList.contains('video-cover')) { - // If it is, pull the video and the button elements from the children and put them through the toggle function - var tKids = Array.from(target.children); - var video = tKids.filter(function (vid) { - return vid.localName === 'video'; - }); - var button = tKids.filter(function (btn) { - return btn.localName === 'button'; - }); - if (video.length > 0) { - toggle(video, button); - } - } else { - //If it isn't, loop of the elements parent, - var parent = target.parentNode; - do { - //Check if the element's parent is the wp-cover block, - if (parent.classList.contains('video-cover')) { - // if it is, pull the video and the button elements from the children and put them through the toggle function - var pKids = Array.from(parent.children); - var _video = pKids.filter(function (vid) { - return vid.localName === 'video'; - }); - var _button = pKids.filter(function (btn) { - return btn.localName === 'button'; - }); - if (_video.length > 0) { - toggle(_video, _button); - } - return true; - } - // if it isn't go up another level and rerun the check - parent = parent.parentNode; - } while (parent); - return false; - } - - //controls the video and button attributes - function toggle(vid, btn) { - if (clickCount == 0) { - //Video initial - btn[0].setAttribute('aria-label', 'Video Paused.'); - btn[0].classList.remove('pause'); - btn[0].classList.add('play'); - vid[0].pause(); - } else if (clickCount % 2 == 0) { - //From initial to pause - btn[0].setAttribute('aria-label', 'Video Paused.'); - btn[0].classList.remove('pause'); - btn[0].classList.add('play'); - vid[0].pause(); - } else { - //From pause to play - btn[0].setAttribute('aria-label', 'Video Playing.'); - btn[0].classList.remove('play'); - btn[0].classList.add('pause'); - vid[0].play(); - } - clickCount++; - } -} - /***/ }), /***/ "./resources/assets/js/bootstrap.js": diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 82acfc21..de5f1463 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,6 +1,6 @@ { - "/js/app.js": "/js/app.js?id=9dc35e8177d13dc48b6a5c2515bf88b0", + "/js/app.js": "/js/app.js?id=24be537863fbbe2259218dfb56ecef72", "/js/manifest.js": "/js/manifest.js?id=dc9ead3d7857b522d7de22d75063453c", - "/css/app.css": "/css/app.css?id=54db96a1c960aab96ee5b38d5cbbf2f1", + "/css/app.css": "/css/app.css?id=bff46e69abe7a97b008296b99e4abadd", "/js/vendor.js": "/js/vendor.js?id=4d3313683b3a2faf8ca0278ce47f3880" } diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index 3305d8c2..c187b44f 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -499,6 +499,47 @@ var profiles = (function ($, undefined) { }); } + /** + * Register playPauseVideo function for video control button(s) + * + * @return {void} + */ + const registerVideoControls = function () { + const play_pause_buttons = document.querySelectorAll('button.video-control.play-pause'); + const prefers_reduced_motion = window.matchMedia(`(prefers-reduced-motion: reduce)`); + + play_pause_buttons.forEach(bt => bt.addEventListener('click', evt => { + const button = evt.currentTarget; + const video = document.getElementById(button?.getAttribute('aria-controls')); + if (video instanceof HTMLVideoElement && button instanceof HTMLButtonElement) { + toggleVideoPlay(video, button); + } + })); + + if (prefers_reduced_motion.matches) { + play_pause_buttons.forEach((bt) => bt.click()); + } + } + + /** + * Play/pause video and controls the video and button attributes + * @param {HTMLVideoElement} vid + * @param {HTMLButtonElement} btn + * @return {void} + */ + const toggleVideoPlay = function (vid, btn) { + const icon = btn.querySelector('[data-fa-i2svg],.fas'); + if (vid.paused) { + vid.play(); + btn.ariaPressed = "true"; + icon.className = "fas fa-pause"; + } else { + vid.pause(); + btn.ariaPressed = "false"; + icon.className = "fas fa-play"; + } + } + return { add_row: add_row, clear_row: clear_row, @@ -513,6 +554,7 @@ var profiles = (function ($, undefined) { toggle_class: toggle_class, toggle_show: toggle_show, wait_when_submitting : wait_when_submitting, + registerVideoControls: registerVideoControls, }; })(jQuery); @@ -593,6 +635,10 @@ $(function() { } }); + if (document.querySelectorAll('.video-cover video').length > 0 && document.querySelectorAll('.video-cover .video-control').length > 0) { + profiles.registerVideoControls(); + } + }); // Livewire global hooks @@ -612,87 +658,4 @@ if (typeof Livewire === 'object') { }); } -//Reduced motion enabled -const isReduced = window.matchMedia(`(prefers-reduced-motion: reduce)`) === true || window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true; - -//Play/Pause Toggle - on any click inside the cover, if not a link, initiate the play/pause toggle -const covers = document.querySelectorAll('.video-cover'); -let clickCount; -if (!isReduced) { - clickCount = 0; -} else { - clickCount = 1; - const coversWithVideo = document.querySelectorAll('.video-cover'); - coversWithVideo.forEach(el => { - const button = el.parentNode.children.item(4); - if (button.classList.contains('pause')) { - button.classList.remove('pause'); - button.classList.add('play'); - button.setAttribute('aria-label', 'Video Paused.'); - el.pause(); - } - }); -} - covers.forEach(cover => { - cover.addEventListener('click', playpause); -}); - -//play pause toggle for video covers -function playpause(el) { - //Check to see if the target element is the cover block, - const target = (typeof el.target !== 'undefined') ? el.target : el; - if (target.classList.contains('video-cover')) { - // If it is, pull the video and the button elements from the children and put them through the toggle function - const tKids = Array.from(target.children); - const video = tKids.filter(vid => vid.localName === 'video'); - const button = tKids.filter(btn => btn.localName === 'button'); - if (video.length > 0) { - toggle(video, button); - } - } else { - //If it isn't, loop of the elements parent, - let parent = target.parentNode; - do { - //Check if the element's parent is the wp-cover block, - if (parent.classList.contains('video-cover')) { - // if it is, pull the video and the button elements from the children and put them through the toggle function - const pKids = Array.from(parent.children); - const video = pKids.filter(vid => vid.localName === 'video'); - const button = pKids.filter(btn => btn.localName === 'button'); - if (video.length > 0) { - toggle(video, button); - } - return true; - } - // if it isn't go up another level and rerun the check - parent = parent.parentNode; - } while (parent); - return false; - } - - //controls the video and button attributes - function toggle(vid, btn) { - - if (clickCount == 0) { - //Video initial - btn[0].setAttribute('aria-label', 'Video Paused.'); - btn[0].classList.remove('pause'); - btn[0].classList.add('play'); - vid[0].pause(); - } else if (clickCount % 2 == 0) { - //From initial to pause - btn[0].setAttribute('aria-label', 'Video Paused.'); - btn[0].classList.remove('pause'); - btn[0].classList.add('play'); - vid[0].pause(); - } else { - //From pause to play - btn[0].setAttribute('aria-label', 'Video Playing.'); - btn[0].classList.remove('play'); - btn[0].classList.add('pause'); - vid[0].play(); - } - clickCount++; - } -} \ No newline at end of file diff --git a/resources/assets/sass/_home.scss b/resources/assets/sass/_home.scss index 8d952547..a815b0e0 100644 --- a/resources/assets/sass/_home.scss +++ b/resources/assets/sass/_home.scss @@ -97,7 +97,7 @@ $home-top-height: 60vh; z-index: -100; } -.control-bt { +button.video-control { $video-btn-size: 45px; $video-btn-spacing: map.get($spacers, 3); position: absolute; @@ -112,29 +112,20 @@ $home-top-height: 60vh; border-radius: 50%; cursor: pointer; transition: opacity 0.3s ease-in-out; + display: flex; + justify-content: center; + align-items: center; - span { + .video-control-icon { width: 24px; height: 24px; fill: $white; - margin-top: -0.1rem; - &:first-of-type { - margin-left: 0.1rem; - } - @media (max-width: 1199.98px) and (hover: none) { - margin-left: -11px; - &:first-of-type { - margin-left: -9px; - } - } } - &.pause span:first-of-type { - display: none - } - &.play span:last-of-type { - display: none + .fa-play { + margin-left: 0.1rem; } + @media (max-width: 991.98px) { display: none; } diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 7ef65f14..84c963f1 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -8,10 +8,10 @@ @if(File::exists(public_path('/storage/video/home.jpg')) && File::exists(public_path('/storage/video/home.mp4')))
- +

Scenes of campus buildings

Scenes of campus buildings