/fresco

A Beautiful Responsive Lightbox

Primary LanguageJavaScriptCreative Commons Attribution 4.0 InternationalCC-BY-4.0

Fresco

A Beautiful Responsive Lightbox.

Fresco comes with thumbnail support, fullscreen zoom, Youtube and Vimeo integration for HTML5 video and a powerful Javascript API.

fresco_preview

Usage

Installation

Download Fresco and include it below the latest 3.x release of jQuery:

<script
  type="text/javascript"
  src="https://code.jquery.com/jquery-3.6.0.min.js"
></script>
<script type="text/javascript" src="/fresco/dist/js/fresco.min.js"></script>
<link rel="stylesheet" type="text/css" href="/fresco/dist/css/fresco.css" />

Alternatively Fresco can be installed using npm or yarn:

npm i @staaky/fresco
yarn add @staaky/fresco

Basic usage

The easiest way to use Fresco is by adding the class fresco to a link.

<a href="image.jpg" class="fresco">Show image</a>

The alternative is using the Javascript API. For more on this see the API docs.

Fresco.show("image.jpg");
<a href="image.jpg" class="fresco" data-fresco-caption="Caption below the image"
  >Caption</a
>

Setting Options

Extra Options and Callbacks can be added using the data-fresco-options attribute.

<a
  href="image.jpg"
  class="fresco"
  data-fresco-caption="Caption on top of the image"
  data-fresco-options="ui: 'inside'"
  >Caption on top</a
>

Groups

Create groups by giving links a data-fresco-group attribute. Each group should have a unique name. Groups can contain multiple types of content, images can be mixed with Youtube videos for example:

<a
  href="image1.jpg"
  class="fresco"
  data-fresco-group="shared_options"
  data-fresco-group-options="ui: 'inside'"
  >This group</a
>
<a href="image2.jpg" class="fresco" data-fresco-group="shared_options"
  >has shared</a
>
<a href="image3.jpg" class="fresco" data-fresco-group="shared_options"
  >options</a
>

User Interface

There are two types of user interface settings, outside and inside. outside is the default and will put user interface elements outside of the window.

data-fresco-group-options="ui: 'outside'"

The alternative is inside, it puts the elements inside the window:

data-fresco-group-options="ui: 'inside'"

On small screens Fresco will switch to an alternative UI mode to optimize use of the viewport. This mode uses the entire screen for navigation and doesn't close Fresco when clicking the overlay.

Note: Touch devices will always use ui: 'outside' no matter which ui option is selected.

Important: ui: 'outside' will be forced whenever a group contains more than images. The reason for this is that interaction with content like Youtube videos would be impossible if it had overlapping user interface elements.

Overflow

Overflow can be used to create a zoom-like effect. By default the overflow options is set to false, which resizes images to fit within the viewport. Using overflow true will allow overflow along the y-axis.

Here's a popular usecase of overflow combined with vertical thumbnails:

<a
  href="large_image_2.jpg"
  class="fresco"
  data-fresco-group="overflow-example"
  data-fresco-group-options="overflow: true, thumbnails: 'vertical', onClick: 'close'"
  >Overflow</a
>
<a href="large_image_2.jpg" class="fresco" data-fresco-group="overflow-example"
  >2</a
>

Note: Overflow is not supported on touch based devices.

Thumbnails

Thumbnails are enabled by default and are automatically generated for images and Youtube videos. They can also be disabled by setting the thumbnails option to false:

data-fresco-group-options="thumbnails: false"

By default the thumbnails option is set to horizontal, the alternative is vertical:

data-fresco-group-options="thumbnails: 'vertical'"

Performance, best practices

To improve performance it's recommended to create your own thumbnails. This avoids having to load entire source images to generate them on the fly. Providing thumbnails using the thumbnail option speeds up load times and saves bandwidth, especially noticeable with groups containing large images.

<a
  href="image1.jpg"
  class="fresco"
  data-fresco-group="thumbnail-example"
  data-fresco-options="thumbnail: 'thumbnail1.jpg'"
  >Generated Thumbnails</a
>
<a
  href="image2.jpg"
  class="fresco"
  data-fresco-group="thumbnail-example"
  data-fresco-options="thumbnail: 'thumbnail2.jpg'"
  >2</a
>

