GithubHelp home page GithubHelp logo

henrygd / bigpicture Goto Github PK

View Code? Open in Web Editor NEW
815.0 21.0 76.0 8.68 MB

Lightweight JavaScript image / video viewer. Supports Youtube, Vimeo, etc.

Home Page: https://henrygd.me/bigpicture

License: MIT License

JavaScript 71.79% CSS 15.12% HTML 13.09%
youtube vimeo lightbox

bigpicture's Introduction

logo BigPicture npm File Size

Example page screenshot Vanilla JavaScript image / video viewer meant to be as lightweight and easy to use as possible.

Installation

Install via package manager or add a script from the dist directory to your page. CDN links are available via jsDelivr.

npm install bigpicture
// import
import BigPicture from 'bigpicture'

// or require
var BigPicture = require('bigpicture')

Or with a script tag:

<script src="BigPicture.js"></script>

No additional CSS file is neccesary.

Usage

When you want to open something, pass an object to BigPicture containing the element from which you want the animation to start, and other optional parameters depending on what you want to do. Examples below use e.target to refer to the trigger element being interacted with in the context of an event handler. You can use a different element if you want (for example, different buttons could be set up to open videos from the same central showcase element).

If your trigger element is an image or an element with a background image, you can open it directly by passing only el.

Options

BigPicture({
	// element from which animation starts (required)
	el: e.target,
	// image url
	imgSrc: 'https://yourimage.jpg',
	// video src (String) or sources (Array)
	vidSrc: ['https://yourvideo.mp4', 'https://yourvideo.webm'],
	// iframe embed URL
	iframeSrc: 'https://youriframe.html',
	// vimeo ID
	vimeoSrc: '119287310',
	// youtube ID
	ytSrc: 'z_PeaHVcohg',
	// use youtube-nocookie
	ytNoCookie: false,
	// audio URL
	audio: 'https://youraudio.mp3',
	// see below for more gallery options
	gallery: '#image_container',
	// attribute used to find gallery elements
	galleryAttribute: 'data-bp',
	// set custom dimensions for embeds / videos
	dimensions: [1920, 1080],
	// show or hide default loading indicator
	noLoader: false,
	// customize the overlay color (any valid css color value)
	overlayColor: 'rgba(0, 0, 0, .8)',
	// open animation callback
	animationStart: () => {},
	// open animation callback
	animationEnd: () => {},
	// close callback
	onClose: () => {},
	// gallery image change callback
	onChangeImage: () => {},
})

The function returns an object with a few helpful properties / methods.

var bp = BigPicture({...})

// close
bp.close()

// next gallery image
bp.next()

// previous gallery image
bp.prev()

// access to active display element (img, video, iframe wrapper div)
bp.display

// options of active instance
bp.opts

Sources

Remote video file

BigPicture({
	el: e.target,
	vidSrc: 'https://yourvideo.mp4',
	// or with multiple sources
	// vidSrc: ['https://yourvideo.mp4', 'https://yourvideo.webm']
})

Youtube

Pass in the video ID from the url. For example, the ID for https://www.youtube.com/watch?v=z_PeaHVcohg would be z_PeaHVcohg (The v parameter in the address).

BigPicture({
	el: e.target,
	ytSrc: 'z_PeaHVcohg',
})

Vimeo

Like Youtube, pass in the video ID from the url. The ID for https://vimeo.com/119287310 would be 119287310.

BigPicture({
	el: e.target,
	vimeoSrc: '119287310',
})

iframe embed

Pass in the URL from the iframe.

BigPicture({
	el: e.target,
	iframeSrc: 'https://youriframe.html',
})

Audio

BigPicture({
	el: e.target,
	audio: 'https://youraudio.mp3',
})

Remote individual image

BigPicture({
	el: e.target,
	imgSrc: 'https://yourimage.jpg',
})

Galleries

Add a data-bp attribute to your elements with the image you want to open, and pass a selector string or NodeList to the function. The string should specify a container which has data-bp elements somewhere inside, whereas the NodeList should be the elements themselves.

The attribute name can be overridden with the galleryAttribute option as of 2.4.0. For instance, galleryAttribute: 'src' would open the thumbs in the example below, and the data-bp attributes would be unnecessary.

<div id="image_container">
	<img src="photo1_thumb.jpg" data-bp="photo1.jpg" class="example" />
	<img src="photo2_thumb.jpg" data-bp="photo2.jpg" />
	<img src="photo3_thumb.jpg" data-bp="photo3.jpg" class="example" />
