diff --git a/public/index.html b/public/index.html index 731a5c4..2c82e7c 100644 --- a/public/index.html +++ b/public/index.html @@ -9,7 +9,9 @@ - + + + diff --git a/src/firefly.ts b/src/Classes/firefly.ts similarity index 96% rename from src/firefly.ts rename to src/Classes/firefly.ts index 231af57..bc41065 100644 --- a/src/firefly.ts +++ b/src/Classes/firefly.ts @@ -88,7 +88,10 @@ class FireFly { speedY: 0, accelerationX: 0, accelerationY: 0, - quarterCircleCenterLocation: "bottom-left" + quarterCircleCenterLocation: "bottom-left", + wind: new Wind(windConfig), + windResistance: 0, + windAffectStrength: 0 } this.config = this.initializedConfig @@ -117,6 +120,8 @@ class FireFly { : startingAngle } + const fireflySize = this.utilGetRandomNumberBetween(size) + this.config = { x: 0, y: 0, @@ -156,12 +161,15 @@ class FireFly { ), opacityChangeMode, // size gets randomized based on your config - size: this.utilGetRandomNumberBetween(size), + size: fireflySize, speedX: this.utilGetRandomNumberBetween(speedX), speedY: this.utilGetRandomNumberBetween(speedY), // Where the center of the quarter circle is located - quarterCircleCenterLocation: getQuarterCircleCenterLocation() + quarterCircleCenterLocation: getQuarterCircleCenterLocation(), + wind: new Wind(windConfig), + windResistance: 0, + windAffectStrength: 0 } const { x: startingX, y: startingY } = this.getNewPosition( @@ -957,6 +965,25 @@ class FireFly { this.config.rotationSpeed += this.config.rotationAcceleration } + handleWind = () => { + const { wind, windAffectStrength } = this.config + if (wind) { + this.config.windAffectStrength = + wind.windConfig.calculateWindAffectionFunction( + wind.config.sourceX, + wind.config.sourceY, + this.config.x, + this.config.y, + this.canvasSize.width, + this.canvasSize.height + ) + this.config.x += + (windAffectStrength - this.config.windResistance) * wind.config.speedX + this.config.y += + (windAffectStrength - this.config.windResistance) * wind.config.speedY + } + } + update(ctx: CanvasRenderingContext2D, hueShiftAmount: number) { this.draw(ctx, hueShiftAmount) this.handleRotation() @@ -965,6 +992,7 @@ class FireFly { // handle Opacity change if (this.config.opacityChangeMode === "fade") this.handleFade() else this.handleGlow() + this.handleWind() this.handleMove() this.handleAcceleration() diff --git a/src/Classes/wind.ts b/src/Classes/wind.ts new file mode 100644 index 0000000..88d90da --- /dev/null +++ b/src/Classes/wind.ts @@ -0,0 +1,57 @@ +class Wind { + windConfig: WindConfigType + config + constructor(windConfig: WindConfigType) { + this.windConfig = windConfig + this.config = { + speedX: this.utilGetRandomNumberBetween(windConfig.speedX), + speedY: this.utilGetRandomNumberBetween(windConfig.speedY), + sourceX: this.utilGetRandomNumberBetween({ + min: 0, + max: config.canvasSize.width + }), + sourceY: this.utilGetRandomNumberBetween({ + min: 0, + max: config.canvasSize.height + }) + } + + this.updateWind() + } + + utilGetRandomNumberBetween = ( + range: RangeType, + getAsInteger: boolean = false + ) => { + const { min, max } = range + return getAsInteger + ? Math.floor(Math.random() * (max - min + 1)) + min + : Math.random() * (max - min) + min + } + + affectFirefly(firefly: FireFly, strength: number = 1) { + firefly.config.wind = this + firefly.config.windAffectStrength = strength + } + + updateWind() { + setInterval(() => { + this.config.sourceX = this.utilGetRandomNumberBetween({ + min: 0, + max: config.canvasSize.width + }) + + this.config.sourceY = this.utilGetRandomNumberBetween({ + min: 0, + max: config.canvasSize.height + }) + + this.config.speedX = this.utilGetRandomNumberBetween( + this.windConfig.speedX + ) + this.config.speedY = this.utilGetRandomNumberBetween( + this.windConfig.speedY + ) + }, this.windConfig.speedResetInterval) + } +} diff --git a/src/Config/boundsConfig.ts b/src/Config/boundsConfig.ts index da90502..ef0eee5 100644 --- a/src/Config/boundsConfig.ts +++ b/src/Config/boundsConfig.ts @@ -1,6 +1,6 @@ const boundsConfig: BoundsConfigType = { toggleBounds: { - top: true, + top: false, right: false, bottom: true, left: false @@ -8,7 +8,7 @@ const boundsConfig: BoundsConfigType = { afterImpactSpeedMultiplier: { top: 1, right: 1, - bottom: 1, + bottom: 0.75, left: 1 }, hueIncreaseAmountAfterImpact: { diff --git a/src/Config/fadeConfig.ts b/src/Config/fadeConfig.ts index b3d5898..ce3ad64 100644 --- a/src/Config/fadeConfig.ts +++ b/src/Config/fadeConfig.ts @@ -1,7 +1,7 @@ const fadeConfig: OpacityChangeConfigType = { rate: { - min: 0, - max: 0 + min: 0.001, + max: 0.009 }, // TODO: change this to new opacity after fade (and grow) @@ -14,12 +14,12 @@ const fadeConfig: OpacityChangeConfigType = { x: 0, y: 0 }, - positioningMethod: "randomX", + positioningMethod: "random", resetColorAfterOpacityChange: true, resetRateAfterOpacityChange: true, resetSizeAfterOpacityChange: true, sizeChange: { - mode: "none", + mode: "grow", frequency: 1 } } diff --git a/src/Config/glowConfig.ts b/src/Config/glowConfig.ts index 854c0d2..1e5eef5 100644 --- a/src/Config/glowConfig.ts +++ b/src/Config/glowConfig.ts @@ -1,7 +1,7 @@ const glowConfig: OpacityChangeConfigType = { rate: { min: 0.003, - max: 0.012 + max: 0.009 }, opacityAfterOpacityChange: { @@ -17,7 +17,7 @@ const glowConfig: OpacityChangeConfigType = { resetRateAfterOpacityChange: true, resetSizeAfterOpacityChange: false, sizeChange: { - mode: "grow", + mode: "none", frequency: 1 } } diff --git a/src/Config/movementConfig.ts b/src/Config/movementConfig.ts index 2deb794..ff3ab28 100644 --- a/src/Config/movementConfig.ts +++ b/src/Config/movementConfig.ts @@ -1,7 +1,7 @@ const movementConfig: MovementConfigType = { speedX: { - min: 1, - max: 5 + min: 0, + max: 0 }, speedY: { min: 0, @@ -14,7 +14,7 @@ const movementConfig: MovementConfigType = { }, accelerationY: { min: 0, - max: 0 + max: 0.4 }, accelerateInCurrentMovingDirection: false, diff --git a/src/Config/opacityChangeOptionsConfig.ts b/src/Config/opacityChangeOptionsConfig.ts index e529ce3..3ee254a 100644 --- a/src/Config/opacityChangeOptionsConfig.ts +++ b/src/Config/opacityChangeOptionsConfig.ts @@ -1,5 +1,5 @@ const opacityChangeOptionsConfig: OpacityChangeOptionsConfigType = { - fadeRatio: 1, + fadeRatio: 0, fade: fadeConfig, glow: glowConfig diff --git a/src/Config/shapingConfig.ts b/src/Config/shapingConfig.ts index 8a5f931..edf84f2 100644 --- a/src/Config/shapingConfig.ts +++ b/src/Config/shapingConfig.ts @@ -1,5 +1,5 @@ const shapingConfig: ShapingConfigType = { - shape: "regularPolygon", + shape: "circle", regularPolygon: { sideCount: { min: 3, diff --git a/src/Config/windConfig.ts b/src/Config/windConfig.ts new file mode 100644 index 0000000..37b7830 --- /dev/null +++ b/src/Config/windConfig.ts @@ -0,0 +1,23 @@ +const windConfig: WindConfigType = { + speedX: { + min: -10, + max: 10 + }, + speedY: { + min: -10, + max: 10 + }, + speedResetInterval: 3000, + calculateWindAffectionFunction: ( + sourceX: number, + sourceY: number, + x: number, + y: number, + width: number, + height: number + ) => { + return ( + (1 - Math.abs(x - sourceX) / width) * (1 - Math.abs(y - sourceY) / height) + ) + } +} diff --git a/src/Interfaces/IConfig.ts b/src/Interfaces/IConfig.ts index 871ce4d..faf38c3 100644 --- a/src/Interfaces/IConfig.ts +++ b/src/Interfaces/IConfig.ts @@ -3,6 +3,8 @@ interface IConfig { rainbowMode: boolean // true = rainbow mode, false = normal mode skyColor: IHSLColor + + wind: WindConfigType fireflies: { // Number of fireflies count: number diff --git a/src/Interfaces/ISingleFireflyConfig.ts b/src/Interfaces/ISingleFireflyConfig.ts index 64c17d1..b738938 100644 --- a/src/Interfaces/ISingleFireflyConfig.ts +++ b/src/Interfaces/ISingleFireflyConfig.ts @@ -35,4 +35,13 @@ interface ISingleFireflyConfig { jitterY: number quarterCircleCenterLocation: TwoDimentionalDirectionType + + // wind properties will be set once wind object is created + wind: Wind + + // how much firefly resists wind [0-1] + windResistance: number + + // how much firefly is affected by wind [0-1] + windAffectStrength: number } diff --git a/src/Types/WindConfigType.ts b/src/Types/WindConfigType.ts new file mode 100644 index 0000000..f745e30 --- /dev/null +++ b/src/Types/WindConfigType.ts @@ -0,0 +1,13 @@ +type WindConfigType = { + speedX: RangeType + speedY: RangeType + speedResetInterval: number + calculateWindAffectionFunction: ( + sourceX: number, + sourceY: number, + x: number, + y: number, + width: number, + height: number + ) => number +} diff --git a/src/config.ts b/src/config.ts index 2731d7c..263cdef 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,12 +8,14 @@ const config: IConfig = { l: 0, a: 1 }, + wind: windConfig, + fireflies: { - count: 3000, + count: 500, size: { - min: 4, - max: 50 + min: 1, + max: 30 }, movement: movementConfig, diff --git a/src/index.ts b/src/index.ts index 0913b92..57e6124 100644 --- a/src/index.ts +++ b/src/index.ts @@ -69,10 +69,13 @@ const addCanvas = ( } let fireflies: FireFly[] = [] + const wind = new Wind(finalConfig.wind) // creating fireflies based on finalConfig for (let i = 0; i < finalConfig.fireflies.count; i++) { - fireflies.push(new FireFly(finalConfig)) + const newFirefly = new FireFly(finalConfig) + wind.affectFirefly(newFirefly, newFirefly.config.x / canvasSize.width) + fireflies.push(newFirefly) } // ============== TEST ============*/ @@ -170,7 +173,9 @@ const addCanvas = ( ctx.fillRect(0, 0, canvasSize.width, canvasSize.height) // Fireflies - fireflies.forEach(firefly => firefly.update(ctx, hueShiftAmount)) + for (let i = 0; i < fireflies.length; i++) { + fireflies[i].update(ctx, hueShiftAmount) + } // requestAnimationFrame causes the browser to call the function again and again requestAnimationFrame(render)