D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
bhvaleri
Full window
Github gist
Wall of Clocks 2
<!DOCTYPE html> <html> <head> <title>Wall of Clocks 2</title> <script src="https://d3js.org/d3.v4.min.js"></script> </head> <body> <script> const margin = { top: 0, right: 0, bottom: 0, left: 0 }; const startingWindowWidth = window.innerWidth, startingWindowHeight = window.innerHeight; const width = startingWindowWidth - margin.left - margin.right, height = startingWindowHeight - margin.top - margin.bottom; const svg = d3.select('body').append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom); const clocksGroup = svg.append('g') .attr('transform', `translate(${margin.left},${margin.top})`); // const radius = width / 4; const x1 = 0; const y1 = 0; const strokeWidth = 4; function secondsToLine(seconds, radius) { // each second gets 6 degrees // force clock wise // ask Colin why this works? const angle = -((seconds * (2 * Math.PI) / 60) - (Math.PI / 2)); return { x2: Math.cos(angle) * radius, y2: -(Math.sin(angle) * radius) } } let clockCounter = 0; function addClock(startingSeconds, startingMinutes, radius, translateX, translateY) { const clock = clocksGroup.append('g').attr('transform', `translate(${translateX},${translateY})`); clock.append('circle') .attr('cx', x1) .attr('cy', y1) .attr('r', radius) .style('fill', 'none') .style('stroke-width', strokeWidth) .style('stroke', 'black'); const startingSecondsCoordinates = secondsToLine(startingSeconds, radius); const secondHandClassName = `second-hand-${clockCounter}`; const minuteHandClassName = `minute-hand-${clockCounter}`; clockCounter++; const secondHand = clock.append('line') .attr('class', `second-hand ${secondHandClassName}`) .attr('x1', x1) .attr('x2', startingSecondsCoordinates.x2) .attr('y1', y1) .attr('y2', startingSecondsCoordinates.y2) .style('stroke', 'black') .style('stroke-width', strokeWidth); let secondCount = startingSeconds; setInterval(() => { secondCount = (secondCount + 1) % 60; const newCoordinates = secondsToLine(secondCount, radius); d3.select(`.${secondHandClassName}`) .transition() .attr('x2', newCoordinates.x2) .attr('y2', newCoordinates.y2); }, 100) const startingMinutesCoordinates = secondsToLine(startingSeconds, radius); const minuteHand = clock.append('line') .attr('class', `minute-hand ${minuteHandClassName}`) .attr('x1', x1) .attr('x2', startingMinutesCoordinates.x2) .attr('y1', y1) .attr('y2', startingMinutesCoordinates.y2) .style('stroke', 'black') .style('stroke-width', strokeWidth); let minuteCount = startingMinutes; setInterval(() => { minuteCount = (minuteCount + 1) % 60; const newCoordinates = secondsToLine(minuteCount, radius); d3.select(`.${minuteHandClassName}`) .transition() .attr('x2', newCoordinates.x2) .attr('y2', newCoordinates.y2); }, 300) }; const circleRadius = 50; // lets create a grid! const gridDimensions = { m: Math.floor(width / (circleRadius * 2)), n: Math.floor(height / (circleRadius * 2)) } let startingSeconds = 0; let startingMinutes = 0; for(let i = 0; i < gridDimensions.m; i++) { for(let j = 0; j < gridDimensions.n; j++) { addClock(startingSeconds++, startingMinutes++, circleRadius, (circleRadius*2*i) + circleRadius, (circleRadius*2*j) + circleRadius); } } </script> </body> </html>
https://d3js.org/d3.v4.min.js