開発環境
- 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 コメント:
コメントを投稿