add expand button, change image height to max-height
authorAndrew Lorimer <andrew@lorimer.id.au>
Sat, 20 Aug 2022 09:54:34 +0000 (19:54 +1000)
committerAndrew Lorimer <andrew@lorimer.id.au>
Sat, 20 Aug 2022 09:54:34 +0000 (19:54 +1000)
README.md
slideshow.css
slideshow.html
slideshow.js
index 383134a294cefdb68d67d3b24313eeada93aa449..0f942fc203f69775e32d7314fba7c303f4fe5775 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,21 +1,29 @@
 # Simple JavaScript Slideshow
 
 # Simple JavaScript Slideshow
 
-This is a very basic slideshow made in JavaScript - no jQuery or other libraries.
+This is a very basic slideshow made in JavaScript - no jQuery or other
+libraries.
 
 
-See slideshow.html for an example. To use, insert the HTML structure and link slideshow.css and slideshow.js.
+See slideshow.html for an example. To use, insert the HTML structure and link
+slideshow.css and slideshow.js.
 
 ## Features
 
 
 ## Features
 
-- Auto advance (default 3 seconds, but you can change `INTERVAL` in slideshow.js or in the HTML)
+- Auto advance (default 3 seconds, but you can change `INTERVAL` in
+  slideshow.js or in the HTML)
 - Pause on hover and manual pause
 - Scroll through slides with buttons or dot indicator at bottom
 - Captions
 - Pause on hover and manual pause
 - Scroll through slides with buttons or dot indicator at bottom
 - Captions
-- Semantic HTML (each slide is a `<figure>` consisting of an `<img>` and `<figcaption>`)
+- Semantic HTML (each slide is a `<figure>` consisting of an `<img>` and
+  `<figcaption>`)
 - Sensible behaviour when JS is disabled (static first slide)
 - Sensible behaviour when JS is disabled (static first slide)
-- Works with different sizes/aspect ratios and different length captions (set width or max-width of outer div, then slide heights are driven by the the height of the first slide at full width)
+- Works with different sizes/aspect ratios and different length captions (set
+  width or max-width of outer div, then slide heights are driven by the the
+  height of the first slide at full width)
 - Works well at all screen sizes and can be styled with basic CSS
 
 ## Todo
 
 - Initialise slideshows with JS object
 - Support for multiple slideshows per page
 - Works well at all screen sizes and can be styled with basic CSS
 
 ## Todo
 
 - Initialise slideshows with JS object
 - Support for multiple slideshows per page
+- Fix issue where images appear small when advancing slideshow manually without
+  first automatically advancing
index 3cd4ce095beee09dded899b55c5d0db2da612c39..be5c4b3ac045ec2707265281ad4d9311cd3e7c2a 100644 (file)
@@ -57,7 +57,7 @@ figure.slide img {
  * Buttons
  */
 
  * Buttons
  */
 
-#prev, #next, #state {
+#prev, #next, #state, #expand {
   cursor: pointer;
   font-weight: bold;
   font-size: 1.5em;
   cursor: pointer;
   font-weight: bold;
   font-size: 1.5em;
@@ -74,17 +74,29 @@ figure.slide img {
   padding: 16px;
 }
 
   padding: 16px;
 }
 
-#state {
+#state, #expand {
   width: 1.5em;
   height: 1.5em;
   width: 1.5em;
   height: 1.5em;
+  line-height: 1.5em;
   text-align: center;
   font-family: monospace;
   top: 15px;
   text-align: center;
   font-family: monospace;
   top: 15px;
-  right: 15px;
   padding: 4px;
   border-radius: 3px;
 }
 
   padding: 4px;
   border-radius: 3px;
 }
 
+#state {
+  right: 15px;
+}
+
+#expand {
+  right: calc(15px + 15px + 1.5em);
+}
+
+#expand svg path {
+  fill: #fff;
+}
+
 #prev {
   left: 0;
   border-radius: 0 3px 3px 0;
 #prev {
   left: 0;
   border-radius: 0 3px 3px 0;
@@ -98,13 +110,14 @@ figure.slide img {
 
 div.slideshow:hover #prev,
 div.slideshow:hover #next,
 
 div.slideshow:hover #prev,
 div.slideshow:hover #next,
+div.slideshow:hover #expand,
 div.slideshow:hover #state {
   /* Show buttons on slideshow hover */
   opacity: 100;
   background-color: rgba(0,0,0,0.3);
 }
 
 div.slideshow:hover #state {
   /* Show buttons on slideshow hover */
   opacity: 100;
   background-color: rgba(0,0,0,0.3);
 }
 
-#prev:hover, #next:hover, #state:hover {
+#prev:hover, #next:hover, #expand:hover, #state:hover {
   /* Button hover */
   background-color: rgba(0,0,0,0.8) !important;
 }
   /* Button hover */
   background-color: rgba(0,0,0,0.8) !important;
 }