</div>
// opens gallery w/ all three images
BigPicture({
	el: e.target,
	gallery: '#image_container',
})
// opens gallery w/ the two images matching the selector
BigPicture({
	el: e.target,
	gallery: document.querySelectorAll('#image_container .example'),
})

Alternatively, you can pass in an array of objects. The gallery will go through these in order. Here's example code for the unsplash gallery on the demo site:

var unsplashImages = ['meiying', 'clemono2', 'heftiba'].map(function (user) {
	return {
		src: 'https://source.unsplash.com/user/' + user + '/daily',
		// caption: 'This image is from unsplash'
	}
})
BigPicture({
	el: e.target,
	gallery: unsplashImages,
	// optionally specify a starting index
	position: 2,
})

You can also loop the gallery (next on last image gives you the first image, and vice versa).

BigPicture({
	el: e.target,
	gallery: '#image_container',
	loop: true,
})

Captions

To display a caption, add a data-caption attribute with the desired text or HTML to the trigger element itself.

<img src="yourimage.jpg" data-caption="Example of an optional caption." />

Optional callbacks

animationStart and animationEnd run at the start or end of the opening animation. animationStart will run even if there's an error, so it's okay to use if you want to hide your own custom loader.

onClose runs after closing animation finishes.

onChangeImage runs when a gallery image is changed and provides useful data about the current image.

// example of how scrolling can be disabled using henrygd.me/hide-show-scroll
BigPicture({
	el: e.target,
	// animationStart executed immediately before open animation starts
	animationStart: hideScroll,
	// animationEnd executed immediately after open animation finishes
	animationEnd: function () {
		console.log('it has opened')
	},
	// onClose executed immediately after close animation finishes
	onClose: showScroll,
	// onChangeImage executed on gallery image change
	onChangeImage: function (props) {
		console.log('gallery image changed', props)
	},
})

Hide default loading icon

If you're loading remote images or videos and don't want the default loading icon displayed, set noLoader to true.

BigPicture({
	el: e.target,
	vimeoSrc: '119287310',
	noLoader: true,
})

Change dimensions of embed / youtube / vimeo

By default, embeds are displayed in 16:9 aspect at a maximum of 1920px by 1080px. To change this, supply an array with width and height in pixels. Default is [1920, 1080].

BigPicture({
	el: e.target,
	ytSrc: 'X2lkvrMa27c',
	dimensions: [1226, 900],
})

Dimensions can also be updated on the fly.

var bp = BigPicture({...})

bp.opts.dimensions = [500, 500]
bp.updateDimensions()

Error handling

You may override the default error alert for images, audio, and direct video links by passing an onError function.

BigPicture({
	el: e.target,
	onError: function () {
		console.log('there was an error')
	},
})

Troubleshooting

If the media or loading icon fails to display, it's probably a z-index issue. The media container has a default z-index of 9999, and the loading icon has a z-index of 9 relative to the trigger element's parent container.


License: MIT

All images found on Unsplash

Towers of Pfeiffer video by Grant Porter (CC-BY)

Music by Nordgroove via icons8

📢 Note: I made another lightbox library with features like responsive images, zooming, HTML modals, and various improvements over this one. Please check out the Bigger Picture demo site or GitHub repository.

bigpicture's People

Contributors

adamkiss avatar bfintal avatar buzut avatar chuckcharles avatar henrygd avatar nextgenthemes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bigpicture's Issues

Feature request: Ability to make a gallery mixing videos images and iframes...

A very nice feature will be the ability to make a gallery mixing various media type (videos, images, pdf and iframes) like Google drive

Something like:

var items= [];
items.push({
	vidSrc: 'https://yourvideo.mp4',
	caption: 'video caption'
});
items.push({
	ytSrc: 'z_PeaHVcohg',
});
items.push({
	vimeoSrc: '119287310',
});
items.push({
	iframeSrc: 'https://youriframe/my-file.pdf',
});
items.push({
	audio: 'https://youraudio.mp3',
	caption: 'audio caption'
});
items.push({
	imgSrc: 'https://yourimage.jpg',
	caption: 'image caption'
})


BigPicture({
	el: e.target,
	gallery: items,
	// optionally specify a starting index
	position: 2,
})

Separate style and script

Hello,

I love your plugin but I actually can't use it because it's impossible to adapt the design to match my website. I guess I'm not the only one as every website is different...

To make this plugin universal it should be a priority to separate the style from the script. You could do it easily by using SCSS with a bunch of default variables that can be override.

What do you think about the idea?

Feature request: support pinch zoom in/out

Seems like I should be able to natively pinch zoom in/out when viewing an image on a mobile device when my viewport setting doesn't prevent it, as so:

<meta name="viewport" content="width=device-width, initial-scale=1">

However, when showing an image, I cannot zoom in/out.

Transition animation for galleries

Thank you for this awesome lightbox.

Given the attention that has been given to the initial transition, it's almost puzzling to the user that there's no transition between two images of the gallery (like the one in baguetteBox for instance).

It would be a real plus!

[how to] instantiate BigPicture for Nodelists [array of img nodes]

hello,

i am not mentioning a bug but want to know how to use

i don't know how to instatiate BigPicture for series of images in a container like

<section id="bigPicture">
		<img src="http://oi49.tinypic.com/2wd63h1.jpg" alt="">
		<img src="http://oi40.tinypic.com/awvrdx.jpg" alt="">
		<img src="http://oi43.tinypic.com/2lke6ug.jpg" alt="">
	</section>

javascript

var images = document.querySelectorAll('bigPicture img');
var forEach = function (array, callback, scope) {
  for (var i = 0; i < array.length; i++) {
    callback.call(scope, i, array[i]); // passes back stuff we need
  }
};

forEach(images, function(ind, el){
    BigPicture({
        'el': el
    });
});

questions

  1. can the same img tags be triggers other than thumbnail buttons or similar
  2. how to instantiate for a group of images

Hide scrollbar

Hi,

Is it possible to hide the scrollbars when bigpicture is open?

Thanks.

Not work multiple (

<a href="#!" class="weight_bold main_page_link_ogange js_lightbox" ytsrc="vsypFJ5mNw0" data-caption="Демо-кабинет">Посмотрите пример</a>

                                    <a href="#!" class="main_page_link_ogange d_none d_xs_block weight_bold main_page_small_txt js_lightbox" ytsrc="p96y6FiD7sU" data-caption="Демо-кабинет">
                                    	Все изменения по вашему делу вы увидите в Личном кабинете
                                    </a>

                                    <a href="#!" class="weight_bold main_page_link_ogange js_lightbox" ytsrc="vsypFJ5mNw0" data-caption="Демо-кабинет">Посмотрите пример</a>

	  		/* ==============================================
	  			Name function
	  		============================================== */

			if(document.querySelector('.js_lightbox')) {

				document.querySelector('.js_lightbox').addEventListener('click', function (e) {

					e.preventDefault();

					var className = e.target.className

					if (~className.indexOf('js_lightbox')) {
						BigPicture({
							el: e.target,
							ytSrc: e.target.getAttribute('ytSrc'),
						});
					}
				});

			};

	  	    /* ==============================================
	  			End of Name function
	  	============================================== */

Feature request: add swipe support

It would be great to support basic swipe events:

swipe up/down - close
swipe left - next slide
swipe right - previous slide

This is a great library... love the simplicity. Thank you!!!

allow for playsinline for ios users

Very nice library, thanks!

You might know that as part of Apple's general program to destroy the open internet, they disallowed "inline" HTML5 video playing for a long time.

They have recently opened things up a bit:

https://webkit.org/blog/6784/new-video-policies-for-ios/

So if you declare a video tag like
<video playsinline src = "whatever.mp4">
Then iOS browsers will actually honor this and play the video inline, instead of full screen.

I think ideally, if possible, bigpicture should support this.

I tried modifying this line

displayVideo.controlsList = "nodownload noremoteplayback nofullscreen playsinline";

But for some reason it doesn't work. It might be because controlsList is actually only for chrome.

Any suggestions on a tweak to get bigpicture to play videos inline on iOS?

thanks!

Feature request - support for iframes with variable height

I would like to set the height of an iframe to be something other than the aspect ratio calculated from the width/height of the dimension array in the options. Is this possible?

Scenario: I have an iframe embed that renders a media player along with some text, so the height of the embed can vary. I want to use as much of the window as I can to render the iframe.

Here's what I'm doing to accomplish this at the moment (using jquery):

BigPicture({
	el: $(elem).get(0),
	iframeSrc: 'iframe.html',
	animationStart: function () {
		var wrap = $('#bp_sv'),
			iframe = $('>iframe', wrap);
		$(iframe).on('load', function () {
			var maxHeight = $(window).height() - 50,
				native = $(this).get(0)
				height = Math.min(native.contentWindow.document.body.scrollHeight + 30, maxHeight);
			$(wrap).css({
				height: height + 'px'
			});
		});
	}
});

A couple issues:

  1. Resizing is a problem... even if I add code to resize, I'll be fighting with BP because it's also resizing. Perhaps BP could support a resize callback?
  2. It would be better to apply the load callback to the iframe immediately when the its created so I don't miss the event
  3. I'm accessing #bp_sv directly, which is not documented

I'm guessing the easiest thing to do would be to add a height option for an iframe, like:

iframeHeight: 'auto' | 'content' | callback

Then, the auto option would be the way it works now. The content option is more or less the code I have above (I'm sure it could be more robust), and a callback would allow the app to return a height.

open content on click event from js on demand

hello
first i want to thank u for the great plugin

I have a need to assign dynamic created divs to preview video and image

and i can create divs as follow


<div id="vid1" filesrc="files/vid2.mp4" onclick="previewfile(this); />
<div id="vid2" filesrc="files/vid2.mp4" onclick="previewfile(this); />

<script>
function previewfile(e){
myvidSrc=e.getAttribute('filesrc')
//code to open bigpicture directly without initialization
//.......
}
</script>

due to heavy ajax usage I cannot use the initialize constructure on dynamic created div
therefore would it be possible to open the preview from such external function

just wanna say Thank You!

the DEMO look awesome! exactly what I need for my next project

Thank you so much!
(you can close this issue)

Loop

Hi, how can I do loop for gallery?
Thanks for nice script :)

Feature request: Publish 2.6.0 to npm

Currently it looks like the 2.5.3 is the latest release published on npm, but commits on this repo indicate that 2.6.0 should be published to npm.

When initiating with Array, can't pass initial position other than 0

If, for whatever reasons[1], you try to initiate the gallery with Array of elements, this line of makeGallery automatically sets the position to 0, and there's no way to set it to any other position. I'd like to propose (I'll PR this, even) to add an optional position argument, which would apply here.

So you could do this:

BigPicture({
  el: this,
  position: someValueIGot,
  gallery: galleryElements
})

This would be useful in use cases where you get the elements/nodes in other way than from DOM.

Also, thank you for making this 🎉.

[1]: In my case, I've tried to pair this with Stimulus by Basecamp, which probably returns an array of Nodes instead of NodeList. When I've modified it transform the elements to array for BigPicture , I was still not able to force the gallery position.

Feature request: onLoaded option

Please add an onLoaded option.
I need this to detect if the iframe initialized a download popup, in which case, the onLoaded option allow me to detect if data appear in iframe; and thus, I can close BigPicture

Feature request: Option to pass controlslist value to HTML Video

It would be best if we have an option that we can pass to the controllist of the HTML video tag. The use case for me is to disable the download option controlslist="nodownload".

If the feature already exists, I might have missed it. can you please point it out?

Thanks for the awesome library.

Image fails to open when targeting a class

I am trying to target only images with a specific class using the following code. Unfortunately, the image does not open nor is there any console error.

 (function() {

    function setClickHandler(id, fn) {
      document.getElementById(id).onclick = fn;
    }
    setClickHandler('mybook', function(e) {
      (e.target.className === 'thumb') && BigPicture({
        el: e.target,
        imgSrc: e.target.src.replace('thumbs', 'slides')
      });
    }); 
  })();

If I use this code, it works as expected.

(function() {

    function setClickHandler(id, fn) {
      document.getElementById(id).onclick = fn;
    }

    setClickHandler('mybook', function(e) {
      e.target.tagName === 'IMG' && BigPicture({
        el: e.target,
        imgSrc: e.target.src.replace('thumbs', 'slides')
      });
    }); 
  })();

AmI missing something when targeting an image with a class rather than all images?

Callback when video has loaded

I'm trying to display my own loading indicator while BigPicture is loading an embedded video. To do this I'd like to be able to define a callback which is called when BigPicture displays the viewer (i.e. the embed has finished loading). This could either be a simple callback or a promise.

Ideally I'd also like an option to disable the built in loading spinner.

Feature request: Support custom HTML element type

It will be awesome if I can show a custom text message for not previewable file types like Google drive:
2017-04-28_16-17-32

So a new option "customElement" could be added:

var element = $("<div id="unpreviewable">Unable to preview this item</div>");
BigPicture({
	el: e.target,
	customElement: element
})

or by id:

BigPicture({
	el: e.target,
	customElement: "unpreviewable"
})

Destroy BigPicture

Hey,

thanks for this lightweight simple image modal plugin 👍
Is there any way to close the current open image and remove all memory allocations?

Customized animation

Another nice feature that we could implement would be custom animation.
Basically, people would be able to choose which animation they want to see when they click on the image. Currently, we've got sort of fade in, maybe someone wants to have something different.

Aspect Ratio seems not working correnctly with iframe. Black bars in Vimeo video.

See: https://codepen.io/nnico/pen/OJJRzyL

I am trying to use it for a Vimeo Video with a very wide Aspect Ratio and it creates black bars.

I saw in the source that you at some point take the dimensions of the element specified and that you set the css to positon: absolute; but I could not figure out how the aspect ratio it kept. No position: relative ?

I would rather like to just pass a string of HTML to be used for wrappers I have prepared with the padding-top element as sibling where the + position: absolute iframe is.

Gallery

Is it possible to do a gallery with bigpicture?
THis comp is awasome, but im trying to do a lightbox gallery with an array of local images.
Can your lib do this?

Separate scripts for video demos

He mate,
i love the script.
but how i add to a Html, Youtube, Vimeo video on a button click????
i trying and final result showing repeated - Error: The requested image could not be loaded.
why this message showing when i trying to get video on popup window???
i guess i miss something but didn't get the actual issue....
Please help with a little but separate code for lightbox video player?? any feedback would be great..

Content Security Error - refused to evaluate string

Hey @henrygd

we are testing bigpicture together with Content Security Policy (CSP)

Unfortunately CSP refuses to execute this line:

bigpicture/index.js

Lines 656 to 657 in 68cc922

// set animationEnd callback to run after animation ends (cleared if container closed)
animationEnd = setTimeout(animationEnd, 410);

The reason is that animationEnd is undefined.
Would it be possible to wrap this call with an if or to set animationEnd to a noop function?

secutiry

Provide overview of the next slides

I've been thinking, when you one of the images from the gallery, we've got left and right arrow to use only. What if we add the possibility to have thumbnails on the bottom of the page?

I'd like to contribute and develop it. What do you think?

Support for multiple video URL sources

mp4 doesn't want to play in Edge and IE11, but webm is supported.

I would like to suggest allowing the vidSrc parameter to accept an array. If an array is used, then multiple <source> can be used instead of a single src attribute.

Iframe

Hi,
is possible to open an iframe? Or html div?

Thanks you

Loading bigpicture via Dynamic Import with Webpack

This is possibly some of the oddest shit I've seen.

For some when trying to load bigpicture with a dynamic import, it doesn't let the styles in my entry point be applied to the elements on page.
The styles in my entry point have no problem being bundled to a .css file, no ES Lint errors or problems bundling.
I can see the file loaded perfectly fine. Inspecting the css file my styles for elements are present. The selectors for a specific element are there, the browser has loaded the file ok.
But the styles just do not get applied.

In addition, I found that commenting out a collection of .scss file imports above made it work, almost like there was a limit.

This doesn't happen with any other library I have tried yet.

const getBigPicture = () => import('bigpicture');
const link = document.querySelector('.link');
link.addEventListener('click', (e) => {
  e.preventDefault();
  getBigPicture().then((module) => {
    if (typeof module.default === 'function') {
      const BigPicture = module.default;
      console.log(BigPicture);
      BigPicture({
        el: link,
        ytSrc: '8ktONdU_wXU',
      });
    }
  });
});

Es6 modules

I think it would be good split de js file into es6 modules. Es6 modules are more easy to test, change and fix. For example, we can create a module that has a function responsible for create elements and than import it into main file.

Alert question

If the image does not exist, it will display alert. I hope I can remove the alert. Can I do it?

Youtube autoplay on desktop chrome

First, thanks for a nice library, much appreciated. It appears that youtube videos now require two clicks to play on a desktop browser. I know mobile safari prohibits this, but it was working previously on the desktop with chrome: click once, bigpicture launches and the video begins playing. I'm using

class="vid iframevid" 
iframesrc="https://www.youtube.com/embed/{id-here}?html5=1&rel=0&playsinline=1&autoplay=1&modestbranding=1"

The youtube example in your documentation also requires two clicks to play, once to launch the bigpicture modal and a second to start the youtube video. Vimeo works with one click. That makes me think there's an issue here. As a reference, fancybox does autoplay, so it's not a change in chrome or youtube. Example here: https://fancyapps.com/fancybox/3/

Any plans to add support for videos in gallery?

Hi, are there any plans to add support for videos in gallery? I created a rough solution which seems to work OK, but it doesn't preload videos like it does with images. I basically check if the object in the gallery has .src or .vidSrc to determine if it's video or image.

dimensions not working for <video>

See: https://codepen.io/nnico/pen/QWyERbw

I can simply set the dimensions on the created <video> in animationStart and that seems to work fine. Not sure if that is the best way to do it but I think it should be part of the script.

Because aspect ratio and height work automatically for <video> I think only width is needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.