Skip to content

Instantly share code, notes, and snippets.

@mathdoodle
Created November 2, 2016 18:31
Show Gist options
  • Save mathdoodle/3d4ec7d45e050f3d832594e8b80e54ca to your computer and use it in GitHub Desktop.
Save mathdoodle/3d4ec7d45e050f3d832594e8b80e54ca to your computer and use it in GitHub Desktop.
Motion and Kinematics
table {
background: #FFFFFF;
border: solid 1px #DDDDDD;
margin-bottom: 1.25rem;
table-layout: auto; }
table caption {
background: transparent;
color: #222222;
font-size: 1rem;
font-weight: bold; }
table thead {
background: #F5F5F5; }
table thead tr th,
table thead tr td {
color: #222222;
font-size: 0.875rem;
font-weight: bold;
padding: 0.5rem 0.625rem 0.625rem; }
table tfoot {
background: #F5F5F5; }
table tfoot tr th,
table tfoot tr td {
color: #222222;
font-size: 0.875rem;
font-weight: bold;
padding: 0.5rem 0.625rem 0.625rem; }
table tr th,
table tr td {
color: #222222;
font-size: 0.875rem;
padding: 0.5625rem 0.625rem;
text-align: left; }
table tr.even, table tr.alt, table tr:nth-of-type(even) {
background: #F9F9F9; }
table thead tr th,
table tfoot tr th,
table tfoot tr td,
table tbody tr th,
table tbody tr td,
table tr td {
display: table-cell;
line-height: 1.125rem; }

Motion and Kinematics

Student Learning Objectives

  • To differentiate between position, velocity, and acceleration.
  • To identify velocity and acceleration vectors (direction and relative magnitude) at different points in an object's motion.
  • To recognize the relationship between $\vec{v}$ and $\vec{a}$ when an object is speeding up, slowing down, curving, or at a turning point.
  • To interpret kinematic graphs and to relate graphs of position, velocity and acceleration to each other.
  • To translate kinematic information between verbal, pictorial, graphical, algebraic, and computational representations.
  • To begin a robust problem solving strategy.
  • To learn the basic ideas of calculus (differentiation and integration) and to use these ideas both symbolically and graphically.
  • To understand freee-fall motion, both linear and in two dimensions.
  • To understand the basic ideas of circular motion.
  • To solve quantitative kinematics problems and to interpret the results.

Motion Diagram

A motion diagram is an ordered series of dots (representing the object as a particle) showing the position of the particle at several points in time.

<!doctype html>
<html>
<head>
<!-- STYLES-MARKER -->
<style>
/* STYLE-MARKER */
</style>
<script src="https://jspm.io/system.js"></script>
<!-- SCRIPTS-MARKER -->
</head>
<body>
<canvas id='canvas3D'></canvas>
<canvas id='canvas2D'></canvas>
<div id='error'></div>
<script>
// CODE-MARKER
</script>
<script>
System.import('./index.js')
</script>
</body>
</html>
import {domReady, requestFrame} from './visual'
import {meter, kilogram, second, newton} from './units'
import {createArrow, Arrow} from './visual'
import {createBox, Box} from './visual'
import {createGridXY, createGridZX, Grid} from './visual'
import {sphere, Sphere} from './visual'
import {color} from './visual'
import {curve} from './visual'
import {World} from './visual'
const i = EIGHT.Vector3.e1()
const j = EIGHT.Vector3.e2()
const k = EIGHT.Vector3.e3()
/**
* A composite containing a camera, the canvas, a scene, etc.
*/
let world: World
/**
* A graphical arrow that will be used to visualize all vectors.
* This is done by moving it around (translation), by changing its color,
* and by changing the vector property that it is model that it represents.
*/
let arrow: Arrow
/**
* A grid in the xy-plane.
*/
let gridXY: Grid
/**
* A grid in the zx-plane.
*/
let gridZX: Grid
/**
* Vector A
*/
const A = 1.0 * j
/**
* Vector B
*/
const B = 1.2 * i + 0.4 * j + 0.0 * k
/**
* Vector C, a random vector.
*/
const C = Math.random() * i + Math.random() * j + Math.random() * k
/**
* Vector D, a random vector.
*/
const D = Math.random() * i + Math.random() * j + Math.random() * k
/*
const gui = new dat.GUI()
const folderA = gui.addFolder("A (vector)")
folderA.add(A, 'x', -2, +2)
folderA.add(A, 'y', -2, +2)
folderA.add(A, 'z', -2, +2)
folderA.open()
const folderB = gui.addFolder("B (vector)")
folderB.add(B, 'x', -2, +2)
folderB.add(B, 'y', -2, +2)
folderB.add(B, 'z', -2, +2)
folderB.open()
*/
/**
* The initialization function is called once, when the DOM has been loaded.
*/
function init(): void {
world = new World()
// world.scaleFactor = meter
// world.camera.eye = 12 * world.scaleFactor * k
world.camera.eye = 6 * k
arrow = createArrow(world)
gridXY = createGridXY(world)
gridZX = createGridZX(world)
}
/**
* The update function is called repeatedly, for each animation frame.
*/
function update() {
/**
* A shortcut to the origin defined on our World.
*/
const origin = world.origin
// Draw the vector A and label it.
arrow.model = A
arrow.label = "A"
arrow.position = origin
arrow.color = color.red
arrow.draw()
// Draw the grid in the XY plane to get a sense of the magnitude and direction of the vectors.
// gridXY.draw()
// Draw the grid normal to A to avoid becoming disorientated!
gridZX.draw()
// Label the origin.
world.drawText("origin", origin)
}
/**
* The animation function is called repeatedly, as a callback for the browser.
*/
function animate() {
world.clear()
update()
requestFrame(animate)
}
/**
* When the DOM has been loaded, initialize this program.
* Then request a frame to get the animation going.
*/
domReady(function() {
init()
requestFrame(animate)
})
{
"description": "Motion and Kinematics",
"dependencies": {
"davinci-eight": "2.319.0",
"davinci-units": "1.5.3",
"DomReady": "1.0.0",
"jquery": "2.1.4",
"stats.js": "0.16.0",
"dat-gui": "0.5.0"
},
"operatorOverloading": true,
"name": "copy-of-copy-of-a-ball-in-a-box-with-units",
"version": "0.1.0",
"keywords": [
"visual",
"UNITS",
"G3"
]
}
body {
margin: 0;
overflow: hidden;
font-family: "Arial";
}
#canvas3D {
position: absolute;
left: 0px;
top: 0px;
z-index: 0;
width: 500px;
height: 500px;
}
#canvas2D {
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
width: 500px;
height: 500px;
/**
* Allow events to go to the other elements
*/
pointer-events: none;
}
#error {
position: absolute;
left: 10px;
top: 10px;
z-index: 20;
}
export const unitless = UNITS.G3.one
export const i = UNITS.G3.e1
export const j = UNITS.G3.e2
export const k = UNITS.G3.e3
export const meter = UNITS.G3.meter
export const kilogram = UNITS.G3.kilogram
export const second = UNITS.G3.second
export const newton = kilogram * meter / (second * second)
export const coulomb = UNITS.G3.coulomb
/**
*
*/
export default class Vector {
constructor(x: number, y: number, z: number, uom: UNITS.Unit) {
}
}
import {meter, kilogram, second, unitless, newton, coulomb} from './units';
// Change the lables used for the basis to i, j, k.
// These lables were borrowed from Hamilton's quaternions.
UNITS.G3.BASIS_LABELS = UNITS.G3.BASIS_LABELS_HAMILTON
/////////////////////////////////////////////////////////////////////////////
// Lighting
/**
* Ambient Lighting for the World.
*/
const ambLight = new EIGHT.AmbientLight(EIGHT.Color.white.scale(0.4))
/**
* Directional Lighting for the World.
*/
const dirLight = new EIGHT.DirectionalLight()
/////////////////////////////////////////////////////////////////////////////
// Standard Colors
/**
* The standard colors.
*/
export const color = {
red: EIGHT.Color.red,
green: EIGHT.Color.green,
blue: EIGHT.Color.blue,
yellow: EIGHT.Color.yellow,
magenta: EIGHT.Color.magenta,
cyan: EIGHT.Color.cyan,
orange: EIGHT.Color.fromRGB(1, 102 / 255, 0),
black: EIGHT.Color.black,
white: EIGHT.Color.white
}
/////////////////////////////////////////////////////////////////////////////
// Physical Constants
/**
*
*/
export const ε0 = 8.854E-12 * (coulomb * coulomb) / (meter * meter * newton)
/////////////////////////////////////////////////////////////////////////////
// Validation
/**
* Determines whether a multivector is admissable as a vector.
*/
function isVector(mv: EIGHT.GeometricE3): boolean {
if (mv.a !== 0 || mv.b !== 0 || mv.yz !== 0 || mv.zx !== 0 || mv.xy !== 0) {
return false;
}
else {
return true;
}
}
/**
* Determines whether a multivector is admissable as a scalar.
*/
function isScalar(mv: EIGHT.GeometricE3): boolean {
if (mv.x !== 0 || mv.y !== 0 || mv.z !== 0 || mv.yz !== 0 || mv.zx !== 0 || mv.xy !== 0 || mv.b !== 0) {
return false;
}
else {
return true;
}
}
/**
* A camera is a frame of reference from which the scene is viewed.
*/
export interface Camera {
/**
* The position of the camera, a position vector, measured in meters.
*/
eye: EIGHT.Vector3;
/**
* The point that the camera is looking at, a position vector, measured in meters.
*/
look: UNITS.G3;
/**
* The desired up direction, a dimensionless vector.
*/
up: UNITS.G3;
}
/**
* A ready-to-go composite for EIGHT animations.
*/
export class World {
/**
* The scale factor for converting world units to dimensionless units.
*/
public scaleFactor: UNITS.G3 = meter;
/**
* The frame of reference from which the world is viewed.
*/
public camera: Camera;
public engine:EIGHT.Engine;
public scene: EIGHT.Scene;
public ambients: EIGHT.Facet[] = [];
private trackball:EIGHT.TrackballControls;
private dimlessCamera: EIGHT.PerspectiveCamera;
public framecounter: number = 0;
public overlay: EIGHT.Diagram3D;
constructor() {
// Notice that the canvas is "burned in".
this.engine = new EIGHT.Engine('canvas3D')
.clearColor(0.2, 0.2, 0.2, 1.0)
.enable(EIGHT.Capability.DEPTH_TEST)
// .enable(EIGHT.Capability.BLEND)
// .blendFunc(EIGHT.BlendingFactorSrc.SRC_ALPHA, EIGHT.BlendingFactorDest.ONE);
this.scene = new EIGHT.Scene(this.engine)
this.dimlessCamera = new EIGHT.PerspectiveCamera()
this.dimlessCamera.eye.x = 0
this.dimlessCamera.eye.y = 0
this.dimlessCamera.eye.z = 3
this.ambients.push(this.dimlessCamera)
this.camera = worldCamera(this, this.dimlessCamera)
this.ambients.push(ambLight)
this.ambients.push(dirLight)
this.trackball = new EIGHT.TrackballControls(this.dimlessCamera, window)
// Workaround because Trackball no longer supports context menu for panning.
this.trackball.noPan = true
this.trackball.subscribe(this.engine.canvas)
this.overlay = new EIGHT.Diagram3D('canvas2D', this.dimlessCamera)
windowResize(this.engine, this.overlay, this.dimlessCamera).resize()
}
/**
* The underlying HTML5 Canvas.
*/
get canvas(): HTMLCanvasElement {
return this.engine.canvas;
}
/**
* The origin is fixed to be zero.
*/
get origin(): EIGHT.Vector3 {
return EIGHT.Vector3.e3().scale(0)
// return 0 * this.scaleFactor
}
/**
* Adds a drawable object to the world.
*/
add(drawable: EIGHT.Renderable): void {
if (drawable){
this.scene.add(drawable)
}
else {
// Throw Error
}
}
/**
* Clears the WebGL canvas and keeps the directional light pointing in the camera direction.
*/
clear(): void {
this.engine.clear()
this.overlay.clear()
this.trackball.update()
dirLight.direction.copy(this.dimlessCamera.look).sub(this.dimlessCamera.eye)
}
/**
* Draws the objects that have been added to the world.
*/
draw(): void {
this.scene.draw(this.ambients)
}
drawText(text: string, X: EIGHT.Vector3): void {
const where = {x: 0, y: 0, z: 0}
// scale(text, X, this.scaleFactor, where)
this.overlay.fillText(text, X)
}
}
/**
* Divides the measure by the scaleFactor to produce a dimensionless quantity.
*/
function scale(name: string, measure: UNITS.G3, scaleFactor: UNITS.G3, out: EIGHT.VectorE3): void {
if (!isScalar(scaleFactor)) {
throw new Error(`scaleFactor must be a scalar. scale(${name}, ${measure}, ${scaleFactor})`)
}
// We are expecting the result of scaling to produce a dimensionless quantity.
const dimless = measure / scaleFactor;
const uom = dimless.uom
if (!uom || uom.isOne()) {
out.x = dimless.x
out.y = dimless.y
out.z = dimless.z
// return EIGHT.Geometric3.copy(dimless)
}
else {
throw new Error(`Units of ${name}, ${scaleFactor}, is not consistent with units of quantity, ${measure}.`)
}
}
function scaleToNumber(name: string, measure: UNITS.G3, scaleFactor: UNITS.G3): number {
if (!isScalar(scaleFactor)) {
throw new Error(`scaleFactor must be a scalar. scale(${name}, ${measure}, ${scaleFactor})`)
}
// We are expecting the result of scaling to produce a dimensionless quantity.
const dimless = measure / scaleFactor;
const uom = dimless.uom
if (!uom || uom.isOne()) {
return dimless.a
}
else {
throw new Error(`Units of ${name}, ${scaleFactor}, is not consistent with units of quantity, ${measure}.`)
}
}
//////////////////////////////////////////////////////////////////////////////
/**
* A type that is useful for representing vectors.
*/
export class Arrow {
private _scaleFactor: UNITS.G3 = meter;
private _label: string;
private inner: EIGHT.Arrow;
constructor(private world: World) {
this.inner = new EIGHT.Arrow()
world.add(this.inner)
}
get color() {
return this.inner.color;
}
set color(color: EIGHT.Color) {
this.inner.color = color;
}
get label() {
return this._label;
}
set label(value: string) {
if (typeof value === 'string') {
this._label = value
}
else {
throw new Error(`Arrow.label property must be a string.`);
}
}
get scaleFactor() {
return this._scaleFactor;
}
set scaleFactor(value: UNITS.G3) {
if (isScalar(value)) {
this._scaleFactor = value;
}
else {
throw new Error(`Arrow.scaleFactor property must be a scalar.`);
}
}
get model() {
return EIGHT.Vector3.copy(this.inner.h)
// return UNITS.G3.copy(this.inner.h).mul(this.scaleFactor)
}
set model(value: EIGHT.Vector3) {
this.inner.h.copyVector(value)
/*
if (isVector(value)) {
scale('axis', value, this.scaleFactor, this.inner.h)
}
else {
throw new Error(`Arrow.axis property must be a vector.`);
}
*/
}
get position() {
return EIGHT.Vector3.copy(this.inner.X)
// return UNITS.G3.copy(this.inner.X).mul(this.world.scaleFactor);
}
set position(value: EIGHT.Vector3) {
this.inner.X.copyVector(value)
/*
if (isVector(value)) {
scale('pos', value, this.world.scaleFactor, this.inner.X)
}
else {
throw new Error(`Arrow.pos property must be a vector.`);
}
*/
}
draw() {
this.inner.render(this.world.ambients)
if (typeof this._label === 'string' && this._label.length > 0) {
this.world.drawText(this._label, this.position + (this.model / 2))
// this.world.drawText(this._label, this.position + (this.model / 2) * (this.world.scaleFactor / this.scaleFactor))
}
}
}
/**
* Constructor function for an Arrow.
*/
export function createArrow(world: World, options: {scaleFactor?: UNITS.G3; color?: EIGHT.Color} = {}): Arrow {
const that = new Arrow(world)
if (options.scaleFactor) {
if (options.scaleFactor instanceof UNITS.G3) {
that.scaleFactor = options.scaleFactor;
}
else {
throw new Error("pos option must have type UNITS.G3");
}
}
if (options.color) {
if (options.color instanceof EIGHT.Color) {
that.color = options.color;
}
else {
throw new Error("color property must have type EIGHT.Color");
}
}
return that;
}
/**
*
*/
export class Box {
public scaleFactor: UNITS.G3 = meter;
private inner: EIGHT.Box;
constructor(private world: World) {
this.inner = new EIGHT.Box({k: 1})
this.scaleFactor = world.scaleFactor
world.add(this.inner)
}
get color() {
return this.inner.color;
}
set color(color: EIGHT.Color) {
this.inner.color = color;
}
get width() {
return UNITS.G3.scalar(this.inner.width, this.scaleFactor.uom)
}
set width(value: UNITS.G3) {
if (isScalar(value)) {
this.inner.width = scaleToNumber('width', value, this.scaleFactor)
}
else {
throw new Error(`Box.width property must be a scalar.`);
}
}
get height() {
return UNITS.G3.scalar(this.inner.height, this.scaleFactor.uom)
}
set height(value: UNITS.G3) {
if (isScalar(value)) {
this.inner.height = scaleToNumber('height', value, this.scaleFactor)
}
else {
throw new Error(`Box.height property must be a scalar.`);
}
}
get depth() {
return UNITS.G3.scalar(this.inner.depth, this.scaleFactor.uom)
}
set depth(value: UNITS.G3) {
if (isScalar(value)) {
this.inner.depth = scaleToNumber('depth', value, this.scaleFactor)
}
else {
throw new Error(`Box.depth property must be a scalar.`);
}
}
get pos() {
return UNITS.G3.copy(this.inner.X).mul(this.world.scaleFactor);
}
set pos(value: UNITS.G3) {
if (isVector(value)) {
scale('X', value, this.world.scaleFactor, this.inner.X)
}
else {
throw new Error(`Box.pos property must be a vector.`);
}
}
get visible() {
return this.inner.visible
}
set visible(value: boolean) {
this.inner.visible = false
}
draw() {
this.inner.render(this.world.ambients)
}
}
/**
* Constructor function for a Box.
*/
export function createBox(world: World, options: {pos?: UNITS.G3; color?: EIGHT.Color} = {}): Box {
if (world) {
const that = new Box(world);
if (options.pos) {
if (options.pos instanceof UNITS.G3) {
that.pos = options.pos;
}
else {
throw new Error("pos option must have type UNITS.G3");
}
}
if (options.color) {
if (options.color instanceof EIGHT.Color) {
that.color = options.color;
}
else {
throw new Error("color property must have type EIGHT.Color");
}
}
return that;
}
else {
throw new Error("World has not yet been initialized.")
}
}
/**
* TODO
*/
export class Cylinder {
private inner: EIGHT.Cylinder;
public scaleFactor: UNITS.G3 = meter;
constructor(private world: World) {
this.inner = new EIGHT.Cylinder();
world.add(this.inner)
}
get color() {
return this.inner.color;
}
set color(color: EIGHT.Color) {
this.inner.color = color;
}
get length() {
return UNITS.G3.copy(this.inner.length, void 0).mul(this.scaleFactor);
}
set length(length: UNITS.G3) {
scale('length', length, this.scaleFactor, this.inner.length)
}
get radius() {
return UNITS.G3.copy(this.inner.radius, void 0).mul(this.scaleFactor);
}
set radius(radius: UNITS.G3) {
scale('radius', radius, this.scaleFactor, this.inner.radius)
}
get axis() {
return UNITS.G3.copy(this.inner.axis, void 0)
}
set axis(axis: UNITS.G3) {
scale('axis', axis, unitless, this.inner.axis)
}
get transparent() {
return this.inner.transparent;
}
set transparent(transparent: boolean) {
this.inner.transparent = transparent;
}
get X() {
return UNITS.G3.copy(this.inner.X, void 0).mul(this.world.scaleFactor);
}
set X(X: UNITS.G3) {
scale('X', X, this.world.scaleFactor, this.inner.X)
}
}
/**
*
*/
export class Grid {
constructor(private world: World, private inner: EIGHT.Grid) {
world.add(inner)
}
get color() {
return this.inner.color;
}
set color(color: EIGHT.Color) {
this.inner.color = color;
}
draw() {
this.inner.render(this.world.ambients)
}
}
export function createGridXY(world: World) {
const that = new Grid(world, new EIGHT.GridXY())
return that;
}
export function createGridZX(world: World) {
const that = new Grid(world, new EIGHT.GridZX())
return that;
}
/**
*
*/
export class Sphere {
public scaleFactor: UNITS.G3 = meter;
public trail: Curve;
private inner: EIGHT.Sphere;
private _velocity: UNITS.G3 = 0 * meter / second;
constructor(private world: World) {
this.inner = new EIGHT.Sphere()
this.scaleFactor = world.scaleFactor;
this.inner.transparent = false
this.inner.opacity = 1
world.add(this.inner)
}
get color() {
return this.inner.color;
}
set color(color: EIGHT.Color) {
this.inner.color = color;
}
get radius() {
return UNITS.G3.scalar(this.inner.radius, this.scaleFactor.uom)
}
set radius(value: UNITS.G3) {
this.inner.radius = scaleToNumber('radius', value, this.scaleFactor)
}
get velocity() {
return this._velocity;
}
set velocity(value: UNITS.G3) {
if (isVector(value)) {
this._velocity = value;
}
else {
throw new Error(`Sphere.velocity property must be a vector.`);
}
}
get pos() {
return UNITS.G3.copy(this.inner.X).mul(this.world.scaleFactor);
}
set pos(value: UNITS.G3) {
if (isVector(value)) {
scale('X', value, this.world.scaleFactor, this.inner.X)
}
else {
throw new Error(`Sphere.pos property must be a vector.`);
}
}
}
/**
* Constructor function for a Sphere.
*/
export function sphere(world: World, options: {pos?: UNITS.G3; radius?: UNITS.G3; color?: EIGHT.Color} = {}): Sphere {
if (world) {
const that = new Sphere(world);
if (options.pos) {
if (options.pos instanceof UNITS.G3) {
that.pos = options.pos;
}
else {
throw new Error("pos option must have type UNITS.G3");
}
}
if (options.radius) {
if (options.radius instanceof UNITS.G3) {
that.radius = options.radius;
}
else {
throw new Error("radius option must have type UNITS.G3");
}
}
if (options.color) {
if (options.color instanceof EIGHT.Color) {
that.color = options.color;
}
else {
throw new Error("color option must have type EIGHT.Color");
}
}
return that;
}
else {
throw new Error("World has not yet been initialized.")
}
}
export interface Curve {
append(point: UNITS.G3): void
}
/**
*
*/
export function curve(world: World, options: {color?: EIGHT.Color} = {}): Curve {
const track = new EIGHT.Track({engine: world.engine, color: options.color})
world.scene.add(track)
const that: Curve = {
append(point: UNITS.G3): void {
track.addPoint(point)
}
}
return that;
}
///////////////////////////////////////////////////////////////////////
/**
* Wrapper object for the PerspectiveCamera so that the eye, look (vector)
* properties use the units of the World (usually meters).
*/
function worldCamera(world: World, camera: EIGHT.PerspectiveCamera): Camera {
const that: Camera = {
get eye() {
return EIGHT.Vector3.copy(camera.eye)
// return UNITS.G3.copy(camera.eye).mul(world.scaleFactor);
},
set eye(value: EIGHT.Vector3) {
camera.eye.copyVector(value)
/*
if (isVector(value)) {
scale('eye', value, world.scaleFactor, camera.eye)
}
else {
throw new Error(`Camera.eye property must be a vector.`);
}
*/
},
get look() {
return UNITS.G3.copy(camera.look).mul(world.scaleFactor);
},
set look(value: UNITS.G3) {
if (isVector(value)) {
scale('look', value, world.scaleFactor, camera.look)
}
else {
throw new Error(`Camera.look property must be a vector.`);
}
},
get up() {
return UNITS.G3.copy(camera.up).mul(unitless);
},
set up(value: UNITS.G3) {
if (isVector(value)) {
scale('up', value, unitless, camera.up)
}
else {
throw new Error(`Camera.up property must be a vector.`);
}
}
}
return that;
}
///////////////////////////////////////////////////////////////////////////////
/**
* Displays an exception by writing it to a <pre> element.
*/
function displayError(e: any) {
const stderr = <HTMLPreElement>document.getElementById('error')
stderr.style.color = "#FF0000"
stderr.innerHTML = `${e}`
}
/**
* Calls the callback argument when the Document Object Model (DOM) has been loaded.
* Exceptions thrown by the callback function are caught and displayed.
*/
export function domReady(callback: () => any): void {
DomReady.ready(function() {
try
{
callback()
}
catch(e) {
displayError(e)
}
})
}
/**
* Catches exceptions thrown in the animation callback and displays them.
* This function will have a slight performance impact owing to the try...catch statement.
* This function may be bypassed for production use by using window.requestAnimationFrame directly.
*/
export function requestFrame(callback: FrameRequestCallback): number {
const wrapper: FrameRequestCallback = function(time: number) {
try {
callback(time)
}
catch(e) {
displayError(e)
}
}
return window.requestAnimationFrame(wrapper)
}
/**
* Creates an object that manages resizing of the output to fit the window.
*/
function windowResize(engine: EIGHT.Engine, overlay: EIGHT.Diagram3D, camera: EIGHT.PerspectiveCamera){
const callback = function() {
engine.size(window.innerWidth, window.innerHeight);
// engine.viewport(0, 0, window.innerWidth, window.innerHeight)
// engine.canvas.width = window.innerWidth
// engine.canvas.height = window.innerHeight
engine.canvas.style.width = `${window.innerWidth}px`
engine.canvas.style.height = `${window.innerHeight}px`
camera.aspect = window.innerWidth / window.innerHeight;
overlay.canvas.width = window.innerWidth
overlay.canvas.height = window.innerHeight
overlay.canvas.style.width = `${window.innerWidth}px`
overlay.canvas.style.height = `${window.innerHeight}px`
const ctxt = overlay.canvas.getContext('2d')
ctxt.font = '24px Helvetica'
ctxt.fillStyle = '#FFFFFF'
}
window.addEventListener('resize', callback, false);
const that = {
/**
*
*/
resize: function() {
callback();
return that;
},
/**
* Stop watching window resize
*/
stop : function() {
window.removeEventListener('resize', callback);
return that;
}
};
return that;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment