☑ Lightbox style hotspots


I building a concept of a product with clickable hotspots. When I click the hotpots, which I’ve managed to react to using the raycast method, I would like to show information about that hotspot in a “lightbox”-type style. I’ve come so far I’ve created UI components in HTML and added to the dom tree, and then I show them when the hotspot sprite is clicked.

Has anyone been successful in using a lightbox plugin i coalition with playbox? I’m talking about something llike Premium JavaScript UI Component Library or similar.

Best regards

  • Björn

Hi Björn,

fancyBox and other libraries are simple to set up with PlayCanvas - I’ve made a project for demonstration here: https://playcanvas.com/project/435704/overview/fancybox

To toggle the lightbox, press the space bar. Feel free to look through the project to see how it’s done. Let me know if you have any questions. :slight_smile:

1 Like

Hi, thanks for that setup… I’m looking into it right now!

First problem i run into is that the script files (jquery-3.1.1.min.js, jquery.fancybox.js etc) I upload into Playcanvas are not accessible from the dropdown list of an entity’s script component. That is, I do not seem to be able to selectec them as script components. Only scripts that are created within the Playcanvas interface are visible there.

  • Björn

You do not need to add external scripts as scripts in a script component. All scripts in your project will be loaded in the order specified by the Scripts Loading Order in your settings regardless of whether they are on a script component or not. (unless you set preload to false on them).

Oh I see! I was confused by that example project there then, because in there all scripts are attached to entitys. Thanks!

It used to be that way but not anymore with the new script system :slight_smile:

Great. CSS I still have to add manually though no? The fancybox system for example comes with some css, which in turn references to some images like the close buttons etc. Where would I put those?

I can’t seem to edit the script loading order. Right now, my jquery is loading last, and I get a lot of reference errors but I can’t pull it up the stack. It jumps back last.

Check this video out: https://dl.dropboxusercontent.com/u/114792/ShareX/2016/11/2016-11-15_14-35-16.mp4

Hm this sounds either like a bug or something that you’re not doing right :slight_smile:

Can you PM me your project link?

Ok, seemed to be some kind of bug.

But to follow up, images that are referenced in css, would I have to load both the CSS and images manually somehow?

You can write CSS inside a CSS asset (
http://developer.playcanvas.com/en/user-manual/assets/css/) and then have a script that exposes a CSS script attribute. Then in the Editor you can assign the CSS asset to the script attribute. Then in your script create a style node and add it to your document. Something like this (untested):

MyScript.attributes.add('css', {type: 'asset', assetType: 'css'});

MyScript.prototype.initialize = function () {
  var style = pc.createStyle(this.css.resource);

  // when asset resource loads/changes,
  // update html of element
  this.css.on('load', function() {
    style.innerHTML = this.css.resource;

Regarding images referenced in CSS either you need to store your images on some server and reference them by URL or instead of typing actual URLs inside your CSS you can add your images as assets inside your project, give them a tag, and then inside your CSS type the tag instead of the URL. Then before creating the style node in your script, preprocess your CSS to replace tags with asset URLs. I know this sounds a bit complicated so here’s some pseudocode:

Example CSS:

.mybutton {
  background: url("{asset[some-tag]}");

Then inside your script where you are creating the style node something like:

var MyScript = pc.createScript('myScript');

MyScript.attributes.add('css', {type: 'asset', assetType: 'css'});

MyScript.prototype.initialize = function() {
    var content = this.replaceTags(this.css.resource);
    var style = pc.createStyle(content);
    this.css.on('load', function () {
        content = this.replaceTags(this.css.resource);
        style.innerHTML = content;

MyScript.prototype.replaceTags = function (raw) {
    // replace {asset[tag]} with the asset's URL
    var matches = raw.match(/\{.+?\}/g);
    for(var i = 0; i < matches.length; i++) {
        var parts = matches[i].match(/\{asset\[([a-z0-9\-]+?)\]/i);
        if (parts) {
            var tag = parts[1];
            var asset = this.app.assets.findByTag(tag)[0];
            if (! asset)
            var url = asset.getFileUrl();                                    
            raw = raw.replace(matches[i], url);
    return raw;    

GREAT, thank you a lot! This code works perfectly. I had an error when using an underscore _ in a tag but I guess it’s to the “parts” regexpression only looking for a-z0-9 something, but I’m not confident enough in that to try and change it. I changed the tags instead.

One last problem I faced was the fancybox plugin takes two gifs, animated loading spinners basically. But when I import those into playcanvas they get converted into png. That’s a restriction in the framework perhaps?


  • Björn