Skip to content

Instantly share code, notes, and snippets.

@jimbog
Created May 27, 2015 01:05
Show Gist options
  • Save jimbog/42e18a63cf9592f03b7d to your computer and use it in GitHub Desktop.
Save jimbog/42e18a63cf9592f03b7d to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
<title>Canvas Graphs</title>
<style>
body {
margin: 1em 1em 1em 1em;
}
</style>
</head>
<body>
<div class="pure-g">
<div class="pure-u-2-3">
<canvas id="my-canvas" width="500" height="500"></canvas>
</div>
<div class="pure-u-1-3">
<textarea name="function" id="function" cols="30" rows="5" placeholder="i.e. n*n"></textarea>
<input type="range" value="100" min="10" max="100000" list="steplist"/>
<datalist id="steplist">
<option>10</option>
<option>100</option>
<option>1000</option>
<option>10000</option>
<option>100000</option>
</datalist>
<div id="slider-text"></div>
<button class="pure-button">draw</button>
</div>
</div>
</body>
<script>
var
canvas = document.getElementById("my-canvas")
, ctx = canvas.getContext("2d")
, raq = window.requestAnimationFrame
, h = canvas.height
, w = canvas.width
, offsetX = 10
, yScale
, xScale;
function _y(y) {
return h - y
}
function createLinearScale(x, y) {
var m, b;
//with y = mx + b
//m = y0 - y1/ x0 - x1
m = (y.min - y.max) / (x.min - x.max);
//b = y0 - mx0
b = y.min - m * x.min;
return function (num) {
return m * num + b;
};
}
function yAxis(from, to, color) {
var _from = from || 0;
var _to = to || h;
yScale = createLinearScale({min: _from, max: _to}, {min: 0, max: h});
ctx.beginPath();
ctx.moveTo(0, _y(0));
ctx.lineTo(0, _y(yScale(_to)));
ctx.lineWidth = 2;
ctx.stroke();
for (var i = _from; i <= _to; i = i + (_to - _from ) / 10) {
ctx.fillText("_", 1, _y(yScale(i)));
ctx.fillText(i.toFixed(2), 10, _y(yScale(i)) + 7);
}
}
function xAxis(from, to, color) {
var _from = from || 0;
var _to = to || w;
xScale = createLinearScale({min: _from, max: _to}, {min: 0, max: w});
ctx.beginPath();
ctx.moveTo(_from, _y(0));
ctx.lineTo(xScale(_to), _y(0));
ctx.lineWidth = 2;
ctx.stroke();
for (var i = _from; i <= _to; i = i + (_to - _from ) / 10) {
ctx.fillText("|", xScale(i), _y(0));
ctx.fillText(i, xScale(i) - 10, _y(10));
}
}
function drawFunc(fn, options) {
var done = false;
var oldX, oldY;
oldX = 0;
oldY = _y(0);
var _y_max = fn(options.x.max);
yAxis(0, _y_max);
xAxis(0, options.x.max);
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'tomato';
raq(drawPix);
var _i = 0;
function drawPix() {
if (_i < options.x.max) {
ctx.moveTo(oldX, oldY);
ctx.lineTo(xScale(_i), _y(yScale(fn(_i))));
oldX = xScale(_i);
oldY = _y(yScale(fn(_i)));
_i += options.x.max * 0.005;
ctx.stroke();
raq(drawPix);
} else {
done = true;
console.log("done");
}
}
}
// drawFunc(function(x){return Math.pow(2, x)}, {x:{max: 20}});
// drawFunc(function(x){return 100 * Math.cos(1*x)}, {x:{max: 5 * Math.PI}});
// drawFunc(function(x){return Math.log(x) }, {x:{max: 1000000}});
// drawFunc(function(x){return x * x}, {x:{max: 10000}});
// drawFunc(function(x){return x}, {x:{max: 1000}});
// drawFunc(function(x){return Math.log(x)}, {x:{max: 100000000}});
</script>
<script>
var drawButton = document.getElementsByTagName("button")[0];
var slider = document.getElementsByTagName("input")[0];
var sliderText = document.getElementById("slider-text");
var textFn = document.getElementsByTagName("textarea")[0];
slider.style.width = "100%";
sliderText.innerText = slider.value;
slider.addEventListener('input', function (evt) {
sliderText.innerText = evt.target.value;
});
drawButton.addEventListener('click', function () {
var fn = new Function("n", "return " + textFn.value);
ctx.strokeStyle = 'black';
ctx.clearRect(0, 0, w, h);
drawFunc(fn, {x: {max: Number(slider.value)}})
})
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment