@olefjaerestad/wc-interactive-slideshow v0.0.4
@olefjaerestad/wc-interactive-slideshow
Image slideshow with play/pause/reverse/stops/goto/reset functionality.
Motivation
Consider this component a video player playing image files in order, complementing the native <video>
element. The <video>
element is good at many things. It's not good at the following:
- Playing backwards.
- Programmatic control over which frame to display (only timestamp).
- Automatically stop playing at certain frames (requires custom code).
- It requires a video file. Not everyone has a video file.
This component aims to solve these issues by providing a simple to use API for configuration and playing.
Use cases
- Product 360° view.
- Video stopping at certain frames to highlight important things.
- The component has minimal styling on its own, so it should be easy to overwrite for you to build whatever you want.
Usage
Define
You need to define the component yourself. This way you won't run into naming conflicts with other components. It also lets you extend the component class.
const { WcInteractiveSlideshow } = require('@olefjaerestad/wc-interactive-slideshow');
if (!customElements.get('wc-interactive-slideshow')) {
customElements.define('wc-interactive-slideshow', WcInteractiveSlideshow);
}
Basic use
<wc-interactive-slideshow
count="30"
src="http://url.to/images/"
></wc-interactive-slideshow>
Attributes
count
: How many images the slideshow should show. Required.format
: Which format your images are. Optional. Default:jpeg
.fps
: How many images should be displayed pr. second when usingplay()
. Optional. Default:10
.poster
: Full URL to image to display while the images insrc
are being loaded. Does not depend on theformat
attribute. Optional. Default:null
.src
: Full URL to where your images are stored. The element expects a folder with images named 1.jpeg, 2.jpeg, 3.jpeg, etc (you can change format with theformat
attribute). Required.stops
: When playing the slideshow (using theplay()
orreverse()
methods), the slideshow can automatically stop at certain images. You'll have toplay()
orreverse()
in order to start playing again. Example:stops="5,15,24"
would stop at 5.jpeg, 15.jpeg and 24.jpeg. Optional. Default:null
.title
: The title will be put on the nested image element (added by the component) and deleted from the component itself. For improved accessibility.
Note: You can of course add all the standard attributes, such as id, class and data-* attributes as well.
Note 2: Each of these attributes have setter methods, so you can do:
const myComponent = document.querySelector('wc-interactive-slideshow');
myComponent.count = 31;
myComponent.format = 'png';
myComponent.fps = 5;
myComponent.poster = 'http://url.to/poster.jpeg';
myComponent.src = 'http://url.to/new/images/';
myComponent.stops = '7,13,17,25';
Methods
goto(to: number)
: Go to specific image.goto(24)
would go to image 24.pause()
: Pause the slideshow.play(to?: number)
: Play the slideshow from the current image. Passto
to play until a given image is reached.to = 3
will play until 3.jpeg is reached. If there are anystops
between the current index andto
, the slideshow will stop beforeto
is reached.reset()
: Go to first image and pause the player.reverse(to?: number)
: Play the slideshow backwards from the current image. Passto
to reverse until a given image is reached.to = 3
will reverse until 3.jpeg is reached. If there are anystops
between the current index andto
, the slideshow will stop beforeto
is reached.
Properties
batch: string[] = []
: The currently loaded image URLs.count: number|null
: The value passed to the count attribute.currentIndex: number
: The index at which the slideshow is currently at. 0-based.error: Error
: The error if an operation in the component has failed.format: 'jpeg'|string
: The value passed to the format attribute.fps: number|null
: The value passed to the fps attribute.img: HTMLImageElement
: The nested<img>
element used to display the images.poster: string|null
: The value passed to the poster attribute.rafId: number
: The requestAnimationFrameId used for animating the slideshow.src: string|null
: The value passed to the src attribute.stops: string|null
: The value passed to the stops attribute.stopsArr: number[]
: The value passed to the stops attribute, converted to an array of numbers by splitting on,
.
Note: For regular use, you probably won't need to use any of these. These are just available for your convenience if you want to do some custom stuff.
Events
The slideshow will emit events when certain, well, events happen. You can listen for these and run custom code when they happen. Most of the events will contain some extra information (in the form of an object) in the .detail
property of the event object.
Event name | Description | e.detail |
---|---|---|
slideshow.change | Image changed | from: numberto: number |
slideshow.error | An error happened | error: Error |
slideshow.load | Images finished loading | urls: string[] |
slideshow.pause | Playing pauses | index: number |
slideshow.play | Playing starts | index: number |
slideshow.reset | Slideshow resets | |
slideshow.reverse | Reverse playing starts | index: number |
const myComponent = document.querySelector('wc-interactive-slideshow');
myComponent.addEventListener('slideshow.change', e => {
console.log(`Changed from image ${e.detail.from} to ${e.detail.to}`);
});
Server side rendering
Instead of passing a poster attribute, just add an <img>
as a child element. Once JS has loaded, the element will hydrate and start working as expected.
<wc-interactive-slideshow
src="http://url.to/images/"
count="34"
fps="5"
>
<img src="http://url.to/poster.jpeg" title="An image slideshow of some very cool stuff.">
</wc-interactive-slideshow>
Browser support
Browser | Supported? |
---|---|
Chrome >= 49 | ✅ |
Edge >= 18 | ✅ |
Firefox >= 45 | ✅ |
Internet Explorer | ❌ |
Opera >= 36 | ✅ |
Safari >= 10 | ✅ |
Chrome for Android > 49 | ✅ |
Firefox for Android > 45 | ✅ |
Opera for Android > 36 | ✅ |
Safari for iOS > 10 | ✅ |
Node.js | ❌ |
Browser support is mainly affected by
Troubleshooting
My images look stretched
Your images might be malformed in some way. Try saving them again and see if that fixes things. See https://prodevsblog.com/questions/209590/css-object-fit-cover-is-stretching-a-particular-image-in-chrome-on-mac/