Simply showing an array of points connected in order of their radial position (angle from center).
A Pen by HARUN PEHLİVAN on CodePen.
| <header> | |
| <input type="range" min="3" max="1000" step="1" value="50"> | |
| </header> | |
| <div> | |
| <canvas id="cvs1" height="800" width="800"></canvas> | |
| <canvas id="cvs2" height="800" width="800"></canvas> | |
| </div> |
| console.clear(); | |
| const PI = Math.PI; | |
| const PI2 = PI * 2; | |
| class Point { | |
| constructor(centerX, centerY) { | |
| this.x = Math.random(); | |
| this.y = Math.random(); | |
| this.R = (Math.atan2(centerY - this.y, centerX - this.x) * 180 / PI + 180) / 360; | |
| this.group = 0; | |
| } | |
| } | |
| class Canvas { | |
| constructor() { | |
| this.element1 = document.querySelector('#cvs1'); | |
| this.context1 = this.element1.getContext('2d'); | |
| this.element2 = document.querySelector('#cvs2'); | |
| this.context2 = this.element2.getContext('2d'); | |
| this.gutter = 30; | |
| this.diameter = this.element1.width; | |
| this.switchContext(0); | |
| } | |
| clear() { | |
| this.context1.clearRect(0, 0, this.diameter, this.diameter); | |
| this.context2.clearRect(0, 0, this.diameter, this.diameter); | |
| } | |
| switchContext(idx) { | |
| this.context = [this.context1, this.context2][idx]; | |
| } | |
| text(x, y, text, offset = 1) { | |
| this.context.textAlign = 'center'; | |
| this.context.textBaseline = 'middle'; | |
| let fontSize = 14; | |
| let offsetY = (y > 0.5) ? fontSize * (offset * 1.5) : fontSize * (offset * -1.5); | |
| this.context.fillStyle = 'white'; | |
| this.context.font = `${fontSize}px Helvetica`; | |
| this.context.fillText(text, this.relative(x), this.relative(y) + offsetY); | |
| } | |
| point(x, y, fill = 'red') { | |
| this.context.fillStyle = fill; | |
| this.context.beginPath(); | |
| this.context.arc(this.relative(x), this.relative(y), 4, 0, PI2); | |
| this.context.fill(); | |
| } | |
| path(x1, y1, x2, y2, stroke = 'red') { | |
| this.context.strokeStyle = stroke; | |
| this.context.lineWidth = 2; | |
| this.context.beginPath(); | |
| this.context.moveTo(this.relative(x1), this.relative(y1)); | |
| this.context.lineTo(this.relative(x2), this.relative(y2)); | |
| this.context.stroke(); | |
| } | |
| relative(plot) { | |
| return plot * (this.diameter - this.gutter * 2) + this.gutter; | |
| } | |
| } | |
| class App { | |
| constructor() { | |
| this.canvas = new Canvas(); | |
| this.x = 0.5; | |
| this.y = 0.5; | |
| } | |
| generate(pointCount) { | |
| this.pointCount = pointCount; | |
| this.points = {}; | |
| for (let i = 0; i < pointCount; i++) { | |
| let point = new Point(this.x, this.y); | |
| this.points[point.group] = this.points[point.group] || []; | |
| this.points[point.group].push(point); | |
| } | |
| this.sortPoints(); | |
| this.drawPoints(); | |
| this.canvas.point(this.x, this.y, 'yellow'); | |
| } | |
| sortPoints() { | |
| for (let group in this.points) { | |
| this.points[group] = this.points[group].sort((a, b) => { | |
| if (a.R > b.R) return -1; | |
| if (a.R < b.R) return 1; | |
| return 0; | |
| }); | |
| } | |
| } | |
| drawPoints() { | |
| this.canvas.clear(); | |
| for (let group in this.points) { | |
| this.points[group].forEach((point, i) => { | |
| let fact = Math.round(point.R * 100) / 100; | |
| let color = `hsl(0, ${fact * 100}%, 50%)`; | |
| let next = this.points[group][(i + 1) % this.points[group].length]; | |
| this.canvas.path(point.x, point.y, next.x, next.y, color); | |
| this.canvas.point(point.x, point.y, color); | |
| this.canvas.switchContext(1); | |
| this.canvas.text(point.x, point.y, fact); | |
| this.canvas.switchContext(0); | |
| }); | |
| } | |
| } | |
| } | |
| let app = new App(); | |
| app.generate(50); | |
| let $input = document.querySelector('input'); | |
| $input.addEventListener('change', () => { | |
| app.generate(parseInt($input.value)); | |
| }); |
| body { | |
| background: #121212; | |
| } | |
| header { | |
| text-align: center; | |
| margin: 1rem 0; | |
| } | |
| div { | |
| position: relative; | |
| width: 95%; | |
| max-width: 600px; | |
| margin: 1rem auto; | |
| cursor: pointer; | |
| &:after { | |
| content: ''; | |
| padding-bottom: 100%; | |
| display: block; | |
| } | |
| canvas:last-child { | |
| display: none; | |
| } | |
| &:hover canvas:last-child { | |
| display: block; | |
| } | |
| canvas { | |
| &:first-child { | |
| background: black; | |
| } | |
| position: absolute; | |
| top: 0; left: 0; | |
| width: 100%; | |
| height: auto; | |
| } | |
| } |
Simply showing an array of points connected in order of their radial position (angle from center).
A Pen by HARUN PEHLİVAN on CodePen.