@thebigcrunch/sdk
Version:
The big crunch SDK library
273 lines (247 loc) • 7.67 kB
JavaScript
import {
getSpaceImageUrl,
getSpaceVizzyUrl,
getSpaceVideoUrl,
getSpaceAudioUrl
} from "../urlcreator";
import {
getFontProperties,
getFontStyleFromProperties,
drawText
} from "./textrenderer";
import {
getOptions,
findDrawingAreaCanvas,
findCentredDrawingArea,
canvasSize,
setElementToSpaceRatio,
setFullHeightWidth,
createElementForSpace,
setElementToParentSize
} from "./common";
import { contentTypes, types, isAudio, isVideo } from "../constants";
/**
* Renders the image to the canvas which is pixel perfect representation of the space in The Big Crunch
* @param space the space that is an image from TBC.crunch
* @param ctx a 2d canvas context
*/
export const renderImageToCanvas = function renderImageToCanvas(
space,
ctx,
opts
) {
const options = getOptions(opts);
// Get size
const { width, height } = findDrawingAreaCanvas(space, ctx, options);
// Draw Image
const image = new Image();
image.addEventListener("load", () => {
ctx.drawImage(image, 0, 0, width, height);
});
image.src = getSpaceImageUrl(space);
};
/**
* Renders the text to the canvas which is pixel perfect representation of the space in The Big Crunch
* @param {*} space the space that is an image from TBC.crunch
* @param {*} ctx a 2d canvas context
*/
export const renderTextToElement = function renderTextToElement(
space,
element
) {
const span = document.createElement("span");
const properties = getFontProperties(space);
const size = 25; // TODO sort this out.
span.style.color = properties.color;
span.style.fontWeight = properties["font-weight"];
span.style.font = getFontStyleFromProperties(properties, size);
span.textContent = space.value;
element.append(span);
};
/**
* Renders text to the canvas the same as The Big Crunch Universe
* @param {*} space
* @param {*} ctx
*/
export const renderTextToCanvas = function renderTextToCanvas(
space,
ctx,
opts
) {
const options = getOptions(opts);
// Get size
const { width, height } = findDrawingAreaCanvas(space, ctx, options);
const canvas = drawText(
space.value,
width,
height,
space.properties.content
);
if (options.fit === "stretch") {
const { canvasWidth, canvasHeight } = canvasSize(ctx);
// Stretch the text over the entire canvas
ctx.drawImage(canvas, 0, 0, canvasWidth, canvasHeight);
} else {
// Centre the text in the canvas. This is for cases where the text doesn't fit the canvas completely
const { x, y } = findCentredDrawingArea(width, height, ctx);
ctx.drawImage(canvas, x, y, width, height);
}
};
/**
* Renders the visualisation into a div which is pixel perfect representation of the space in The Big Crunch
* @param space the space that is passed from the callback of TBC.crunch
* @param element the container to place the visualisation IFrame in. A raw dom element
*/
export const renderVisualisationToElement = function renderVisualisationToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const visualisation = document.createElement("iframe");
let params = "";
if (opts.odo) {
params = "&odo=true";
}
visualisation.src =
getSpaceVizzyUrl(space.encodedUuid) + window.location.search + params;
visualisation.sandbox =
"allow-same-origin allow-scripts allow-popups allow-forms";
setFullHeightWidth(visualisation);
if (options.fit === "cellaspect") {
setElementToSpaceRatio(space, element, options);
}
element.append(visualisation);
return visualisation;
};
/**
* Render a image space to an element
* @param space
* @param element
* @param options
*/
export const renderImageToElement = function renderImageToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const img = document.createElement("img");
setFullHeightWidth(img);
img.src = getSpaceImageUrl(space);
if (options.fit === "cellaspect") {
setElementToSpaceRatio(space, element, options);
}
element.append(img);
return img;
};
export const renderYoutubeVideoToElement = function renderYoutubeVideoToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const videoId = space.value;
const iframe = document.createElement("iframe");
iframe.src = `https://www.youtube.com/embed/${videoId}`;
iframe.frameBorder = 0;
setFullHeightWidth(iframe);
if (options.fit === "cellaspect") {
setElementToSpaceRatio(space, element, options);
}
element.append(iframe);
return iframe;
};
export const renderVideoToElement = function renderVideoToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const video = document.createElement("video");
video.src = `${getSpaceVideoUrl(space)}`;
video.controls = "controls";
video.type = space.contentType;
video.autoplay = "autoplay";
video.loop = "loop";
setFullHeightWidth(video);
if (options.fit === "cellaspect") {
setElementToSpaceRatio(space, element, options);
}
element.append(video);
return video;
};
export const renderAudioToElement = function renderAudioToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const audio = document.createElement("audio");
audio.src = `${getSpaceAudioUrl(space)}`;
audio.controls = "controls";
audio.type = space.contentType;
audio.autoplay = "autoplay";
audio.loop = "loop";
setFullHeightWidth(audio);
if (options.fit === "cellaspect") {
setElementToSpaceRatio(space, element, options);
}
element.append(audio);
return audio;
};
export const renderJsonToElement = function renderJsonToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const div = document.createElement("div");
setFullHeightWidth(div);
if (options.fit === "cellaspect") {
setElementToSpaceRatio(space, element, options);
}
element.append(div);
return div;
};
export const renderSpaceIntoElement = function renderSpaceIntoElement(
space,
element,
options
) {
if (space.type === types.visualisation) {
renderVisualisationToElement(space, element, options);
} else if (space.contentType === contentTypes.textText) {
renderTextToCanvas(space, element.getContext("2d"), options);
} else if (space.contentType === contentTypes.videoYoutube) {
renderYoutubeVideoToElement(space, element, options);
} else if (
space.contentType &&
space.contentType.includes(contentTypes.imageImage)
) {
renderImageToElement(space, element, options);
} else if (space.contentType && isVideo(space.contentType)) {
renderVideoToElement(space, element, options);
} else if (space.contentType && isAudio(space.contentType)) {
renderAudioToElement(space, element, options);
} else if (space.contentType === contentTypes.json) {
renderJsonToElement(space, element, options);
}
};
/**
*
* @param {*} space
* @param {*} element
* @param {*} opts
*/
export const renderCellToElement = function renderCellToElement(
space,
element,
opts
) {
const options = getOptions(opts);
const elementToDrawIn = createElementForSpace(space);
element.appendChild(elementToDrawIn);
setElementToParentSize(elementToDrawIn, element, options);
renderSpaceIntoElement(space, elementToDrawIn, options);
};