From 6b3e1f4e198543928a307e801940073b6327b151 Mon Sep 17 00:00:00 2001 From: Justin Georgi Date: Mon, 28 Oct 2024 13:51:46 -0700 Subject: [PATCH] Add hotpot navigation and slideshow Signed-off-by: Justin Georgi --- includes/GlModelTransformOutput.php | 36 ++++++++++++++++++++++++- modules/glmv.css | 41 +++++++++++++++++++++++++++-- modules/glmv.js | 9 ++++++- resources/goto_hs.svg | 1 + resources/hs_slideshow.svg | 1 + resources/menu_arrow.svg | 1 + 6 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 resources/goto_hs.svg create mode 100644 resources/hs_slideshow.svg create mode 100644 resources/menu_arrow.svg diff --git a/includes/GlModelTransformOutput.php b/includes/GlModelTransformOutput.php index 2801d12..0c18528 100644 --- a/includes/GlModelTransformOutput.php +++ b/includes/GlModelTransformOutput.php @@ -2,6 +2,8 @@ namespace MediaWiki\Extension\GlModelViewer; use MediaTransformOutput; +use ConfigFactory; +use OutputPage; use Html; class GlModelTransformOutput extends MediaTransformOutput { @@ -157,8 +159,40 @@ class GlModelTransformOutput extends MediaTransformOutput { $attrMenu = array( 'class' => 'glmv-menu' ); + $mainConfig = ConfigFactory::getDefaultInstance()->makeConfig( 'main' ); + $menuUrl = $mainConfig->get( 'ExtensionAssetsPath' ) . '/GlModelViewer/resources/menu_arrow.svg'; + $attrMenuImg = array ( + 'class' => 'glmv-menu-image', + 'src' => $menuUrl + ); + $menuImg = Html::rawElement('img', $attrMenuImg, ''); - return Html::rawElement('div', $attrMenu, '>'); + $gotoUrl = $mainConfig->get( 'ExtensionAssetsPath' ) . '/GlModelViewer/resources/goto_hs.svg'; + $attrMenuButtonPrev = array ( + 'class' => 'glmv-menu-button prev-hs', + 'onclick' => 'prevAnnotation(event.target.closest(".glmv-container").querySelector("model-viewer"))', + 'onmousedown' => 'event.stopPropagation()', + 'ontouchstart' => 'event.stopPropagation()' + ); + $attrMenuButtonNext = array ( + 'class' => 'glmv-menu-button next-hs', + 'onclick' => 'nextAnnotation(event.target.closest(".glmv-container").querySelector("model-viewer"))', + 'onmousedown' => 'event.stopPropagation()', + 'ontouchstart' => 'event.stopPropagation()' + ); + + $slideUrl = $mainConfig->get( 'ExtensionAssetsPath' ) . '/GlModelViewer/resources/hs_slideshow.svg'; + $attrMenuButtonSlides = array ( + 'class' => 'glmv-menu-button', + 'onclick' => 'event.target.toggleAttribute("toggled"); slideshowAnnotations(event.target.closest(".glmv-container").querySelector("model-viewer"))', + 'onmousedown' => 'event.stopPropagation()', + 'ontouchstart' => 'event.stopPropagation()' + ); + $buttonPrev = Html::rawElement('div', $attrMenuButtonPrev, ''); + $buttonNext = Html::rawElement('div', $attrMenuButtonNext, ''); + $buttonSlides = Html::rawElement('div', $attrMenuButtonSlides, ''); + + return Html::rawElement('div', $attrMenu, $menuImg . $buttonPrev . $buttonSlides . $buttonNext); } /** diff --git a/modules/glmv.css b/modules/glmv.css index b9ad33b..906fc69 100644 --- a/modules/glmv.css +++ b/modules/glmv.css @@ -74,14 +74,51 @@ overflow: hidden; height: 32px; width: 32px; - text-align: center; font-weight: bold; border-radius: 6px; transition: width .75s; position: absolute; bottom: 50px; left: 0; + display: flex; + flex-direction: row; + justify-content: flex-start; + &:hover { - width: 100% + width: auto; + + & .glmv-menu-image { + transform: rotate(180deg); + } } + } + + .glmv-menu-image { + width: 32px; + height: 32px; + position: relative; + transition: transform .75s; + flex: 0 0 32px; + } + + .glmv-menu-button { + width: 28px; + height: 28px; + position: relative; + margin: 2px; + flex: 0 0 28px; + + & img { + width: 100%; + height: 100%; + pointer-events: none; + } + + &[toggled] { + background: #00000033; + } + } + + .prev-hs img { + transform: scaleX(-1); } \ No newline at end of file diff --git a/modules/glmv.js b/modules/glmv.js index 45dc0c9..2b75f1b 100644 --- a/modules/glmv.js +++ b/modules/glmv.js @@ -1,3 +1,5 @@ +let slideShowInterval = null + /** * Sets listener and attributes on model-viewer to * allow for click registering of a new hotspot @@ -151,5 +153,10 @@ prevAnnotation = function(mView) { * @return {intervalID} ID of the created interval timer */ slideshowAnnotations = function(mView, slideDuration = 5000) { - return setInterval(nextAnnotation, slideDuration, mView) + if (slideShowInterval) { + clearInterval(slideShowInterval) + } else { + nextAnnotation(mView) + slideShowInterval = setInterval(nextAnnotation, slideDuration, mView) + } } diff --git a/resources/goto_hs.svg b/resources/goto_hs.svg new file mode 100644 index 0000000..651656f --- /dev/null +++ b/resources/goto_hs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/hs_slideshow.svg b/resources/hs_slideshow.svg new file mode 100644 index 0000000..6d87cfd --- /dev/null +++ b/resources/hs_slideshow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/menu_arrow.svg b/resources/menu_arrow.svg new file mode 100644 index 0000000..8b648c5 --- /dev/null +++ b/resources/menu_arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file