Skip to content

Instantly share code, notes, and snippets.

@brianpeiris
Created August 28, 2019 21:00
Show Gist options
  • Save brianpeiris/2c15b1b4f828de241a1a5b7c2e47b0d3 to your computer and use it in GitHub Desktop.
Save brianpeiris/2c15b1b4f828de241a1a5b7c2e47b0d3 to your computer and use it in GitHub Desktop.
Hubs slides
(() => {
class Viewer {
constructor(slides) {
this.slides = slides;
this.currentIndex = 0;
const block = "https://poly.google.com/view/0LfGexYbqij";
const root = spawnMedia(AFRAME.scenes[0], { resize: false, src: block });
const title = spawnMedia(root, { resolve: false });
title.object3D.position.y = 2;
this.title = title;
const model = spawnMedia(root);
model.object3D.position.y = 1.5;
model.object3D.position.x = -1;
this.model = model;
const media = spawnMedia(root);
media.object3D.position.y = 1.5;
this.media = media;
const controller = spawnMedia(root, { resize: false, src: block });
controller.setAttribute("tags", { singleActionButton: true });
controller.object3D.position.y = 1;
controller.object3D.scale.setScalar(2);
let lastUpdate = Date.now();
controller.object3D.addEventListener("interact", () => {
if (Date.now() - lastUpdate > 1000) {
this.nextSlide();
lastUpdate = Date.now();
}
});
}
loadFirstSlide() {
this.currentIndex = 0;
this.loadCurrentSlide();
}
loadCurrentSlide() {
const currentSlide = this.slides[this.currentIndex];
this.title.setAttribute("media-loader", "src", renderText(currentSlide.title, 400, 100));
const slideModel = currentSlide.model;
this.model.setAttribute("media-loader", "src", slideModel.src);
if (slideModel.position) this.model.setAttribute("position", slideModel.position);
if (slideModel.rotation) {
this.model.object3D.rotation.y = slideModel.rotation;
} else {
this.model.object3D.rotation.y = 0;
}
this.media.setAttribute("media-loader", "src", currentSlide.media);
}
nextSlide() {
this.currentIndex = (this.currentIndex + 1) % this.slides.length;
this.loadCurrentSlide();
}
}
function spawnMedia(root, options) {
options = Object.assign(
{
position: null,
src: null,
resize: true,
resolve: true
},
options
);
const media = document.createElement("a-entity");
media.setAttribute("networked", { template: "#interactable-media" });
media.setAttribute("media-loader", {
resize: options.resize,
animate: false,
playSoundEffect: false,
src: options.src,
resolve: options.resolve
});
if (options.position) media.setAttribute("position", options.position);
root.append(media);
return media;
}
const renderText = (() => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
return (text, width, height) => {
canvas.width = width;
canvas.height = height;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
const lines = text.split("\n").map(line => line.trim());
for (let i = 0; i < lines.length; i++) {
ctx.font = "bold 40px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "black";
ctx.fillText(lines[i], canvas.width / 2, (lines.length > 1 ? 10 : canvas.height / 2) + i * 50);
}
return canvas.toDataURL();
};
})();
const deg45 = Math.PI / 4;
const slides = [
{
title: "Bulbasaur",
model: { src: "https://sketchfab.com/3d-models/bulbasaur-64815cda802746b8b1be2e2246db4b35", rotation: deg45 * 5 },
media: "https://www.youtube.com/watch?v=N9DVZRs4jx0"
},
{
title: "Charmander",
model: { src: "https://sketchfab.com/3d-models/charmander-b3ceb37f97ea47b0926f5a2099f210a6", rotation: deg45 },
media: "https://www.youtube.com/watch?v=UgcX7p0xArc"
},
{
title: "Squirtle",
model: { src: "https://sketchfab.com/3d-models/squirtle-18caed58804943d7a839dcbd44d21b80", rotation: deg45 },
media: "https://www.youtube.com/watch?v=__FYSw-PvOs"
}
];
const viewer = new Viewer(slides);
viewer.loadFirstSlide();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment