document.onkeydown = handleKeyDown; PI = 3.141592 startX = window.innerWidth / 2 startY = (window.innerHeight-250) /2 length = 100 // sides = Math.floor(Math.random()* 7) + 3 ratio = Math.random() mid_value = Math.random() / 2 iterations = Math.random()*50+5 mid_angle = Math.random() / 2 alpha = 0.4 ratio_f = (x) => Math.sin(x) function start() { canvas.start(); } var canvas = { canvas: document.createElement("canvas"), start: function () { this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight - 250; this.context = this.canvas.getContext("2d"); document.body.insertBefore(this.canvas, document.body.childNodes[0]); this.frameNo = 0; this.interval = setInterval(updateCanvas, 10); this.style = "z-index:-1" // updateCanvas() }, clear: function () { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } } function updateCanvas() { sides = parseInt(document.getElementById("sides").value) length = parseInt(document.getElementById("length").value) ratio = parseInt(document.getElementById("ratio").value) / 1000 mid_value = parseInt(document.getElementById("mid_value").value) / 1000 iterations = parseInt(document.getElementById("iterations").value) mid_angle = parseInt(document.getElementById("mid_angle").value) / 10000 if(document.getElementById("moving").checked){ mid_angle = mid_angle + 0.01 } document.getElementById("mid_angle").value = mid_angle * 10000 if (document.getElementById("mid_angle").value == document.getElementById("mid_angle").max && document.getElementById("moving").checked) { document.getElementById("mid_angle").value = document.getElementById("mid_angle").min } test = document.getElementById("function").value if(test==1){ ratio_f = (x)=>Math.sin(x) }else if(test == 2){ ratio_f = (x) => x }else if(test == 3){ ratio_f = (x) => 1 } ctx = canvas.context ctx.globalAlpha = alpha ctx.strokeWidth = 2 canvas.clear() ctx.strokeStyle = 'rgb(0,0,0)' ctx.beginPath() var apothem = ((length/2) / Math.tan(PI/sides)) var pentagon = polygon(startX - length/2, startY + apothem, sides, length) pentagon.forEach((point) => { ctx.moveTo(point.x, point.y) ctx.lineTo(point.xEnd, point.yEnd) }) for (i = 0; i < iterations; i++) { var mids = midpoints(length * ratio, pentagon, i, ratio_f) mids.forEach((point) => { ctx.moveTo(point.x, point.y) ctx.lineTo(point.xEnd, point.yEnd) }) pentagon = connectPoints(mids) pentagon.forEach((point) => { ctx.moveTo(point.x, point.y) ctx.lineTo(point.xEnd, point.yEnd) }) } ctx.stroke() } function polygon(x, y, sides, length) { var polygonReducer = (accumulator, currentValue, currentIndex, array) => { var prevEnd = accumulator.slice(-1)[0] var x = prevEnd.xEnd + Math.cos(currentValue * 2 * PI / sides) * length var y = prevEnd.yEnd - Math.sin(currentValue * 2 * PI / sides) * length accumulator.push({ 'x': prevEnd.xEnd, 'y': prevEnd.yEnd, 'xEnd': x, 'yEnd': y }) if (currentIndex == 0) { accumulator.shift() } return accumulator } return range(0, sides).reduce(polygonReducer, [{ 'xEnd': x, 'yEnd': y }]) } function midpoints(length, pointList, currentIteration, fun_y) { var midReducer = (accumulator, currentValue, currentIndex, array) => { var cv = currentValue var angle = Math.atan2(cv.yEnd - cv.y, cv.xEnd - cv.x) - mid_angle x = mid_value * cv.x + (1-mid_value) * cv.xEnd y = mid_value * cv.y + (1-mid_value) * cv.yEnd var radius = fun_y(currentIteration) * length var value = { 'x': x, 'y': y, 'xEnd': x + radius* Math.cos(angle), 'yEnd': y + radius * Math.sin(angle) } accumulator.push(value) return accumulator } return pointList.reduce(midReducer, []) } function connectPoints(pointsList) { var result = [] for (var i = 0; i < pointsList.length; i++) { var next = i + 1 if (i == pointsList.length - 1) { next = 0 } result.push({ 'x': pointsList[i].xEnd, 'y': pointsList[i].yEnd, 'xEnd': pointsList[next].xEnd, 'yEnd': pointsList[next].yEnd }) } return result } // function polygonReducer(accumulator, currentValue, currentIndex, array){ // var x = accumulator.slice(-1)[0].x + Math.cos(currentValue*2*PI/5)*50 // var y = accumulator.slice(-1)[0].y + Math.sin(currentValue*2*PI/5)*50 // accumulator.push({'x': x, 'y': y}) // return accumulator // } function range(start, count) { return Array.apply(0, Array(count)) .map((element, index) => index + start); } function handleTouchMove(event) { finalX = event.touches[0].clientX //clamp(event.touches[0].pageX - canvas.canvas.getBoundingClientRect().left, 0, canvas.canvas.width) finalY = event.touches[0].clientY //clamp(event.touches[0].pageY - canvas.canvas.getBoundingClientRect().top, 0, canvas.canvas.height) } function handleMouseMove(event) { currentX = clamp(event.x - canvas.canvas.getBoundingClientRect().left, 0, canvas.canvas.width) currentY = clamp(event.y - canvas.canvas.getBoundingClientRect().top, 0, canvas.canvas.height) } function handleMouseDown(event) { x = clamp(event.x - canvas.canvas.getBoundingClientRect().left, 0, canvas.canvas.width) y = clamp(event.y - canvas.canvas.getBoundingClientRect().top, 0, canvas.canvas.height) downX = x downY = y } function handleKeyDown(event) { } function handleMouseUp(event) { x = clamp(event.x - canvas.canvas.getBoundingClientRect().left, 0, canvas.canvas.width) y = clamp(event.y - canvas.canvas.getBoundingClientRect().top, 0, canvas.canvas.height) xVel = (downX - x) / 100 yVel = (downY - y) / 100 // makeParticle(downX, downY, xVel, yVel) } function handleTouchStart(event) { var thing = { 'x': event.touches[0].clientX, 'y': event.touches[0].clientY } handleMouseDown(thing) } function handleTouchEnd(event) { event.preventDefault() var thing = { 'x': finalX, 'y': finalY } handleMouseUp(thing) } function getRandomColor() { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; } function clamp(num, min, max) { return num <= min ? min : num >= max ? max : num } function cos(num) { return Math.cos(num * Math.PI / 180) } function sin(num) { return -1 * Math.sin(num * Math.PI / 180) } function isColliding(x1, y1, w1, h1, x2, y2, w2, h2) { return x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2 }