diff options
Diffstat (limited to 'html/simple-shape/index.html')
-rw-r--r-- | html/simple-shape/index.html | 467 |
1 files changed, 1 insertions, 466 deletions
diff --git a/html/simple-shape/index.html b/html/simple-shape/index.html index 4e4fa49..91a68a3 100644 --- a/html/simple-shape/index.html +++ b/html/simple-shape/index.html @@ -53,471 +53,6 @@ <div class="canvas-container"> <canvas id="canvas"></canvas> </div> - <script> - /** - * Configuration object for application-wide settings - * Centralizes magic numbers and configuration values - * @constant {Object} - */ - const CONFIG = { - canvas: { - dpi: 300, - width: 8.5 * 300, // 8.5in at 300dpi - height: 11 * 300, // 11in at 300dpi - }, - grid: { - rows: 4, - columns: 5, - topMargin: 100, - bottomMargin: 300, - patternSize: 400, - gutterRatio: 0.1, // 10% of pattern size - patternRatio: 0.8 // 80% of space for pattern - }, - style: { - strokeWidth: 4, - strokeColor: '#000' - } - }; - - /** - * Canvas Setup and Configuration - * This section initializes a high-resolution canvas optimized for both screen display and printing. - */ - const canvas = document.getElementById('canvas'); - const ctx = canvas.getContext('2d'); - - canvas.width = CONFIG.canvas.width; - canvas.height = CONFIG.canvas.height; - - /** - * Utility Functions Module - * Pure functions for common operations - * @namespace Utils - */ - const Utils = { - /** - * Generates a random number within a range - * @param {number} min - Minimum value - * @param {number} max - Maximum value - * @returns {number} - */ - random: (min, max) => Math.random() * (max - min) + min, - - /** - * Generates a random integer within a range - * @param {number} min - Minimum value - * @param {number} max - Maximum value - * @returns {number} - */ - randomInt: (min, max) => Math.floor(Utils.random(min, max)), - - /** - * Randomly selects an item from an array - * @param {Array} arr - Source array - * @returns {*} - */ - randomChoice: arr => arr[Math.floor(Math.random() * arr.length)], - - /** - * Fisher-Yates shuffle implementation - * @param {Array} arr - Array to shuffle - * @returns {Array} New shuffled array - */ - shuffle: arr => [...arr].sort(() => Math.random() - 0.5), - - /** - * Creates a range array of numbers - * @param {number} start - Start value - * @param {number} end - End value - * @returns {Array<number>} - */ - range: (start, end) => Array.from( - { length: end - start }, - (_, i) => start + i - ) - }; - - /** - * Drawing Context Manager - * Handles canvas context state management using functional composition - * @namespace ContextManager - */ - const ContextManager = { - /** - * Executes a drawing operation with saved context state - * @param {Function} drawFn - Drawing function to execute - * @returns {Function} - */ - withContext: drawFn => (...args) => { - ctx.save(); - drawFn(...args); - ctx.restore(); - }, - - /** - * Applies a translation transformation - * @param {number} x - X translation - * @param {number} y - Y translation - * @returns {Function} - */ - withTranslation: (x, y) => drawFn => (...args) => { - ctx.translate(x, y); - drawFn(...args); - }, - - /** - * Applies a rotation transformation around a point - * @param {number} angle - Rotation angle in radians - * @param {number} x - Center X coordinate - * @param {number} y - Center Y coordinate - * @returns {Function} - */ - withRotation: (angle, x, y) => drawFn => (...args) => { - ctx.translate(x, y); - ctx.rotate(angle); - ctx.translate(-x, -y); - drawFn(...args); - } - }; - - /** - * Shape Factory Pattern - * @namespace Shapes - */ - const Shapes = { - /** - * Creates a circle with optional fill - * @param {number} x - Center X coordinate - * @param {number} y - Center Y coordinate - * @param {number} size - Reference size for radius calculation - * @param {Object} params - Optional parameters for customization - * @param {number} [params.radius] - Optional explicit radius - * @param {boolean} [params.fill] - Whether to fill the circle - */ - circle: (x, y, size, params = {}) => { - const radius = params.radius || size/3; - ctx.beginPath(); - ctx.arc(x, y, radius, 0, Math.PI * 2); - params.fill ? ctx.fill() : ctx.stroke(); - }, - - line: (x1, y1, x2, y2) => { - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.stroke(); - }, - - triangle: (x, y, size) => { - ctx.beginPath(); - ctx.moveTo(x, y + size); - ctx.lineTo(x + size/2, y); - ctx.lineTo(x + size, y + size); - ctx.closePath(); - ctx.stroke(); - }, - - square: (x, y, size) => { - ctx.strokeRect(x, y, size, size); - } - }; - - /** - * Pattern Generator System - * @namespace Patterns - */ - const Patterns = { - /** - * Creates a pattern generator with transformation capabilities - * @param {Function} patternFn - Base pattern drawing function - * @returns {Function} Enhanced pattern generator - */ - createGenerator: patternFn => { - return ContextManager.withContext((x, y, size) => { - const rotation = Math.PI/2 * Utils.randomInt(0, 4); - if (rotation > 0) { - ContextManager.withRotation( - rotation, - x + size/2, - y + size/2 - )(patternFn)(x, y, size); - } else { - patternFn(x, y, size); - } - }); - }, - - /** - * Collection of base pattern implementations - * @type {Array<Function>} - */ - types: [ - /** - * Grid-based pattern strategy - * Demonstrates use of nested loops for regular grid generation - * @param {number} x - Starting X coordinate - * @param {number} y - Starting Y coordinate - * @param {number} size - Pattern size - */ - (x, y, size) => { - const spacing = size/3; - for(let i = 0; i < 3; i++) { - for(let j = 0; j < 3; j++) { - if((i + j) % 2 === 0) { // Checkerboard pattern - Shapes.circle( - x + spacing/2 + i * spacing, - y + spacing/2 + j * spacing, - spacing/2 - ); - } - } - } - }, - - // Nested squares - (x, y, size) => { - for(let i = 3; i > 0; i--) { - const offset = (3 - i) * size/6; - const squareSize = size - offset * 2; - Shapes.square(x + offset, y + offset, squareSize); - } - }, - - // Simple flower pattern - (x, y, size) => { - const center = size/2; - const radius = size/4; - - // Center circle - Shapes.circle(x + center, y + center, size/6); - - // Petals - for(let i = 0; i < 6; i++) { - const angle = (i / 6) * Math.PI * 2; - const petalX = x + center + Math.cos(angle) * radius; - const petalY = y + center + Math.sin(angle) * radius; - Shapes.circle(petalX, petalY, size/6); - } - }, - - // Triangles in a row - (x, y, size) => { - const triSize = size/3; - for(let i = 0; i < 3; i++) { - Shapes.triangle( - x + i * triSize, - y + (i % 2) * triSize/2, - triSize - ); - } - }, - - // Simple grid of squares - (x, y, size) => { - const gridSize = size/2; - for(let i = 0; i < 2; i++) { - for(let j = 0; j < 2; j++) { - Shapes.square( - x + i * gridSize + size/8, - y + j * gridSize + size/8, - gridSize * 0.75 - ); - } - } - }, - - // Alternating circles and squares - (x, y, size) => { - const spacing = size/2; - for(let i = 0; i < 2; i++) { - for(let j = 0; j < 2; j++) { - if((i + j) % 2 === 0) { - Shapes.circle( - x + spacing/2 + i * spacing, - y + spacing/2 + j * spacing, - spacing/3 - ); - } else { - Shapes.square( - x + i * spacing + spacing/6, - y + j * spacing + spacing/6, - spacing * 2/3 - ); - } - } - } - }, - - // Simple star pattern - (x, y, size) => { - const center = size/2; - // Horizontal and vertical lines - Shapes.line(x, y + center, x + size, y + center); - Shapes.line(x + center, y, x + center, y + size); - // Diagonal lines - Shapes.line(x, y, x + size, y + size); - Shapes.line(x + size, y, x, y + size); - }, - - // Nested arcs - (x, y, size) => { - const center = size/2; - for(let i = 1; i <= 4; i++) { - const radius = (size/2) * (i/4); - ctx.beginPath(); - ctx.arc(x + center, y + center, radius, 0, Math.PI); - ctx.stroke(); - } - }, - - // Quarter circles in corners - (x, y, size) => { - const radius = size/2; - // Top left - ctx.beginPath(); - ctx.arc(x, y, radius, 0, Math.PI/2); - ctx.stroke(); - // Top right - ctx.beginPath(); - ctx.arc(x + size, y, radius, Math.PI/2, Math.PI); - ctx.stroke(); - // Bottom right - ctx.beginPath(); - ctx.arc(x + size, y + size, radius, Math.PI, Math.PI * 3/2); - ctx.stroke(); - // Bottom left - ctx.beginPath(); - ctx.arc(x, y + size, radius, Math.PI * 3/2, Math.PI * 2); - ctx.stroke(); - }, - - // Concentric circles - (x, y, size) => { - const center = size/2; - for(let i = 1; i <= 3; i++) { - Shapes.circle( - x + center, - y + center, - size, - {radius: (size/2) * (i/3)} - ); - } - }, - - // Nested diamonds - (x, y, size) => { - const center = size/2; - for(let i = 1; i <= 3; i++) { - const offset = (size/2) * (i/3); - ctx.beginPath(); - ctx.moveTo(x + center, y + center - offset); - ctx.lineTo(x + center + offset, y + center); - ctx.lineTo(x + center, y + center + offset); - ctx.lineTo(x + center - offset, y + center); - ctx.closePath(); - ctx.stroke(); - } - }, - - // Radiating arcs - (x, y, size) => { - const center = size/2; - const radius = size/3; - for(let i = 0; i < 4; i++) { - const startAngle = (Math.PI/2) * i; - ctx.beginPath(); - ctx.arc(x + center, y + center, radius, startAngle, startAngle + Math.PI/2); - ctx.stroke(); - } - }, - - // Stacked semicircles - (x, y, size) => { - const width = size * 0.8; - for(let i = 0; i < 3; i++) { - ctx.beginPath(); - ctx.arc( - x + size/2, - y + (size/3) * (i + 1), - width/2, - 0, - Math.PI, - i % 2 === 0 - ); - ctx.stroke(); - } - } - ] - }; - - /** - * Layout System - * Handles grid layout and composition - * @namespace Layout - */ - const Layout = { - /** - * Calculates layout metrics for the grid - * @returns {Object} Layout calculations - */ - calculateMetrics: () => { - const availableHeight = CONFIG.canvas.height - - (CONFIG.grid.topMargin + CONFIG.grid.bottomMargin); - - const totalPatternHeight = CONFIG.grid.rows * CONFIG.grid.patternSize; - const totalGapHeight = availableHeight - totalPatternHeight; - const rowGap = totalGapHeight / (CONFIG.grid.rows - 1); - - const totalWidth = CONFIG.grid.patternSize * CONFIG.grid.columns; - const xOffset = (CONFIG.canvas.width - totalWidth) / 2; - - return { rowGap, xOffset }; - }, - - /** - * Draws a row of patterns - */ - drawRow: (xOffset, y, size) => { - const gutter = size * CONFIG.grid.gutterRatio; - const patternSize = size * CONFIG.grid.patternRatio; - - const patterns = Utils.shuffle(patternGenerators); - Utils.range(0, CONFIG.grid.columns).forEach(i => { - const xPos = xOffset + i * size + gutter; - const yPos = y + gutter; - patterns[i](xPos, yPos, patternSize); - }); - }, - - /** - * Draws the complete grid - */ - drawGrid: () => { - ctx.clearRect(0, 0, CONFIG.canvas.width, CONFIG.canvas.height); - - ctx.strokeStyle = CONFIG.style.strokeColor; - ctx.lineWidth = CONFIG.style.strokeWidth; - - const { rowGap, xOffset } = Layout.calculateMetrics(); - - Utils.range(0, CONFIG.grid.rows).forEach(i => { - const y = CONFIG.grid.topMargin + - i * (CONFIG.grid.patternSize + rowGap); - Layout.drawRow(xOffset, y, CONFIG.grid.patternSize); - }); - } - }; - - // Generate pattern instances - const patternGenerators = Utils.range(0, 10) - .map(() => Patterns.createGenerator( - Utils.randomChoice(Patterns.types) - )); - - // Initialize and set up interaction - Layout.drawGrid(); - canvas.addEventListener('click', Layout.drawGrid); - </script> + <script src="app.js"></script> </body> </html> \ No newline at end of file |