Note: The thumbnail generated is set to 240x240px because the maximum dimensions of a thumbnail are 120x120px. Having double the size available will make sure the thumbnails look good on Retina displays.

Media types

Fresco attempts to automatically detect the media type using the given url. The type can also be set to one of the following values using the data-fresco-type attribute: image, youtube or vimeo.

Image

Most of the time setting the type will not be required for images, it will be required in cases where Fresco cannot detect it based on the url:

<a href="/images/?id=1337" class="fresco" data-fresco-type="image">Image</a>

Youtube

Links to Youtube videos will be embedded using the Youtube <iframe> API.

<a href="http://www.youtube.com/watch?v=c0KYU2j0TM4" class="fresco">Youtube</a>

Options of the Youtube <iframe> API can be set using the youtube option, see YouTube Embedded Players and Player Parameters for all the available options. Setting the width and height option might also be desired:

<a
  href="http://www.youtube.com/watch?v=7gFwvozMHR4"
  class="fresco"
  data-fresco-options="
      width: 853,
      height: 480,
      youtube: { autoplay: 0 }
    "
  >Youtube - Dimensions and options</a
>

Vimeo

Vimeo links are embedded using the Vimeo API:

<a href="http://vimeo.com/32071937" class="fresco">Vimeo</a>

Options of the Vimeo Player API can be set using the vimeo option. See Vimeo Player Embedding for all the available options:

<a
  href="http://vimeo.com/108057431"
  class="fresco"
  data-fresco-options="
     width: 853,
     height: 480,
     vimeo: { autoplay: 0 }
   "
  >Dimensions and options</a
>

Note: Vimeo videos don't have a thumbnail by default, this can be set using the thumbnail option.

Javascript API

The API allows Fresco to be used with just Javascript, as an alternative to using the fresco class on links. The most common use of the API is opening multiple items from a single link.

Method

Fresco.show()

A single item can be shown by giving Fresco.show() a url:

<a href="#" id="example-1">Show Image</a>

<script type="text/javascript">
  $(document).ready(function () {
    $("#example-1").on("click", function (event) {
      // the page will scroll up without this
      event.preventDefault();

      // Fresco API code goes here
      Fresco.show("image.jpg");
    });
  });
</script>

Add a caption by using an object instead:

Fresco.show({
  url: "image.jpg",
  caption: "Caption below the image",
});

This object also accepts options to customize Fresco:

Fresco.show({
  url: "http://www.youtube.com/watch?v=c0KYU2j0TM4",
  options: {
    width: 853,
    height: 480,
    youtube: { autoplay: 0 },
  },
});

Groups

Groups can be shown by giving Fresco.show() an array with multiple items:

// use urls
Fresco.show(["image1.jpg", "image2.jpg"]);

// or objects
Fresco.show([
  { url: "image1.jpg", caption: "Caption for this image" },
  { url: "image2.jpg", caption: "Another caption" },
]);

Options for the entire group can be set using the second argument:

Fresco.show(["image1.jpg", "image2.jpg"], {
  thumbnails: false,
});

Position

Open Fresco at a specific position by setting a number as the last argument:

Fresco.show(["image1.jpg", "image2.jpg"], 2);

Links

Links that use the fresco class can also be opened by passing Fresco.show() an element:

Fresco.show($("#elementid")[0]);

Fresco.hide()

Close Fresco at any time by calling Fresco.hide():

Fresco.hide();

Fresco.disable()

Disables Fresco. When disabled, links using the fresco class will no longer open Fresco but work as regular links. Calls to Fresco.show() will use a fallback to make them behave like regular links.

Fresco.disable();

Use Fresco.fallback(false) should you need to disable this fallback as well:

Fresco.fallback(false).disable();

Fresco.enable()

Enable Fresco if it was previously disabled.

Fresco.disable();

Fresco.fallback()

When Fresco is disabled it will fallback to making Fresco.show() calls open as regular links. By disabling this fallback API calls will do nothing at all.

Fresco.fallback(false);

Fresco.setDefaultSkin()

Sets the name of the default skin, this skin will be used when no skin option is provided.

Fresco.setDefaultSkin("custom");

Options

Options can be set using the data-fresco-options attribute.

<a href="image.jpg" class="fresco" data-fresco-options="ui: 'inside'"
  >Show Image</a
>

Or when used with groups, the data-fresco-group-options attribute.