index 88964561d2f7f110e77e7f43cc82d715706c5188..b4099eb078a0163b5cd966c9ee30ff2a47f8cd55 100644 (file)
 
       </div>
 
 
       </div>
 
-      <a id="prev">&#10094;</a>
-      <a id="next">&#10095;</a>
-      <a id="state">&#x23f8;&#xFE0E;</a>
+      <a id="prev" title="Previous image">&#10094;</a>
+      <a id="next" title="Next image">&#10095;</a>
+      <a id="expand" title="View in new tab">
+        <svg version="1.1" viewBox="0 0 36 36">
+          <path d="m 10,16 2,0 0,-4 4,0 0,-2 L 10,10 l 0,6 0,0 z"></path>
+          <path d="m 20,10 0,2 4,0 0,4 2,0 L 26,10 l -6,0 0,0 z"></path>
+          <path d="m 24,24 -4,0 0,2 L 26,26 l 0,-6 -2,0 0,4 0,0 z"></path>
+          <path d="M 12,20 10,20 10,26 l 6,0 0,-2 -4,0 0,-4 0,0 z"></path>
+        </svg>
+      </a>
+      <a id="state" title="Pause">&#x23f8;&#xFE0E;</a>
 
       <div id="controls">
         <span class="dot"></span>
 
       <div id="controls">
         <span class="dot"></span>
index 80614c9a2562df2ff0194c336883da268f6220d2..cccf2ee2cb900323fa5da46630d6fe1bc132de61 100644 (file)
@@ -13,6 +13,7 @@ let container = document.getElementsByClassName("slides")[0];
 let slides = document.getElementsByClassName("slide");
 let dots = document.getElementsByClassName("dot");
 let stateBtn = document.getElementById("state");
 let slides = document.getElementsByClassName("slide");
 let dots = document.getElementsByClassName("dot");
 let stateBtn = document.getElementById("state");
+let expandBtn = document.getElementById("expand");
 
 // Global state
 let maxIndex = slides.length - 1;
 
 // Global state
 let maxIndex = slides.length - 1;
@@ -29,6 +30,7 @@ document.getElementById("state").addEventListener("click", changeState);
 if (dots.length - 1 != maxIndex) {
   console.log("Number of control dots does not match number of slides");
 }
 if (dots.length - 1 != maxIndex) {
   console.log("Number of control dots does not match number of slides");
 }
+expandBtn.addEventListener("click", expand);
 for (i = 0; i <= dots.length - 1; i++) {
   dots[i].addEventListener("click", goToSlide);
   dots[i].slide = i;
 for (i = 0; i <= dots.length - 1; i++) {
   dots[i].addEventListener("click", goToSlide);
   dots[i].slide = i;
@@ -72,9 +74,9 @@ function setHeights() {
   for (i = 1; i <= maxIndex; i++) {
     var captionHeight = slides[i].getElementsByTagName("figcaption")[0].offsetHeight;
     // Set figure height
   for (i = 1; i <= maxIndex; i++) {
     var captionHeight = slides[i].getElementsByTagName("figcaption")[0].offsetHeight;
     // Set figure height
-    slides[i].style.height = slides[0].offsetHeight.toString() + "px";
+    slides[i].style.maxHeight = slides[0].offsetHeight.toString() + "px";
     // Set image height
     // Set image height
-    slides[i].getElementsByTagName("img")[0].style.height = (firstSlideHeight - captionHeight).toString() + "px";
+    slides[i].getElementsByTagName("img")[0].style.maxHeight = (firstSlideHeight - captionHeight).toString() + "px";
   }
 }
 
   }
 }
 
@@ -121,12 +123,19 @@ function changeState() {
     // Play immediately despite mouseover
     stateBtn.innerHTML = STATE_PAUSE;
     timeout = setTimeout(playSlideshow, INTERVAL);
     // Play immediately despite mouseover
     stateBtn.innerHTML = STATE_PAUSE;
     timeout = setTimeout(playSlideshow, INTERVAL);
+    stateBtn.title = "Pause";
   }
   else {
     // Pause until user presses play again
     clearTimeout(timeout); // make sure timer is stopped
     timeout = null;
     stateBtn.innerHTML = STATE_PLAY;
   }
   else {
     // Pause until user presses play again
     clearTimeout(timeout); // make sure timer is stopped
     timeout = null;
     stateBtn.innerHTML = STATE_PLAY;
+    stateBtn.title = "Play";
   }
   paused = !paused;
 }
   }
   paused = !paused;
 }
+
+function expand() {
+  // Open the image in a new tab
+  window.open(slides[currentSlide].getElementsByTagName('img')[0].src, 'blank');
+}