L'utilizzo più semplice del navigatore è quello in cui si definisce un segnaposto per il navigatore, in modo che il componente sappia dove deve essere positionato, si include il JavaScript del componente, e si inizializza il componente stesso, indicando la struttura ad albero dei modelli Sketchfab da navigare.
Il componente è realizzato completamente in Plain JavaScript e pertanto non richiede librerie come jQuery, Prototype o Underscore. Questo non significa che le suddette librerie JavaScript non possano essere utilizzate, ma semplicemente che il componente di navigazione non ne ha bisogno e non ne fà uso.
Il frammento di codice HTML seguente è spiegato sotto:
<div id="sfab-container" data-role="sfab-container" tabindex="10"></div>
<script src="js/sketchfabnav.js"></script>
<script>
(function() {
const sketchFabNavSettings = {
// mr worker (cappello giallo)
modelId: 'cf11f523047a4cfab2edc51fbcf0b258',
children: [{
// 1. Belt
modelId: 'bdb0215c0eb14ad19759e84c9bf0c1ae',
children: [{
// 1.1. Drill
modelId: 'f00ddf74d1ad447c8ac7145dedfd3311'
}, {
// 1.2. Stahlwille
modelId: '21e86485c5cb4ba2ad69ea9fa2e92d3c'
}]
}, {
// 2. Guanto
modelId: '4156ccbe044a4c909c035a6a4bc8ac65'
}, {
// 3. Gilet
modelId: '2aaa2bba5a7e46c1a71c225357c6090a'
}]
};
new SketchFabNav(document, 'sfab-container', sketchFabNavSettings);
})();
</script>
id="sfab-container"
per identificare il componente in
modo da potersi riferire ad esso in linea 26 (secondo parametro del costruttore).data-role="sfab-container"
è facoltativo ma consigliato, e viene usato esclusivamente per CSS.tabindex
è facoltativo anch'esso, e serve solamente per rendere il componente soggetto a
focus (tab-focus), che potrebbe essere utile per l'accessibilità.
document
) che contiene il navigatoreHTMLElement
o identificatore univoco (attributo id
del tag HTML)
del contenitore per il navigatore (nel nostro esempio, sfab-container
).
id
dell'elemento HTML corrispondente) oppure direttamente l'istanza dell'elemento stesso, come per
il secondo parametro del costruttore.<iframe src="" allow="autoplay; fullscreen; xr-spatial-tracking"
allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"
xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered
web-share></iframe>
Trattasi dello snippet HTML raccomandato da Sketchfab, per cui comunque diamo la possibilità di personalizzazione,
nel caso dovesse servire per questioni di accessibilità o altre necessità.La struttura dati dell'albero di navigazione è un oggeto JavaScript che rappresenta un singolo nodo dell'albero, che inizia con il nodo radice (root) e permette di specificare un numero qualsiasi di nodi figli, ciascuno dei quali può avere figli a sua volta, e così via, in modo da rappresentare la gerarchia di navigazione tra modelli Sketchfab correlati al componente di navigazione.
Nel nostro esempio, abbiamo la seguente struttura, con 3 livelli (partendo da Mr Worker come nodo "root"):
Questa struttura può essere rappresentata con il seguente frammento di codice JavaScript:
{
// mr worker (cappello giallo)
modelId: 'cf11f523047a4cfab2edc51fbcf0b258',
children: [{
// 1. Belt
modelId: 'bdb0215c0eb14ad19759e84c9bf0c1ae',
children: [{
// 1.1. Drill
modelId: 'f00ddf74d1ad447c8ac7145dedfd3311'
}, {
// 1.2. Stahlwille
modelId: '21e86485c5cb4ba2ad69ea9fa2e92d3c'
}]
}, {
// 2. Guanto
modelId: '4156ccbe044a4c909c035a6a4bc8ac65'
}, {
// 3. Gilet
modelId: '2aaa2bba5a7e46c1a71c225357c6090a'
}]
}
Ogni nodo (incluso il nodo root) deve necessariamente avere la proprietà modelId
che come valore ha
l'identificativo del modello Sketchfab che il nodo stesso rappresenta. Questo identificativo può essere trovato
nel "Embed URL" del modello, in Sketchfab. Ad esempio, il nostro modello "Mr Worker con cappello
giallo" ha il seguente Embed URL: https://sketchfab.com/models/ cf11f523047a4cfab2edc51fbcf0b258 /embed,
la parte che rappresenta il modelId è in grassetto (cf11f523047a4cfab2edc51fbcf0b258).
Oltre al modelId
, ogni nodo può avere dei nodi-figli, che possono essere indicati come un array
JavaScript di oggetti nodo, utilizzando la proprietà children
del nodo-genitore. Nel nostro esempio,
i nodi Cintura, Guanto e Gilet sono figli del nodo Mr Worker, e i nodi Trapano e Stahlwille sono figli del nodo
Cintura, che a sua volta è figlio del nodo-root Mr Worker.
Altre proprietà dei nodi sono elencate di seguito:
(string)
Titolo del nodo, interamente opzionale e non utilizzato attualmente, salvo che per quelle rappresentazioni oggetto
JavaScript (JSON) che non ammettono l'uso dei commenti(object)
Oggetto JavaScript, interamente opzionale, da passare come parametro ad ogni evento che riguarda il nodo.
Questo parametro può essere utilizzato per integrare il navigatore con una qualsiasi applicazione, come per esempio una
piattaforma di eCommerce. Il contenuto dell'oggetto è interamente arbitrario e non ha una struttura definita, ma può
essere adattato a contenere qualsiasi tipo e numero di informazioni necessarie alla piattaforma integrante ad interagire
con la pagina o la piattaforma stessa in base alle iterazioni del visitatore con uno dei nodi.eventData
potrebbe essere strutturato come segue:
eventData: {
sku: "ABC-123",
name: "Chiave inglese",
productId: 12345,
add2CartUrl: "https://www.mysite.com/cart/add/12345/qty/2"
}
Quando l'utente interagirà con il nodo avente questa proprietà eventData
, l'intero oggetto verrà passato
come parametro al event listener, il quale potrà fare quello che necessario, come ad esempio visualizzare il nome
del prodotto selezionato, o aggiungerlo al carrello.
Il navigatore genera eventi custom, per permettere alle applicazioni che utilizzano il componente di integrare azioni che un utente esegui relativamente ai nodi dell'albero di navigazione.
Gli eventi disponibili sono elencati di seguito, e ciascun evento trasporta con se l'eventuale oggetto eventData
,
esattamente come passato al costruttore al momento dell'istanziazione del navigatore.
Gli eventi sono lanciati sull'elemento contenitore del navigatore, ma si propagano (bubble) fino all'oggetto document
,
se non intercettati e fermati prima. Questo significa che gli event handler possono essere agganciati sia ad uno specifico
navigatore, che genericamente al documento, il ché può fare la differenza nel caso si usino più di un navigatore per pagina.
Tutti gli eventi generati dal navigatore hanno in comune il fatto che sono basati sulla classe CustomEvent
,
e tutti pertanto forniscono la proprietà evt.detail
come parte dell'oggetto ricevuto come parametro dagli event
listener.
Per tutti gli eventi, l'oggetto evt.detail
contiene almeno le seguenti proprietà:
evt.detail.eventData
- (object) l'oggetto dati con struttura arbitraria associato al nodo coinvolto dall'evento,
come passato nella definizione della struttura di navigazione al costruttore del navigatore.evt.detail.isLeaf
- (boolean) indica se il nodo coinvolto dall'evento è un nodo-foglia (senza figli) o menoevt.detail.modelId
- (string) identificatore (embed ID) del modello Sketchfab corrispondente al nodo coinvolto dall'eventoevt.detail.nodeDepth
- (number) indica la profondità del sottoalbero relativo al nodo coinvolto dall'evento (quanti livelli di gerarchia il nodo presenta)evt.detail.nodeIndex
- (number) indice progressivo del nodo coinvolto dall'evento tra i suoi siblings, nel caso di nodi associati con annotazioni (ossia
tutti quelli che non sono il nodo root), questo è il numero rappresentato nell'annotazione meno uno (zero-based index), ed è sempre 0 per il nodo root.evt.detail.nodeLevel
- (number) livello del nodo coinvolto dall'evento, dove 0 rappresenta il livello root, 1 il livello dei figli di root, 2 il livello
dei figli dei figli di root, e così via.sfab:ready
sfab:node:loaded
sfab:node:ready
, il quale riceve gli stessi parametri
ma viene lanciato successivamente a questo evento.
sfab:node:ready
root
al caricamento iniziale del navigatore.
sfab:node:selected
sfab:node:loaded
e successivamente dall'evento sfab:node:ready
, tutti
corrispondente al nodo entrante destinazione della navigazione).
Per consistenza, gli eventi sfab:node:selected
, sfab:node:loaded
e sfab:node:ready
vengono generati dal navigatore anche quando, nei livelli successivi al
livello base (root), viene premuto il pulsante "Back": la navigazione, infatti, si sposta al nodo genitore
del nodo corrente, anche se in questi casi il modello Sketchfab corrispondente al nodo genitore (destinazione) è già
caricato e pronto.
const containerEl = document.getElementById('sfab-container');
containerEl.addEventListener('sfab:ready', function(evt) {
console.log('EVT sfab:ready', evt);
});
containerEl.addEventListener('sfab:node:loaded', function(evt) {
console.log('EVT sfab:node:loaded', evt);
});
containerEl.addEventListener('sfab:node:ready', function(evt) {
console.log('EVT sfab:node:ready', evt);
});
containerEl.addEventListener('sfab:node:selected', function(evt) {
console.log('EVT sfab:node:selected', evt);
if (evt.detail && evt.detail.hasOwnProperty('eventData')) {
const eventData = evt.detail.eventData || null;
if (eventData) {
if (eventData.hasOwnProperty('redirect') && eventData.redirect) {
document.location.href = eventData.redirect;
} else if (eventData.hasOwnProperty('productId') && eventData.productId) {
cartComponent.addProductToCart(eventData.productId, 1);
}
}
}
});
Qualora fosse necessario (ad esempio per specifiche esigenze di accessibilità), il modello dell'elemento iFrame utilizzato dal componente navigatore per ogni livello, può essere personalizzato.
Per cambiare il template, è necessario prima indicare un nuovo template, per esempio:
<template id="sfab-template-level">
<iframe src="" allow="autoplay; fullscreen; xr-spatial-tracking; accelerometer; gyroscope"
xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share
allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</template>
Una volta che il template è stato definito, lo si può impostare come template per il navigatore nel costruttore
SketchFabNav
, utilizzando il quarto parametro del costruttore:
<div id="sfab-container" data-role="sfab-container" tabindex="10"></div>
<script src="js/sketchfabnav.js"></script>
<script>
(function() {
const sketchFabNavSettings = {
// mr worker (cappello giallo)
modelId: 'cf11f523047a4cfab2edc51fbcf0b258',
children: [{
// 1. Belt
modelId: 'bdb0215c0eb14ad19759e84c9bf0c1ae',
children: [{
// 1.1. Drill
modelId: 'f00ddf74d1ad447c8ac7145dedfd3311'
}, {
// 1.2. Stahlwille
modelId: '21e86485c5cb4ba2ad69ea9fa2e92d3c'
}]
}, {
// 2. Guanto
modelId: '4156ccbe044a4c909c035a6a4bc8ac65'
}, {
// 3. Gilet
modelId: '2aaa2bba5a7e46c1a71c225357c6090a'
}]
};
new SketchFabNav(document, 'sfab-container', sketchFabNavSettings, 'sfab-template-level');
})();
</script>
In caso di personalizzazione del template, è necessario assicurarsi che l'elemento alla base del template sia sempre un
iframe
, e che l'attributo src
rimanga vuoto.
In caso di necessità (per esempio per questioni di accessibilità o traduzioni), il pulsante "Back" può essere personalizzato.
Per personalizzare il pulsante "Back" è sufficiente aggiungere il codice HTML del pulsante all'interno del contenitore del navigatore, sotto il placeholder per i livelli (in modo tale che il pulsante sia sovrapposto naturalmente ai livelli Sketchfab), per esempio:
<div id="sfab-container" data-role="sfab-container" tabindex="10">
<div data-role="sfab-levels"></div>
<button data-role="sfab-back" title="Torna alla schermata precedente">« Back</button>
</div>
È possibile aggiungere una schermata di "Caricamento in Corso" da essere utilizzata dal navigatore ogni volta che un livello richieda il caricamento di un nuovo modello Sketchfab.
Per aggiungere la schermata di caricamento, è sufficiente indicare il suo codice HTML all'interno del segnaposto navigatore, come da esempio quì sotto:
<div id="sfab-container" data-role="sfab-container" tabindex="10">
<div data-role="sfab-levels"></div>
<button data-role="sfab-back" title="Torna alla schermata precedente">« Back</button>
<div data-role="sfab-loading">
<div>
<img src="images/loading.svg" alt="Caricamento in corso" />
<small>Attendere, prego ...</small>
</div>
</div>
</div>
Nel caso questa funzionalità venga utilizzata, raccomandiamo di inserire la schermata di caricamento sotto sia al placeholder dei livelli, che al pulsante "Back", in modo che la schermata di caricamento copra naturalmente sia il pulsante che i livelli Sketchfab.
I parametri di configurazione di Sketchfab Viewer utilizzati di default dal componente navigatore sono i seguenti (tutti gli altri sono ai loro valori di default):
animation_autoplay
: 0
autostart
: 0
annotation_tooltip_visible
: 0
annotations_visible
: 1
dnt
: 1
preload
: 0
transparent
: 1
prevent_user_light_rotation
: 1
ui_animations
: 0
ui_annotations
: 0
ui_controls
: 0
ui_fullscreen
: 0
ui_general_controls
: 0
ui_help
: 0
ui_hint
: 0
ui_infos
: 0
ui_inspector
: 0
ui_loading
: 0
ui_settings
: 0
ui_start
: 0
ui_stop
: 0
ui_vr
: 0
ui_ar
: 0
ui_ar_help
: 0
ui_ar_qrcode
: 0
ui_watermark
: 0
orbit_constraint_pan
: 1
Qualora fosse necessario modificare questi valori, o passare altri parametri al costruttore di Sketchfab Viewer,
è possibile passare i valori desiderati al costruttore SketchFabNav
, utilizzando la proprietà settings
,
del nodo root nella definizione della struttura di navigazione ad albero.
Per esempio, nel caso si volesse attivare il tracking (modificando il valore dell'impostazione dnt
) ed
allo stesso tempo modificare la velocità di riproduzione delle animazioni (aggiungendo fps_speed
), è possibile
aggiungere la proprietà settings
al nodo root come segue (linee 25-28):
<div id="sfab-container" data-role="sfab-container" tabindex="10"></div>
<script src="js/sketchfabnav.js"></script>
<script>
(function() {
const sketchFabNavSettings = {
// mr worker (cappello giallo)
modelId: 'cf11f523047a4cfab2edc51fbcf0b258',
children: [{
// 1. Belt
modelId: 'bdb0215c0eb14ad19759e84c9bf0c1ae',
children: [{
// 1.1. Drill
modelId: 'f00ddf74d1ad447c8ac7145dedfd3311'
}, {
// 1.2. Stahlwille
modelId: '21e86485c5cb4ba2ad69ea9fa2e92d3c'
}]
}, {
// 2. Guanto
modelId: '4156ccbe044a4c909c035a6a4bc8ac65'
}, {
// 3. Gilet
modelId: '2aaa2bba5a7e46c1a71c225357c6090a'
}],
settings: {
dnt: 0, /* disattiva Do Not Track */
fps_speed: 10 /* default speed would be 25 fps, making it 10 fps */
}
};
new SketchFabNav(document, 'sfab-container', sketchFabNavSettings);
})();
</script>
Maggiori dettagli sulle proprietà disponibili si possono trovare nella documentazione di Sketchfab, al seguente indirizzo: https://sketchfab.com/developers/viewer/initialization
In questo esempio, dimostriamo le funzionalità di inizializzazione con settings personalizzate, utilizzo di eventi per reagire alla selezione di nodi di navigazione (mostrando un flyover con i dati del prodotto corrispondente al nodo, eccetto che per il nodo root), pulsante "Back" personalizzato e schermata di caricamento personalizzata. Inoltre, utilizziamo anche un template di livello (iframe) personalizzato.
Inoltre, questo esempio dimostra anche la possibilità di navigatori multipli all'interno della stessa (questa stessa) pagina.
<div id="sfab-container2" data-role="sfab-container" tabindex="10">
<div data-role="sfab-levels"></div>
<button data-role="sfab-back" title="Torna alla schermata precedente">« Back</button>
<div data-role="sfab-loading">
<div>
<img src="images/loading.svg?v=1.0.4" alt="Caricamento in corso" />
<small>Attendere, prego ...</small>
</div>
</div>
</div>
<div data-role="flyover">
<div data-role="flyover-content">
<dl>
<dt>SKU</dt>
<dd data-role="flyover-sku"></dd>
<dt>EAN</dt>
<dd data-role="flyover-ean"></dd>
<dt>Nome Prodotto</dt>
<dd data-role="flyover-name"></dd>
</dl>
</div>
</div>
<template id="sfab-template-level2">
<iframe src="" allow="autoplay; fullscreen; xr-spatial-tracking; accelerometer; gyroscope"
xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share
allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</template>
<script>
(function() {
const sketchFabNavSettings = {
// mr worker (cappello giallo)
modelId: 'cf11f523047a4cfab2edc51fbcf0b258',
eventData: {},
children: [{
// 1. Belt
modelId: 'bdb0215c0eb14ad19759e84c9bf0c1ae',
eventData: { id: 123, sku: '100206', ean: '4042146875780', name: 'KS TOOLS 100206 - Kit di utensili' },
children: [{
// 1.1. Drill
modelId: 'f00ddf74d1ad447c8ac7145dedfd3311',
eventData: { id: 124, sku: 'TOP DRILL R', ean: '8024482189468', name: 'GT LINE TOP DRILL R - TOP DRILL N - Porta trapano' }
}, {
// 1.2. Stahlwille
modelId: '21e86485c5cb4ba2ad69ea9fa2e92d3c',
eventData: { id: 125, sku: 'U03110001', ean: '8010239149090', name: 'USAG U03110001 - 311 N - Giratubi svedese chiave a pappagallo con ganasce a 45° sottili e diritte' }
}, {
// 1.13. Hammer
modelId: '14d2f44db97c4c0c9cd9d835b79c9fab',
eventData: { id: 126, sku: '200H.26', ean: '3148517496361', name: 'FACOM 200H.26 - Martello per meccanici modello francese' }
}]
}, {
// 2. Guanto
modelId: '4156ccbe044a4c909c035a6a4bc8ac65',
eventData: { id: 127, sku: '2870140397006', ean: '7330509896525', name: 'BLAKLADER 28701403970012 - Guanto da lavoro con touch Grigio antracite (confezione multipla)' },
}, {
// 3. Gilet
modelId: '2aaa2bba5a7e46c1a71c225357c6090a',
eventData: { id: 199, sku: 'FMST1-71181', ean: '3253561711817', name: 'STANLEY FMST1-71181 - Gilet multitasche FatMax®' },
}, {
// 4. Scarpe
modelId: 'b8faa38f3abc46458b9c016b05eb6c35',
eventData: { id: 200, sku: 'GO10054-38', ean: '8033546284377', name: 'U-POWER GO10054-39 - GO10054 - Scarpe antinfortunistiche alte Drop GTX S3 HRO HI CI WR SRC, nere' },
}],
settings: {
dnt: 0,
transparent: 1
}
};
function updateFlyover(eventData) {
const productId = eventData.hasOwnProperty('id') ? eventData.id : null;
const productSku = eventData.hasOwnProperty('sku') ? eventData.sku : null;
const productEan = eventData.hasOwnProperty('ean') ? eventData.ean : null;
const productName = eventData.hasOwnProperty('name') ? eventData.name : null;
const flyover = document.querySelector('[data-role="flyover"]');
if (flyover) {
if (productId) {
let element;
element = flyover.querySelector('[data-role="flyover-sku"]');
if (element) {
element.innerText = (productSku) ? productSku : ' ';
}
element = flyover.querySelector('[data-role="flyover-ean"]');
if (element) {
element.innerText = (productEan) ? productEan : ' ';
}
element = flyover.querySelector('[data-role="flyover-name"]');
if (element) {
element.innerText = (productName) ? productName : ' ';
}
flyover.classList.add('active');
} else {
flyover.classList.remove('active');
}
}
}
const containerEl2 = document.getElementById('sfab-container2');
containerEl2.addEventListener('sfab:node:selected', function(evt) {
if (evt.detail && evt.detail.hasOwnProperty('eventData')) {
const eventData = evt.detail.eventData || null;
if (eventData) {
updateFlyover(eventData);
}
}
});
const templateEl2 = document.getElementById('sfab-template-level2');
new SketchFabNav(document, containerEl2, sketchFabNavSettings, templateEl2);
})();
</script>
Tutto il codice inerente al navigatore è stato realizzato in "Plain JavaScript" e pertanto non ha librerie che possano rappresentare dipendenze (come ad esempio jQuery, PrototypeJs, Underscore, ecc). Ciò non significa che tali librerie non possano essere utilizzate, semplicemente che la loro presenza non influisce sul funzionamento del navigatore. Non vi sono conflitti conosciuti.
Il funzionamento del navigatore è subordinato al funzionamento di Sketchfab Viewer, pertanto i requisiti minimi di compatibilità del navigatore sono stati mantenuti gli stessi di Sketchfab Viewer.
Secondo la documentazione di Sketchfab, Sketchfab Viewer è compatibile con tutti i browser moderni, incluso:
Sempre secondo la documentazione di Sketchfab, non è supportato Internet Explorer. Su dispositivi mobili, il supporto comprende iOS 8+ e Android 4.0+. Sketchfab utilizza WebGL, pertanto il supporto di questa tecnologia da parte dei browser è anch'esso un requisito. Per maggiori dettagli, si prega di riferirsi alla documentazione Sketchfab ed il loro articolo sulla compatibilità disponibile al seguente indirizzo: https://help.sketchfab.com/hc/en-us/articles/203059088-Compatibility
Sono stati rilevati alcuni problemi di compatibilità su browser Google Chrome per Linux, ma tali problemi sono inerenti a Sketchfab Viewer e non al navigatore nello specifico, inoltre appaiono solo per alcuni dei modelli Sketchfab, mentre altri (inclusi quelli in questa guida) funzionano come dovrebbero.
Archivio di distribuzione: SketchFab Nav v1.0.4
Archivio sogenti: SketchFab Nav v1.0.4 (codice sorgente)