<a
  href="image1.jpg"
  class="fresco"
  data-fresco-group="options_example"
  data-fresco-group-options="thumbnails: false, ui: 'inside'"
  >Image 1</a
>
<a href="image2.jpg" class="fresco" data-fresco-group="options_example"
  >Image 2</a
>
<a href="image3.jpg" class="fresco" data-fresco-group="options_example"
  >Image 3</a
>

When using the Javascript API these would translate to:

Fresco.show({ url: "image.jpg", options: { ui: "inside" } });
Fresco.show(["image1.jpg", "image2.jpg", "image3.jpg"], {
  thumbnails: false,
  ui: "inside",
});
Option

effects

Sets the duration ofindividual effects, or disables them when set to false.

effects: false

These are all the available options:

effects: {
  content: { show: 0, hide: 0 },
  spinner: { show: 150, hide: 150 },
  window: { show: 440, hide: 300 },
  thumbnail: { show: 300, delay: 150 },
  thumbnails: { slide: 0 }
}

height

This option only affects youtube content, for everything else this option will translate to maxHeight.

height: 720

initialTypeOptions

Initial options for different types, available types are image, vimeo and youtube. This option is there for use within skins where it can help to adjust defaults and avoid code repetition.

initialTypeOptions: {
  'image': { },
  'vimeo': {
    width: 1280
  },
  'youtube': {
    width: 1280,
    height: 720
  }
}

keyboard

Enable or disable individual keyboard buttons or all of them when set to false. Useful for when the content requires keyboard interaction.

keyboard: false

Use an object to toggle individual buttons:

keyboard: {
  left: true,
  right: true,
  esc: false
}

Note: The keys left and right are only enabled when using the image type. Any other type of content might require these keys.

loadedMethod

Sets the method used to decide when an image is loaded. The default is naturalWidth, which starts showing the image as soon as dimensions are known.

The alternative is using onload, which shows the image as soon as onload fires. This can give the image more time to render, but is slower.

loadedMethod: 'onload'

loop

When set to true a group becomes a continuous loop, keeping navigation buttons enabled at all times:

loop: true

maxHeight

Sets a maximum height for the content.

maxHeight: 500

maxWidth

Sets a maximum width for the content.

maxWidth: 500

overflow

Sets overflow along the y-axis, creating a zoom like effect whenever an image overflows.

See the documentation on overflow for examples on using this option.

overflow: true

Note: Overflow is not supported on touch based devices.

overlay

Options of the overlay, setting close: false will prevents clicks on the overlay from closing the window.

overlay: { close: false }

onClick

What to do when clicking the area overlapping an image. Available options are: 'previous-next' or 'close'

position

Shows a position indicator when set to true, or hides it when set to false.

position: false

preload

Sets the items to preload before and after the current item, or disables preloading when set to false.

preload: [1, 2] // preload 1 before and 2 after
preload: false // disables preloading

spinner

Disables the loading icon when set to false.

spinner: false

skin

Sets the skin, the options of this skin will be applied as a starting point for other options. Available skins are: fresco and any added custom skins.

skin: 'fresco'

Note: See documentation on Skins for instructions on creating and customizing skins.

sync

Hides the current item while showing the next one when set to true (the default). Setting it to false will hide the current item before showing the next one.

sync: false

thumbnail

This option can be used to set an alternative thumbnail image, it will be based on the source if this option isn't set.

thumbnail: 'thumbnail.jpg'

Note: See the documentation on performance more information on optimizing thumbnails for performance.

thumbnails

Enabled or disables the thumbnails below the content.

thumbnails: false

Note: Thumbnails aren't used on touch based devices for performance reasons.

ui

Sets position of user interface elements. The default is outside which positions everything outside of the content, inside puts the elements on top of the content:

ui: 'inside'

On small screens Fresco will switch to an alternative UI mode to optimize use of the viewport. This mode uses the entire screen for navigation and doesn't close Fresco when clicking the overlay.

uiDelay

The duration in miliseconds to wait before hiding UI elements that can be toggled on mouseover:

uiDelay: 3000

vimeo

Sets the player parameters of a Vimeo video, available options can be found in the Vimeo documentation: Vimeo Player Embedding.

vimeo: {
  autoplay: 1,
  title: 1,
  byline: 1,
  portrait: 0,
  loop: 0
}

