Skip to content

Repository files navigation

SmartPhoto

npm version npm download GitHub license

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 --save

or yarn

yarn add smartphoto

Usage

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>

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 mode

Slide fields:

field required description
src yes full-size image URL (equivalent to href in HTML mode)
thumb no thumbnail URL used in the nav strip. Falls back to src
caption no caption text (equivalent to data-caption)
alt no image alt text. Falls back to caption, then src
id no identifier used by show(id) and the URL hash. Falls back to the index
group no group name (equivalent to data-group). Falls back to "nogroup"
width / height no natural image size in px. When given, SmartPhoto skips the preload used to measure the image

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

variable description default
arrows prev/next arrows true
nav navigation images at the bottom true
showAnimation animate the open/close transition true
verticalGravity apply device-tilt gravity to the vertical axis too (in addition to horizontal) false
useOrientationApi use the accelerometer (deviceorientation) to move a zoomed image false
useHistoryApi update the URL hash (#group=…&photo=…) via the History API true
swipeTopToClose close the viewer on an upward swipe false
swipeBottomToClose close the viewer on a downward swipe true
swipeOffset minimum swipe distance (px) to trigger navigation/close 100
swipeVelocity minimum swipe speed (px/ms) that triggers navigation even below swipeOffset (fast flicks) 0.5
headerHeight height (px) reserved for the header when fitting images 60
footerHeight height (px) reserved for the footer when fitting images 60
resizeStyle resize images to fill/fit on the screen 'fit'
animationSpeed animation speed (ms) when switching/opening/closing images 300
forceInterval frequency (ms) to apply force to images 10
registance friction applied to the inertia scroll of a zoomed image 0.5
loadOffset number of neighboring slides to preload around the current one 2
lazyAttribute attribute read for a lazy-loaded thumbnail (HTML mode only) 'data-src'
classNames override any of the generated CSS class names see source
message override screen-reader text (gotoNextImage / gotoPrevImage / closeDialog / carouselLabel) see source

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

method description
on(event, listener) subscribe to one of the events listed above
destroy() remove the viewer and all of its event listeners
[Symbol.dispose]() same as destroy(). Lets a using declaration destroy the instance automatically when it goes out of scope: { using photo = new SmartPhoto(...); }
gotoSlide(index) go to the slide at index within the current group
hidePhoto(dir?) close the viewer. dir is 'bottom' (default) or 'top' and controls the close animation direction
zoomPhoto() / zoomOutPhoto() zoom the current image in/out programmatically
addNewItem(element) register a new <a> thumbnail element (HTML mode)
show(indexOrId?, options?) open the viewer, by index or id. Works in both HTML mode and data source mode. options.group picks the group; options.trigger sets the element to animate from and to return focus to
hide() alias of hidePhoto()
next() / prev() go to the next/previous slide. No-op at the start/end of the group
addItem(slideOrElement) add a new item. Accepts a slide object (data source mode) or an Element (HTML mode, same as addNewItem)
currentIndex (getter) the index currently displayed within its group

CSS Custom Properties

property description default
--smartphoto-animation-speed animation speed when switching/opening/closing images. Overridden per-instance by the animationSpeed JS option 300ms
--smartphoto-animation-function easing function used for animations ease-out
--smartphoto-backdrop-color backdrop color when viewing images rgba(0, 0, 0, 1)
--smartphoto-header-color header color rgba(0, 0, 0, .2)

Set these on .smartphoto (or :root) to override the defaults, no rebuild required:

.smartphoto {
  --smartphoto-animation-speed: 500ms;
  --smartphoto-animation-function: ease-in-out;
  --smartphoto-backdrop-color: rgba(0, 0, 0, 0.9);
  --smartphoto-header-color: rgba(0, 0, 0, 0.4);
}

Download

Download ZIP

Github

https://github.com/appleple/SmartPhoto

License

Code and documentation copyright 2017 by appleple, Inc. Code released under the MIT License.

About

The most easy to use responsive image viewer especially for mobile devices

Topics

Resources

Stars

897 stars

Watchers

27 watching

Forks

Releases

Packages

Used by

Contributors

Languages