UNPKG

codehs-graphics

Version:

Helpers used to run graphics problems in the CodeHS editor.

233 lines (203 loc) 6.29 kB
'use strict'; var Thing = require('./thing.js'); var DEFAULT_WIDTH = 150; var DEFAULT_HEIGHT = (DEFAULT_WIDTH * 3) / 4; const WEBCAM_INDICATOR = 'WEBCAM'; /** * @constructor * @augments Thing * @param {string} filename - Filepath to the video */ function WebVideo(filename) { if (typeof filename !== 'string') { throw new TypeError( 'You must pass a string to <span class="code">' + "new WebVideo(filename)</span> that has the video's location." ); } Thing.call(this); var self = this; var vid = document.createElement('video'); this.width = DEFAULT_WIDTH; this.height = DEFAULT_HEIGHT; this.type = 'WebVideo'; this.isWebCam = filename === WEBCAM_INDICATOR; this.browserSupportsVideo = !!vid.canPlayType; if (this.browserSupportsVideo) { this.video = vid; if (!this.isWebCam) { this.video.src = filename; } else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices .getUserMedia({video: true}) .then(function(stream) { self.video.srcObject = stream; self.video.play(); }) .catch(function(error) { throw new Error('Web camera access was denied: ' + error); }); } else { throw new TypeError('Your browser does not support web camera access'); } this.filename = filename; this.video.autoplay = true; this.video.loop = false; // Treat cross origin URLs as same origin. Allows for videos from different // origins to be loaded and played, as long as that origin allows us to load // the given video resource. this.video.crossOrigin = 'anonymous'; } } WebVideo.WEBCAM = WEBCAM_INDICATOR; WebVideo.prototype = new Thing(); WebVideo.prototype.constructor = WebVideo; /** * Draws the WebVideo in the canvas. * * @param {CodeHSGraphics} __graphics__ - Instance of the __graphics__ module. */ WebVideo.prototype.draw = function(__graphics__) { if (this.browserSupportsVideo) { var context = __graphics__.getContext('2d'); // Scale and translate // X scale, X scew, Y scew, Y scale, X position, Y position context.setTransform(1, 0, 0, 1, this.x + this.width / 2, this.y + this.height / 2); context.rotate(this.rotation); context.drawImage(this.video, -this.width / 2, -this.height / 2, this.width, this.height); // Reset transformation matrix // X scale, X scew, Y scew, Y scale, X position, Y position context.setTransform(1, 0, 0, 1, 0, 0); } }; /** * Checks if the passed point is contained in the WebVideo. * * @param {number} x - The x coordinate of the point being tested. * @param {number} y - The y coordinate of the point being tested. * @returns {boolean} Whether the passed point is contained in the WebVideo. */ WebVideo.prototype.containsPoint = function(x, y) { if (this.browserSupportsVideo) { return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height; } return false; }; /** * Gets the width of the WebVideo. * * @returns {number} Width of the WebVideo. */ WebVideo.prototype.getWidth = function() { return this.width; }; /** * Gets the height of the WebVideo. * * @returns {number} Height of the WebVideo. */ WebVideo.prototype.getHeight = function() { return this.height; }; /** * Sets the size of the WebVideo. * * @param {number} width - The desired width of the resulting WebVideo. * @param {number} height - The desired height of the resulting WebVideo. */ WebVideo.prototype.setSize = function(width, height) { this.width = width; this.height = height; }; /** * Sets whether the WebVideo should start playing automatically once loaded. * * @param {boolean} autoplay - True/false whether the video should start playing automatically. */ WebVideo.prototype.setAutoplay = function(autoplay) { if (this.browserSupportsVideo) { this.video.autoplay = autoplay; } }; /** * Sets whether the WebVideo should loop and play again once finished. * * @param {boolean} loop - True/false whether the video should loop. */ WebVideo.prototype.setLoop = function(loop) { if (this.browserSupportsVideo) { this.video.loop = loop; } }; /** * Sets whether the WebVideo is muted or not. * * @param {boolean} muted - True/false whether the video should be muted. */ WebVideo.prototype.setMuted = function(muted) { if (this.browserSupportsVideo) { this.video.muted = muted; } }; /** * Starts playing the WebVideo. */ WebVideo.prototype.play = function() { if (this.browserSupportsVideo) { this.video.play(); } }; /** * Pauses the WebVideo. */ WebVideo.prototype.pause = function() { if (this.browserSupportsVideo) { this.video.pause(); } }; /** * Stops the WebVideo. */ WebVideo.prototype.stop = function() { if (this.browserSupportsVideo) { this.video.pause(); this.video.currentTime = 0; if (this.isWebCam && this.video.srcObject) { this.video.srcObject.getTracks().forEach(function(track) { track.stop(); }); } } }; /** * Returns whether the WebVideo is currently playing. * * @returns {boolean} True if the video is playing, false if it is not. */ WebVideo.prototype.isPlaying = function() { if (this.browserSupportsVideo) { return !(this.video.paused || this.video.ended); } return false; }; /** * Returns whether the WebVideo is currently muted. * * @returns {boolean} True if the video is muted, false if it is not. */ WebVideo.prototype.isMuted = function() { if (this.browserSupportsVideo) { return this.video.muted; } return false; }; /** * Defines a function to call once the video has loaded enough and is ready to play. * @param {Function} fn A function to call when the video is ready to play. */ WebVideo.prototype.onReadyToPlay = function(fn) { if (this.browserSupportsVideo) { this.video.oncanplay = fn; } }; module.exports = WebVideo;