UNPKG

@thebigcrunch/sdk

Version:
273 lines (247 loc) 7.67 kB
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); };