// Modified from https://github.com/redlanta/react-jazzicon import React from 'react'; import Color from 'color'; import { Paper } from './Paper'; import { RNG } from './RNG'; const defaultColors = [ '#01888c', // teal '#fc7500', // bright orange '#034f5d', // dark teal '#E784BA', // light pink '#81C8B6', // bright green '#c7144c', // raspberry '#f3c100', // goldenrod '#1598f2', // lightning blue '#2465e1', // sail blue '#f19e02', // gold ]; const isColor = (str: string) => /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str); const isColors = (arr: Array) => { if (!Array.isArray(arr)) { return false; } if (arr.every(value => typeof value === 'string' && isColor(value))) { return true; } return false; }; interface Props { diameter: number; seed: number; paperStyles?: Object; svgStyles?: Object; shapeCount?: number; wobble?: number; colors?: Array; } // tslint:disable-next-line no-http-string const svgns = 'http://www.w3.org/2000/svg'; const shapeCount = 4; const wobble = 30; export class JazzIcon extends React.PureComponent { public render() { const { colors: customColors, diameter, paperStyles, seed, svgStyles, } = this.props; const generator = new RNG(seed); const colors = customColors || defaultColors; const newColours = this.hueShift( this.colorsForIcon(colors).slice(), generator ); const shapesArr = Array(shapeCount).fill(null); const shuffledColours = this.shuffleArray(newColours, generator); return ( {shapesArr.map((_, i) => this.genShape( shuffledColours[i + 1], diameter, i, shapeCount - 1, generator ) )} ); } private hueShift(colors: Array, generator: RNG) { const amount = generator.random() * 30 - wobble / 2; return colors.map(hex => Color(hex) .rotate(amount) .hex() ); } private genShape( colour: string, diameter: number, i: number, total: number, generator: RNG ) { const center = diameter / 2; const firstRot = generator.random(); const angle = Math.PI * 2 * firstRot; const velocity = diameter / total * generator.random() + i * diameter / total; const tx = Math.cos(angle) * velocity; const ty = Math.sin(angle) * velocity; const translate = `translate(${tx} ${ty})`; // Third random is a shape rotation on top of all of that. const secondRot = generator.random(); const rot = firstRot * 360 + secondRot * 180; const rotate = `rotate(${rot.toFixed(1)} ${center} ${center})`; const transform = `${translate} ${rotate}`; return ( ); } private colorsForIcon(arr: Array) { if (isColors(arr)) { return arr; } return defaultColors; } private shuffleArray(array: Array, generator: RNG) { let currentIndex = array.length; const newArray = [...array]; // While there remain elements to shuffle... while (currentIndex > 0) { // Pick a remaining element... const randomIndex = generator.next() % currentIndex; currentIndex -= 1; // And swap it with the current element. const temporaryValue = newArray[currentIndex]; newArray[currentIndex] = newArray[randomIndex]; newArray[randomIndex] = temporaryValue; } return newArray; } }