width

This option only affects youtube content, for everything else this option will translate to maxWidth.

width: 1280

youtube

Sets the player parameters of a Youtube video, available options can be found in the Youtube documentation: YouTube Embedded Players and Player Parameters.

youtube: {
  autohide: 1,
  autoplay: 1,
  controls: 1,
  enablejsapi: 1,
  hd: 1,
  iv_load_policy: 3,
  loop: 0,
  modestbranding: 1,
  rel: 0,
  vq: 'hd1080'
}

Callbacks

Callbacks can be used alongside other Options.

Callback

afterPosition

A function to call after the position changes. The first argument is the current position within the loaded group.

afterPosition: function(position) {
  alert("You've reached position " + position);
}

afterHide

A function to call when Fresco hides.

afterHide: function() {
  alert('Fresco is no longer visible');
}

onShow

A function to call when Fresco comes into view.

onShow: function() {
  alert('Fresco is visible');
}

Skins

Skins are a combination of Javascript Options, CSS and an SVG/PNG sprite. To use a skin the only option required is the skin option. Options of the selected skin are then applied as a starting point. Additional options will overwrite what's defined on the skin:

skin: 'fresco', ui: 'inside'

When creating your own skins it's highly recommended to place all custom Javascript and CSS in separate files included below the Fresco files. This will allow upgrading without losing any of your custom skins. Here's an example:

<script
  type="text/javascript"
  src="https://unpkg.com/@staaky/fresco@2.3.0/dist/js/fresco.js"
></script>
<link
  rel="stylesheet"
  type="text/css"
  href="'https://unpkg.com/@staaky/fresco@2.3.0/dist/css/fresco.css"
/>

<script type="text/javascript" src="/fresco/custom-skin.js"></script>
<link rel="stylesheet" type="text/css" href="/fresco/custom-skin.css" />

<script type="text/javascript">
  // make a custom skin the new default
  Fresco.setDefaultSkin("custom");
</script>

Adding a new skin

A custom skin requires Javascript, CSS and sprite images. Let's start with the Javascript.

All skins inherit their options from a base skin defined in Fresco.skins. Because of this inheritance the only Options that have to be defined are those different from the base skin. A custom skin is created by extending the Fresco.Skins object, here's how it could be defined:

$.extend(Fresco.Skins, {
  custom: {
    ui: "inside",
  },
});

After the skin has been created it can be applied using the skin option:

<a href="image.jpg" class="fresco" data-fresco-options="skin: 'custom'"
  >Custom skin</a
>

When using groups the best way to apply the skin is using the data-fresco-group-options:

<a
  href="image1.jpg"
  class="fresco"
  data-fresco-group="example"
  data-fresco-group-options="skin: 'custom'"
  >Same</a
>
<a href="image2.jpg" class="fresco" data-fresco-group="example">Skin</a>

Custom CSS

Once the Javascript for a skin is in place a skin will need CSS and sprites for styling. To help with styling Fresco adds the name of the skin to certain classnames:

.fr-window-skin-SKINNAME
.fr-overlay-skin-SKINNAME
.fr-spinner-skin-SKINNAME

It is recommended to copy the fresco skin defined in fresco.css as a starting point for new skins. To do this copy all the definitions of the fresco skin into to a separate css file.

This means all definitions starting with .fr-window-fresco, .fr-overlay-fresco and .fr-spinner-fresco. Rename those to match your new skin. For example, if your skin is named custom the CSS rules would start with:

.fr-window-skin-custom
.fr-overlay-skin-custom
.fr-spinner-skin-custom

Changing the default skin

To avoid having to set the skin option all the time the default skin can be changed using Fresco.setDefaultSkin(). It should be called after the file that defines custom skins, for example:

<script type="text/javascript" src="/js/fresco/fresco.js"></script>
<link rel="stylesheet" type="text/css" href="/css/fresco/fresco.css" />

<script type="text/javascript" src="/js/fresco/fresco-custom-skins.js"></script>
<link
  rel="stylesheet"
  type="text/css"
  href="/css/fresco/fresco-custom-skins.css"
/>

<script type="text/javascript">
  // make a custom skin the new default
  Fresco.setDefaultSkin("custom");
</script>

Fresco has been open-sourced under the Creative Commons BY 4.0 license as of oct. 26 2019.