開発環境
- macOS Sierra - Apple (OS)
- Emacs (Text Editor)
- JavaScript (プログラミング言語)
- D3.js (JavaScript Library)
- Safari(Web browser)
- 参考書籍
- JavaScript 第6版 (David Flanagan(著)、村上 列(翻訳)、オライリージャパン)
- JavaScriptリファレンス 第6版(David Flanagan(著)、木下 哲也(翻訳)、オライリージャパン)
- インタラクティブ・データビジュアライゼーション(Scott Murray (著)、長尾 高弘 (翻訳)、オライリージャパン)
素数夜曲 (吉田 武 (著)、東海大学出版会)の付録D(女王陛下のLISP)、D.9(行列で蝶を愛でる)、D.9.2(不可能を描く)を JavaScript で取り組んでみる。
コード(Emacs)
HTML5
<div id="graph0"></div> <label for="speed0">速度(ms): </label> <input id="speed0" type="number" min="1" value="500"> <label for="color0">色: </label> <input id="color0" type="color" value="#ff0000"> <label for="step0">滑らかさ: </label> <input id="step0" type="number" min="1" step="1" value="24"> <button id="draw0">描画</button> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.6/d3.min.js" integrity="sha256-5idA201uSwHAROtCops7codXJ0vja+6wbBrZdQ6ETQc=" crossorigin="anonymous"></script> <script src="sample12.js"></script>
JavaScript
let div_graph = document.querySelector('#graph0'),
input_speed = document.querySelector('#speed0'),
input_color = document.querySelector('#color0'),
input_step = document.querySelector('#step0'),
button = document.querySelector('#draw0'),
svg,
width = 600,
height = 600,
tm;
let xscale = d3.scaleLinear()
.domain([-5, 5])
.range([0, 600]);
let yscale = d3.scaleLinear()
.domain([-5, 5])
.range([600, 0]);
let range = (start, end, step) => {
let result = [];
for (let i = start; i < end; i += step) {
result.push(i);
}
return result;
};
let butterfly = (t) => {
let r = Math.pow(Math.E, Math.sin(t)) - 2 * Math.cos(4 * t) + Math.pow(Math.sin(t / 12), 5);
return [r * Math.cos(t), r * Math.sin(t)];
};
let getPoints = (i) => {
return range(0, 24 * Math.PI + 0.1, Math.PI / i).map(butterfly);
};
let draw = (i) => {
let points = getPoints(i),
color = input_color.value;
div_graph.innerHTML = '';
svg = d3.select('#graph0')
.append('svg')
.attr('width', width)
.attr('height', height);
svg.selectAll('line')
.data(points.slice(0, -1))
.enter()
.append('line')
.attr('x1', (d) => xscale(d[0]))
.attr('y1', (d) => yscale(d[1]))
.attr('x2', (d, i) => xscale(points[i + 1][0]))
.attr('y2', (d, i) => yscale(points[i + 1][1]))
.attr('stroke', color);
};
let animate = () => {
let i = 1,
speed = parseInt(input_speed.value, 10),
step = parseInt(input_step.value, 10);
tm = setInterval(
() => {
draw(i);
i += 1;
if (i > step) {
clearInterval(tm);
}
}, speed);
};
button.onclick = () => {
clearInterval(tm);
animate();
};
animate();
0 コメント:
コメントを投稿