Skip to content

Instantly share code, notes, and snippets.

@stemcstudio
Last active October 7, 2020 18:29
Show Gist options
  • Save stemcstudio/396b8b6a4e706acc9bf83ac0537e7104 to your computer and use it in GitHub Desktop.
Save stemcstudio/396b8b6a4e706acc9bf83ac0537e7104 to your computer and use it in GitHub Desktop.
JSXGraph Conference 2020

JSXGraph Template

Overview

This program provides the boilerplate for creating a JSXGraph Board.

Credits

JSXGraph was developed by the Center for Mobile Learning with Digital Technology – Universität Bayreuth, Germany.

$$e^{i\pi}+1=0$$

/**
* Attributes used to initialize the JXG.Board.
*/
export const boardAttributes: JXG.BoardAttributes = {
axis: true,
boundingBox: [-6, 6, 6, -6],
showCopyright: true,
showNavigation: true,
showFullscreen: true,
showScreenshot: true
}
@charset "UTF-8";
/* Resets and base styles from HTML5 Boilerplate */
div,
span,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
abbr,
address,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
samp,
small,
strong,
sub,
sup,
var,
b,
i,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: "";
content: none;
}
ins {
background-color: #ff9;
color: #000;
text-decoration: none;
}
mark {
background-color: #ff9;
color: #000;
font-style: italic;
font-weight: bold;
}
del {
text-decoration: line-through;
}
abbr[title],
dfn[title] {
border-bottom: 1px dotted;
cursor: help;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
input,
select {
vertical-align: middle;
}
select,
input,
textarea,
button {
font: 99% sans-serif;
}
pre,
code,
kbd,
samp {
font-family: monospace, sans-serif;
}
a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
a:hover,
a:active {
outline: none;
}
ul,
ol {
margin-left: 2em;
vertical-align: top;
}
ol {
list-style-type: decimal;
}
nav ul,
nav li {
margin: 0;
list-style: none;
list-style-image: none;
}
small {
font-size: 85%;
}
strong,
th {
font-weight: bold;
}
td {
vertical-align: top;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
textarea {
overflow: auto;
}
input[type="radio"] {
vertical-align: text-bottom;
}
input[type="checkbox"] {
vertical-align: bottom;
}
label,
input[type="button"],
input[type="submit"],
input[type="image"],
button {
cursor: pointer;
}
button,
input,
select,
textarea {
margin: 0;
}
input:invalid,
textarea:invalid {
border-radius: 1px;
-moz-box-shadow: 0px 0px 5px red;
-webkit-box-shadow: 0px 0px 5px red;
box-shadow: 0px 0px 5px red;
}
input:invalid .no-boxshadow,
textarea:invalid .no-boxshadow {
background-color: #f0dddd;
}
button {
width: auto;
overflow: visible;
}
select,
input,
textarea {
color: #444444;
}
a {
color: #607890;
}
a:hover,
a:focus {
color: #036;
}
a:link {
-webkit-tap-highlight-color: #fff;
}
/* End HTML5 Boilerplate adaptations */
h1 {
font-size: 4.5em;
}
h1,
.vcenter {
font-weight: bold;
text-align: center;
padding-top: 1em;
max-height: 100%;
}
.csstransforms h1,
.csstransforms .vcenter {
padding: 0 48px;
position: absolute;
left: 0;
right: 0;
top: 50%;
-webkit-transform: translate(0, -50%);
-moz-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
-o-transform: translate(0, -50%);
transform: translate(0, -50%);
}
.vcenter h1 {
position: relative;
top: auto;
padding: 0;
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
-o-transform: none;
transform: none;
}
h2 {
font-size: 2.25em;
font-weight: bold;
padding-top: .5em;
margin: 0 0 .66666em 0;
border-bottom: 3px solid #888;
}
h3 {
font-size: 1.4375em;
font-weight: bold;
margin-bottom: .30435em;
}
h4 {
font-size: 1.25em;
font-weight: bold;
margin-bottom: .25em;
}
h5 {
font-size: 1.125em;
font-weight: bold;
margin-bottom: .2222em;
}
h6 {
font-size: 1em;
font-weight: bold;
}
img,
iframe,
video {
display: block;
max-width: 100%;
}
video,
iframe,
img {
display: block;
margin: 0 auto;
}
p,
blockquote,
iframe,
img,
ul,
ol,
pre,
video {
margin-bottom: 1em;
}
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
padding: 1em;
border: 1px solid #888;
}
em {
font-style: italic;
}
li {
padding: .25em 0;
vertical-align: middle;
}
li>ol,
li>ul {
margin-bottom: inherit;
}
.deck-container {
font-size: 16px;
line-height: 1.25;
color: #444;
}
.slide {
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: "Hoefler Text", Constantia, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
}
h1 {
color: #08455f;
}
h2 {
color: #0b7495;
border-bottom: 0;
}
.cssreflections h2 {
line-height: 1;
-webkit-box-reflect: below -0.5555em -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.3, transparent), color-stop(0.7, rgba(255, 255, 255, 0.1)), to(transparent));
-moz-box-reflect: below -0.5555em -moz-linear-gradient(top, transparent 0%, transparent 30%, rgba(255, 255, 255, 0.3) 100%);
}
h3 {
color: #000;
}
pre {
border-color: #cde;
background: #fff;
position: relative;
z-index: auto;
border-radius: 5px;
/* http://nicolasgallagher.com/css-drop-shadows-without-images/ */
}
.csstransforms.boxshadow pre> :first-child:before {
content: "";
position: absolute;
z-index: -1;
background: #fff;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.csstransforms.boxshadow pre:before,
.csstransforms.boxshadow pre:after {
content: "";
position: absolute;
z-index: -2;
bottom: 15px;
width: 50%;
height: 20%;
max-width: 300px;
box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
}
.csstransforms.boxshadow pre:before {
left: 10px;
-webkit-transform: rotate(-3deg);
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
}
.csstransforms.boxshadow pre:after {
right: 10px;
-webkit-transform: rotate(3deg);
-ms-transform: rotate(3deg);
transform: rotate(3deg);
}
code {
color: #789;
}
blockquote {
font-family: "Hoefler Text", Constantia, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
font-size: 2em;
padding: 1em 2em .5em 2em;
color: #000;
background: #fff;
position: relative;
border: 1px solid #cde;
z-index: auto;
border-radius: 5px;
}
.boxshadow blockquote> :first-child:before {
content: "";
position: absolute;
z-index: -1;
background: #fff;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.boxshadow blockquote:after {
content: "";
position: absolute;
z-index: -2;
top: 10px;
bottom: 10px;
left: 0;
right: 50%;
-moz-border-radius: 10px / 100px;
border-radius: 10px / 100px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.6);
}
blockquote p {
margin: 0;
}
blockquote cite {
font-size: .5em;
font-style: normal;
font-weight: bold;
color: #888;
}
blockquote:before {
content: "“";
position: absolute;
top: 0;
left: 0;
font-size: 5em;
line-height: 1;
color: #ccf0f0;
z-index: 1;
}
::-moz-selection {
background: #08455f;
color: #fff;
}
::selection {
background: #08455f;
color: #fff;
}
a,
a:hover,
a:focus,
a:active,
a:visited {
color: #599;
text-decoration: none;
}
a:hover,
a:focus {
text-decoration: underline;
}
.deck-container {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
font-size: 1.75em;
background: #f4fafe;
/* Old browsers */
background: -moz-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4fafe), color-stop(100%, #ccf0f0));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* Opera11.10+ */
background: -ms-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* IE10+ */
background: linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* W3C */
background-attachment: fixed;
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5);
}
.deck-container>.slide {
padding: 0 48px;
}
.slide .deck-before,
.slide .deck-previous {
opacity: 0.4;
}
.slide .deck-before:not(.deck-child-current) .deck-before,
.slide .deck-before:not(.deck-child-current) .deck-previous,
.slide .deck-previous:not(.deck-child-current) .deck-before,
.slide .deck-previous:not(.deck-child-current) .deck-previous {
opacity: 1;
}
.slide .deck-child-current {
opacity: 1;
}
.deck-prev-link,
.deck-next-link {
background: #fff;
opacity: 0.5;
}
.deck-prev-link,
.deck-prev-link:hover,
.deck-prev-link:focus,
.deck-prev-link:active,
.deck-prev-link:visited,
.deck-next-link,
.deck-next-link:hover,
.deck-next-link:focus,
.deck-next-link:active,
.deck-next-link:visited {
color: #599;
}
.deck-prev-link:hover,
.deck-prev-link:focus,
.deck-next-link:hover,
.deck-next-link:focus {
opacity: 1;
text-decoration: none;
}
.deck-status {
font-size: 0.6666em;
}
.deck-menu .slide {
background: transparent;
border-radius: 5px;
}
.rgba .deck-menu .slide {
background: rgba(0, 0, 0, 0.1);
}
.deck-menu .slide.deck-current,
.rgba .deck-menu .slide.deck-current,
.no-touch .deck-menu .slide:hover {
background: #fff;
}
.goto-form {
background: #fff;
border: 1px solid #cde;
border-radius: 5px;
}
.boxshadow .goto-form {
box-shadow: 0 15px 10px -10px rgba(0, 0, 0, 0.5), 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=1024, user-scalable=no">
<title>Your deck.js Presentation</title>
<link rel='stylesheet' href="deck.css" />
</head>
<body>
<div class="deck-container">
<!-- Begin slides. Just make elements with a class of slide. -->
<section class="slide">
<h1>Using JSXGraph in STEMCstudio</h1>
</section>
<section class="slide">
<div>
<h2>Overview</h2>
<ul>
<li>Philosopy of Computation in Education</li>
<li>Introduction to STEMCstudio</li>
<li>Walkthrough</li>
<li>Demonstration</li>
<li>Future and Discussion</li>
</ul>
</div>
</section>
<section class="slide">
<h2>Philosophy</h2>
<blockquote cite="http://example.com">
<p>The purpose of (scientific) computing is insight, not numbers.</p>
<p><cite>Richard Hamming</cite></p>
</blockquote>
</section>
<section class="slide">
<h2>About STEMCstudio</h2>
<!-- p>Here is a list of points:</p -->
<ul>
<li>General Purpose, In-Browser, Coding Environment</li>
<li>HTML + TypeScript, JavaScript, ...</li>
<li>Optimized for Education and Research</li>
<li>Easy to Use for Novice, Designed for Experts</li>
<li></li>
<li>Bring best practices from Software Engineering</li>
</ul>
</section>
<section class="slide">
<h1>Here</h1>
</section>
<!-- End slides. -->
<!-- Begin extension snippets. Add or remove as needed. -->
<!-- deck.navigation snippet -->
<div aria-role="navigation">
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
</div>
<!-- deck.status snippet -->
<p class="deck-status" aria-role="status">
<span class="deck-status-current"></span> /
<span class="deck-status-total"></span>
</p>
<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>
<!-- End extension snippets. -->
</div>
</body>
</html>
$(function() {
$['deck']('.slide')
})
/*
import { boardAttributes } from './boardAttribs.js'
DomReady.ready(function() {
const board = JXG.JSXGraph.initBoard('box', boardAttributes)
const p1 = board.create('point', [0, 0])
const p2 = board.create('point', [5, 0])
const p3 = board.create('point', [0, 5])
board.create('circle', [p1, p2])
const angle = board.create('angle', [p2, p1, p3], { radius: 3 })
const slider = board.create('slider', [[-2, 1], [2, 1], [0, Math.PI * 0.5, 2 * Math.PI]])
angle.setAngle(function() {
return slider.Value()
})
board.update()
}).catch(function(err) { console.error(err) })
*/
body {
background: #cccccc;
}
pre code.hljs {
display: block;
}
code.hljs {
display: inline;
}
<!DOCTYPE html>
<html lang='en'>
<head>
<base href='/'>
<link rel='stylesheet' href="index.css" />
</head>
<body>
<div id='box' class='jxgbox' style='width:500px; height:500px'></div>
<ul>
<li>
<a href='http://jsxgraph.uni-bayreuth.de' target='_blank' class='JXGtext'>JSXGraph Home Page</a>
</li>
</ul>
</body>
</html>
import { boardAttributes } from './boardAttribs.js'
DomReady.ready(function() {
const board = JXG.JSXGraph.initBoard('box', boardAttributes)
const p1 = board.create('point', [0, 0])
const p2 = board.create('point', [5, 0])
const p3 = board.create('point', [0, 5])
board.create('circle', [p1, p2])
const angle = board.create('angle', [p2, p1, p3], { radius: 3 })
const slider = board.create('slider', [[-2, 1], [2, 1], [0, Math.PI * 0.5, 2 * Math.PI]])
angle.setAngle(function() {
return slider.Value()
})
board.update()
}).catch(function(err) { console.error(err) })
export class Board {
constructor(public jxgBoard: JXG.Board) {
// Do nothing
}
/**
*
* @param centerPoint
* @param radiusPoint
* @param anglePoint
* @param attributes
*/
addAngle(centerPoint: JXG.PointSpecification, radiusPoint: JXG.PointSpecification, anglePoint: JXG.PointSpecification, attributes?: JXG.AngleAttributes): JXG.Angle {
return this.jxgBoard.create('angle', [centerPoint, radiusPoint, anglePoint], attributes)
}
/**
*
* @param centerPoint
* @param radiusPoint
* @param anglePoint
* @param attributes
*/
addArc(centerPoint: JXG.PointSpecification, radiusPoint: JXG.PointSpecification, anglePoint: JXG.PointSpecification, attributes?: JXG.ArcAttributes): JXG.Arc {
return this.jxgBoard.create('arc', [centerPoint, radiusPoint, anglePoint], attributes)
}
/**
*
* @param point1
* @param point2
* @param attributes
*/
addAxis(point1: JXG.PointSpecification, point2: JXG.PointSpecification, attributes?: JXG.AxisAttributes): JXG.Axis {
return this.jxgBoard.create('axis', [point1, point2], attributes)
}
/**
*
* @param centerPoint
* @param radiusOrPoint
*/
addCircle(centerPoint: JXG.PointSpecification, radiusOrPoint: number | JXG.PointSpecification, attributes?: JXG.CircleAttributes): JXG.Circle {
return this.jxgBoard.create('circle', [centerPoint, radiusOrPoint], attributes)
}
/**
*
* @param dataX
* @param dataY
* @param attributes
*/
addCurve(dataX: number[] | JXG.CurveFunction, dataY: number[] | JXG.CurveFunction, attributes?: JXG.CurveAttributes): JXG.Curve {
return this.jxgBoard.create('curve', [dataX, dataY], attributes)
}
/**
*
* @param curveFunction
* @param a
* @param b
* @param attributes
*/
addFunctionGraph(curveFunction: JXG.CurveFunction, a?: number | JXG.NumberFunction, b?: number | JXG.NumberFunction, attributes?: JXG.FunctiongraphAttributes): JXG.Functiongraph {
return this.jxgBoard.create('functiongraph', [curveFunction, a, b], attributes)
}
/**
*
* @param glideObject
* @param attributes
*/
addGlider(glideObject: JXG.GeometryElement, attributes?: JXG.GliderAttributes): JXG.Glider {
return this.jxgBoard.create('glider', [glideObject], attributes)
}
/**
*
* @param point1
* @param point2
* @param attributes
*/
addLine(point1: JXG.PointSpecification, point2: JXG.PointSpecification, attributes?: JXG.LineAttributes): JXG.Line {
return this.jxgBoard.create('line', [point1, point2], attributes)
}
/**
*
* @param coordX
* @param coordY
* @param attributes
*/
addPointXY(coordX: JXG.CoordSpecification, coordY: JXG.CoordSpecification, attributes?: JXG.PointAttributes): JXG.Point {
return this.jxgBoard.create('point', [coordX, coordY], attributes)
}
/**
* @param coords The coordinates of the point that will be added added to the board.
* @param attributes
* @returns
*/
addPoint(coords: [JXG.CoordSpecification, JXG.CoordSpecification], attributes?: JXG.PointAttributes): JXG.Point {
return this.jxgBoard.create('point', [coords[0], coords[1]], attributes)
}
/**
*
* @param f
* @param n
* @param type
* @param a
* @param b
* @param attributes
*/
addRiemannsum(f: JXG.CurveFunction, n: JXG.NumberFunction, type: JXG.RiemannSumType | JXG.RiemannSumTypeFunction, a: JXG.BorderSpecification, b: JXG.BorderSpecification, attributes?: JXG.CurveAttributes): JXG.Riemannsum {
return this.jxgBoard.create('riemannsum', [f, n, type, a, b], attributes)
}
/**
*
* @param beginPoint
* @param endPoint
* @param min
* @param start
* @param max
* @param attributes
*/
addSlider(beginPoint: JXG.PointSpecification, endPoint: JXG.PointSpecification, min: number, start: number, max: number, attributes?: JXG.SliderAttributes): JXG.Slider {
return this.jxgBoard.create('slider', [beginPoint, endPoint, [min, start, max]], attributes)
}
/**
*
* @param tangent
* @param attributes
*/
addSlopetriangleFromTangent(tangent: JXG.Tangent, attributes?: JXG.SlopetriangleAttributes): JXG.Slopetriangle {
return this.jxgBoard.create('slopetriangle', [tangent], attributes)
}
/**
*
* @param line
* @param point
* @param attributes
*/
addSlopetriangleFromLineAndPoint(line: JXG.Line, point: JXG.Point, attributes?: JXG.SlopetriangleAttributes): JXG.Slopetriangle {
return this.jxgBoard.create('slopetriangle', [line, point], attributes)
}
/**
*
* @param dataX
* @param dataY
* @param attributes
*/
addStepfunction(dataX: JXG.CoordSpecification[], dataY: JXG.CoordSpecification[], attributes?: JXG.StepfunctionAttributes): JXG.Stepfunction {
return this.jxgBoard.create('stepfunction', [dataX, dataY], attributes)
}
/**
*
* @param glider
* @param attributes
*/
addTangent(glider: JXG.Glider, attributes?: JXG.TangentAttributes): JXG.Tangent {
return this.jxgBoard.create('tangent', [glider], attributes)
}
/**
*
* @param x
* @param y
* @param s
* @param attributes
*/
addText(x: number | JXG.NumberFunction, y: number | JXG.NumberFunction, text: string | JXG.StringFunction, attributes?: JXG.TextAttributes): JXG.Text {
return this.jxgBoard.create('text', [x, y, text], attributes)
}
}
export function initBoard(elementId: string, attributes?: JXG.BoardAttributes): Board {
return new Board(JXG.JSXGraph.initBoard(elementId, attributes))
}
{
"description": "JSXGraph Conference 2020",
"dependencies": {
"deck.js": "^1.1.0",
"DomReady": "^1.0.0",
"jquery": "^2.1.4",
"jsxgraph": "^1.1.0"
},
"name": "project-1",
"version": "1.0.0",
"linting": true,
"hideConfigFiles": true,
"author": "David Geo Holmes"
}
body {
background: #cccccc;
}
pre code.hljs {
display: block;
}
code.hljs {
display: inline;
}
{
"allowJs": true,
"checkJs": true,
"declaration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"jsx": "react",
"module": "system",
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"preserveConstEnums": true,
"removeComments": true,
"skipLibCheck": true,
"sourceMap": false,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"target": "es5",
"traceResolution": true
}
{
"rules": {
"array-type": [
true,
"array"
],
"curly": false,
"comment-format": [
true,
"check-space"
],
"eofline": true,
"forin": true,
"jsdoc-format": true,
"new-parens": true,
"no-conditional-assignment": false,
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-for-in-array": true,
"no-inferrable-types": [
true
],
"no-magic-numbers": false,
"no-shadowed-variable": true,
"no-string-throw": true,
"no-trailing-whitespace": [
false,
"ignore-jsdoc"
],
"no-var-keyword": true,
"one-variable-per-declaration": [
true,
"ignore-for-loop"
],
"prefer-const": true,
"prefer-for-of": true,
"prefer-function-over-method": false,
"prefer-method-signature": true,
"radix": true,
"semicolon": [
true,
"never"
],
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": true,
"use-isnan": true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment