<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Desmos (Line Generator 3)</title>
</head>
<body>
<p>
<button id="btnFirst">First</button>
<button id="btnPrev">Prev</button>
<button id="btnNext">Next</button>
<button id="btnLast">Last</button></p>
<p id="desmosTitle">Straight Lines and Gradients: click Next to create a new line</p>
<div id="calculator" style="width: 600px; height: 400px;"></div>
<p><button id="btnClear">Clear</button></p>
<p id="findOut"><a href="http://www.room51.co.uk/tutorials/desmos/generating-lines/part3.html" target="_blank">Tutorial at room51.co.uk</a></p>
<script src="https://www.desmos.com/api/v0.8/calculator.js?apiKey=dcb31709b452b1cf9dc26972add0fda6"></script>
</body>
</html>
(function () {
"use strict";
var calculator;
var pointsCollection;
var qIndex;
function between (a, b) {
var range = b - a + 1;
return a + Math.floor(Math.random() * range);
}
function getPoints () {
var p1 = { x:0, y:0 };
var p2 = { x:0, y:0 };
while (p1.x === p2.x && p1.y === p2.y) {
p1.x = between(-5, 5);
p1.y = between(-5, 5);
p2.x = between(-5, 5);
p2.y = between(-5, 5);
}
return [ p1, p2 ];
}
function getFractionString (num, den, cb) {
var isNegative = num * den < 0;
var helper = calculator.HelperExpression({
latex: '\\gcd(' + num +',' + den +')'
});
helper.observe('numericValue', function () {
var fracString = num * den < 0 ? '-' : '';
num = Math.abs(num / helper.numericValue);
den = Math.abs(den / helper.numericValue);
if (den === 1) {
fracString += num;
} else {
fracString += '\\frac{' + num + '}{' + den + '}';
}
cb(fracString);
});
}
function getGradientInfo (points) {
var dy = points[1].y - points[0].y;
var dx = points[1].x - points[0].x;
return {
dy: dy,
dx: dx,
isZero: dy === 0 && dx !== 0,
isUndefined: dx === 0,
yIntNum: points[0].y * dx - points[0].x * dy
};
}
function pointString (point) {
return '(' + point.x + ', ' + point.y + ')';
}
function lineString (points, cb) {
var info = getGradientInfo(points);
if (info.isUndefined) {
cb('x = ' + points[0].x);
} else if (info.isZero) {
cb('y = ' + points[0].y);
} else {
getFractionString(info.dy, info.dx, function (gradient) {
getFractionString(info.yIntNum, info.dx, function (yInt) {
var lineString = 'y = ' + gradient + 'x + ' + yInt;
lineString = lineString
.replace(' 1x', 'x')
.replace('-1x', '-x')
.replace(' + -', ' - ')
.replace(' + 0', '');
cb(lineString);
});
});
}
}
function showLine () {
var points = pointsCollection[qIndex];
calculator.setMathBounds({
left: - 8,
right: 8,
bottom: -8,
top: 8
});
lineString(points, function (line) {
calculator.setExpression({id:'line', latex:line});
});
points.forEach(function (point, i) {
calculator.setExpression({id: 'point' + i, latex: pointString(point)});
});
}
function setTitle () {
var title = 'Straight Lines and Gradients: ';
var desmosTitle = document.getElementById('desmosTitle');
if (pointsCollection.length) {
title += (qIndex + 1) + ' of ' + pointsCollection.length;
} else {
title += 'click Next to create a new line'
}
desmosTitle.innerText = title;
}
function render () {
showLine();
setTitle();
}
function next () {
if (qIndex === pointsCollection.length - 1) {
pointsCollection.push(getPoints());
}
qIndex++;
render();
}
function prev () {
if (qIndex > 0) {
qIndex--;
render();
}
}
function first () {
if (pointsCollection.length) {
qIndex = 0;
render();
}
}
function last () {
if (pointsCollection.length) {
qIndex = pointsCollection.length - 1;
render();
}
}
function clear () {
qIndex = -1;
pointsCollection = [];
setTitle();
calculator.removeExpressions([
{ id: 'point0' },
{ id: 'point1' },
{ id: 'line' }
]);
}
function init () {
var elt = document.getElementById('calculator');
calculator = Desmos.GraphingCalculator(elt, {
expressionsCollapsed: true
});
calculator.updateSettings({
xAxisMinorSubdivisions: 1,
yAxisMinorSubdivisions: 1,
yAxisStep: 1,
xAxisStep: 1
});
qIndex = -1;
pointsCollection = [];
document.getElementById('btnNext').addEventListener('click', next);
document.getElementById('btnPrev').addEventListener('click', prev);
document.getElementById('btnFirst').addEventListener('click', first);
document.getElementById('btnLast').addEventListener('click', last);
document.getElementById('btnClear').addEventListener('click', clear);
}
init();
})();
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |