var canvas = document.getElementById("daCanvas"); var context = canvas.getContext("2d"); var displayWidth = window.innerWidth; //canvas.width; var displayHeight = window.innerHeight; //canvas.height; var colorsA, colorsS; init(); function colorToRGB(color, alpha) { //from Foundation HTML5 Animation with JavaScript, by Billy Lamberta , Keith Peters //number in octal format or string prefixed with # if (typeof color === 'string' && color[0] === '#') { color = window.parseInt(color.slice(1), 16); } alpha = (alpha === undefined) ? 1 : alpha; //parse hex values var r = color >> 16 & 0xff, g = color >> 8 & 0xff, b = color & 0xff, a = (alpha < 0) ? 0 : ((alpha > 1) ? 1 : alpha); //only use 'rgba' if needed if (a === 1) { return "rgb(" + r + "," + g + "," + b + ")"; } else { return "rgba(" + r + "," + g + "," + b + "," + a + ")"; } }; function init() { colorsA = ['#fff600', '#ffa100','#ff6f00','#ff6f00','#ff3c00', '#c7009b','#af00c7','#8800c7']; colorsS = []; for (var i = 0; i < colorsA.length; i++){ colorsS[colorsA.length - i] = colorToRGB(colorsA[i]); colorsA[i] = colorToRGB(colorsA[i], .6); } resizeCanvas(); window.addEventListener('resize', resizeCanvas, false); } function setLinePoints(iterations) { //based on Imperfect Circles by Dan Gries: http://codepen.io/RectangleWorld/pen/murei var pointList = {}; pointList.first = {x: 0, y: 1}; var lastPoint = {x: 1, y: 1} var minY = 1; var maxY = 1; var point; var nextPoint; var dx, newX, newY; pointList.first.next = lastPoint; for (var i = 0; i < iterations; i++) { point = pointList.first; while (point.next != null) { nextPoint = point.next; dx = nextPoint.x - point.x; newX = 0.5 * (point.x + nextPoint.x); newY = 0.5 * (point.y + nextPoint.y); newY += dx * (Math.random() * 2 - 1); var newPoint = {x: newX, y: newY}; //min, max if (newY < minY) { minY = newY; } else if (newY > maxY) { maxY = newY; } //put between points newPoint.next = nextPoint; point.next = newPoint; point = nextPoint; } } //normalize to values between 0 and 1 if (maxY != minY) { var normalizeRate = 1 / (maxY - minY); point = pointList.first; while (point != null) { point.y = normalizeRate * (point.y - minY); point = point.next; } } //unlikely that max = min, but could happen if using zero iterations. In this case, set all points equal to 1. else { point = pointList.first; while (point != null) { point.y = 1; point = point.next; } } return pointList; } function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; displayWidth = canvas.width; displayHeight = canvas.height; generate(); } function generate() { context.clearRect(0, 0, displayWidth, displayHeight); var centerX, centerY; var r, g, b, a; var randColor, colorF, colorS; var lineW; var maxRad, minRad, maxRadC, maxRadR, baseDiam; var phase; if (displayWidth > 640){ //"responsive" baseDiam = 125; }else if(displayWidth >= 480 && displayWidth <= 640){ baseDiam = 90; }else{ baseDiam = 75; } var columns = Math.floor(displayWidth / baseDiam); var rows = Math.floor(displayHeight / baseDiam); var baseW = displayWidth / columns; var baseH = displayHeight / rows; lineW = 1.01; for (var i = 0; i < columns; i++) { for (var j = 0; j < rows; j++) { maxRadC = 0.8 * (0.5 * baseW); maxRadR = 0.8 * (0.5 * baseH); maxRad = Math.min(maxRadC, maxRadR); //pick lowest of the two minRad = 0.88 * maxRad; centerX = (baseW * i) + baseW/2; centerY = (baseH * j) + baseH/2; randColor = Math.floor(Math.random() * colorsA.length); colorF = colorsA[randColor]; colorS = colorsS[randColor]; phase = Math.random() * Math.PI * 2; context.beginPath(); context.rect(baseW*i, baseH*j, baseW, baseH); context.fillStyle = colorF; context.fill(); drawCircle(centerX, centerY, minRad, maxRad, phase, colorF, colorS, lineW); } } //draw main circle var mainDiameter, radius, grd; if (displayWidth <= displayHeight){ mainDiameter = displayWidth - 70; }else if (displayHeight <= displayWidth){ mainDiameter = displayHeight - 70; } centerX = displayWidth / 2; centerY = displayHeight / 2; radius = mainDiameter / 2; maxRad = 0.5 * mainDiameter; minRad = 0.88 * maxRad; phase = Math.random() * Math.PI * 2; colorF = colorsA[randColor]; colorS = colorsS[randColor]; lineW = 2.02; drawCircle(centerX, centerY, minRad, maxRad, phase, colorF, colorS, lineW); } function drawCircle(centerX, centerY, minRad, maxRad, phase, colorF, colorS, lineW) { var point; var rad, theta; var twoPi = 2 * Math.PI; var x0, y0; //generate the random function that will be used to vary the radius, 9 iterations of subdivision var pointList = setLinePoints(9); context.strokeStyle = colorS; context.lineWidth = lineW; context.fillStyle = 'rgba(225,225,225,' + (lineW * 0.2); for (var i = 0; i < (Math.floor(2 * lineW)); i++) { context.beginPath(); point = pointList.first; theta = phase; rad = minRad + point.y * (maxRad - minRad); x0 = centerX + rad * Math.cos(theta); y0 = centerY + rad * Math.sin(theta); context.lineTo(x0, y0); while (point.next != null) { point = point.next; theta = twoPi * point.x + phase; rad = minRad + point.y * (maxRad - minRad); x0 = centerX + rad * Math.cos(theta); y0 = centerY + rad * Math.sin(theta); context.lineTo(x0, y0); } context.stroke(); phase = Math.random() * Math.PI * 2; } context.fill(); }