smartphoto
v2.1.8
Published
smartphoto
Keywords
Readme
SmartPhoto
The most easy to use responsive image viewer especially for mobile devices
See https://appleple.github.io/SmartPhoto/ for complete docs and demos If you are Japasese, See here https://www.appleple.com/blog/javascript/smartphoto-js.html instead.
Feature
- Intuitive gestures such as pinch-in/pinch-out/drag/swipe
- Use Accelerometer to move images
- Accessible from keyboards and screen-readers
- Show pictures via URL hash
- Can make photo groups
Installation
via npm
npm install smartphoto --saveor yarn
yarn add smartphotoUsage
require
const SmartPhoto = require('smartphoto');smartphoto.js
document.addEventListener('DOMContentLoaded',function(){
new SmartPhoto(".js-smartphoto");
});jquery-smartphoto.js
$(function(){
$(".js-smartphoto").SmartPhoto();
});Basic Standalone Usage
<a href="./assets/large-bear.jpg" class="js-smartphoto" data-caption="bear" data-id="bear" data-group="0">
<img src="./assets/bear.jpg" width="360"/>
</a>
<a href="./assets/large-camel.jpg" class="js-smartphoto" data-caption="camel" data-id="camel" data-group="0">
<img src="./assets/camel.jpg" width="360"/>
</a>
<a href="./assets/large-rhinoceros.jpg" class="js-smartphoto" data-caption="rhinoceros" data-id="sai" data-group="0">
<img src="./assets/rhinoceros.jpg" width="360"/>
</a>
<link rel="stylesheet" href="./css/smartphoto.min.css">
<script src="./js/smartphoto.js"></script>
<script>
document.addEventListener('DOMContentLoaded',function(){
new SmartPhoto(".js-smartphoto");
});
</script>When SmartPhoto is constructed with a CSS selector string (as above), clicks are handled via a single delegated listener, so elements added to the page after construction (e.g. by Ajax/infinite scroll) are picked up automatically just by clicking them — no need to call addItem()/addNewItem() manually. Right before a photo is opened, SmartPhoto also reconciles that photo's group against the current DOM: newly appended matching elements are added, and elements that have since been removed from the DOM are dropped from the group (remaining indices are recalculated). This auto-detection only applies to the selector-string form; when a NodeList/Element[] is passed (or in data source mode below), add/remove items explicitly via addItem()/addNewItem().
A few things to keep in mind:
- Reconciliation only happens right before a photo is opened (via a click,
show(), or hash restoration) — not continuously. If an element disappears from the DOM while the viewer is already open and younext()/prev()through the same session, that removal isn't reflected until the viewer is opened again. - It does not support replacing an entire container's
innerHTML(which recreates existing elements too, as brand-new DOM nodes) — that produces duplicate items, since the old and new elements aren't recognized as the same one. Only appending/removing individual elements is supported; if you regenerate the whole container, calldestroy()and construct a new instance instead. - Changing
data-groupon an element that has already been opened/registered has no effect (the group is fixed at first registration). Changing it before the element is first interacted with is picked up correctly. - If multiple instances are built with overlapping selectors, avoid relying on distinguishing exactly which instance handles a click for elements that could match either.
Programmatic usage (data source mode)
Instead of scanning <a> elements in the page, you can pass an array of slide objects directly (inspired by yet-another-react-lightbox). This is useful when your images come from an API or a JS-rendered list.
const photo = new SmartPhoto([
{ src: "/img/bear-large.jpg", thumb: "/img/bear.jpg", caption: "bear", id: "bear" },
{ src: "/img/camel-large.jpg", thumb: "/img/camel.jpg", caption: "camel", id: "camel", width: 1200, height: 800 },
]);
photo.show(0); // open by index
photo.show("camel"); // or by id
photo.next();
photo.prev();
photo.hide();
photo.on("change", () => { /* ... */ }); // same event contract as HTML modeSlide fields:
show(indexOrId, options) also accepts options.group (which group to open) and options.trigger (the element to animate from / return focus to). Both HTML mode and data source mode share the exact same public API, options, and events.
Option
Hide parts
document.addEventListener('DOMContentLoaded',function(){
new SmartPhoto(".js-smartphoto",{
arrows: false,
nav: false
});
});Fit/Fill Option
You can choose if you want to scale images to fit/fill
document.addEventListener('DOMContentLoaded',function(){
new SmartPhoto(".js-smartphoto",{
resizeStyle: 'fit'
});
});Event
// when the modal opened
photo.on('open',function(){
console.log('open');
});
// when the modal closed
photo.on('close',function(){
console.log('close');
});
// when all images are loaded
photo.on('loadall',function(){
console.log('loadall');
});
// when photo is changed
photo.on('change',function(){
console.log('change');
});
// when swipe started
photo.on('swipestart',function(){
console.log('swipestart');
});
// when swipe ended
photo.on('swipeend',function(){
console.log('swipeend');
});
// when zoomed in
photo.on('zoomin',function(){
console.log('zoomin');
});
// when zoomed out
photo.on('zoomout',function(){
console.log('zoomout');
});Methods
CSS Custom Properties
Set these on .smartphoto (or :root) to override the defaults, no rebuild required:
.smartphoto {
--smartphoto-animation-speed: 450ms;
--smartphoto-animation-function: ease-in-out;
--smartphoto-backdrop-color: rgba(0, 0, 0, 0.9);
--smartphoto-header-color: rgba(0, 0, 0, 0.4);
}
@media (max-width: 480px) {
.smartphoto {
--smartphoto-arrow-top: 85%;
}
}The bottom thumbnail nav (.smartphoto-nav) also reserves env(safe-area-inset-bottom) automatically so it isn't hidden behind the iOS home indicator/toolbar.
Download
Github
https://github.com/appleple/SmartPhoto
License
Code and documentation copyright 2017 by appleple, Inc. Code released under the MIT License.
