From 9f044cbc888201e72a247fd334fbf43058bdfa1a Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Tue, 15 Jun 2021 13:56:34 +0100 Subject: [PATCH 01/13] add heart effect --- src/effects/hearts/index.ts | 192 ++++++++++++++++++++++++++++++++++++ src/effects/index.ts | 12 +++ src/i18n/strings/en_EN.json | 2 + 3 files changed, 206 insertions(+) create mode 100644 src/effects/hearts/index.ts diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts new file mode 100644 index 00000000000..a0094693553 --- /dev/null +++ b/src/effects/hearts/index.ts @@ -0,0 +1,192 @@ +/* + Copyright 2021 The Matrix.org Foundation C.I.C. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +import ICanvasEffect from '../ICanvasEffect'; +import { arrayFastClone } from "../../utils/arrays"; + +export type HeartOptions = { + /** + * The maximum number of hearts to render at a given time + */ + maxCount: number; + /** + * The amount of gravity to apply to the hearts + */ + gravity: number; + /** + * The maximum amount of drift (horizontal sway) to apply to the hearts. Each heart varies. + */ + maxDrift: number; + /** + * The maximum amount of tilt to apply to the heart. Each heart varies. + */ + maxRot: number; +} + +type Heart = { + x: number; + y: number; + xCol: number; + scale: number; + maximumDrift: number; + maximumRot: number; + gravity: number; + color: string, +} + +export const DefaultOptions: HeartOptions = { + maxCount: 120, + gravity: 3.2, + maxDrift: 5, + maxRot: 5, +}; + +const KEY_FRAME_INTERVAL = 15; // 15ms, roughly + +export default class Hearts implements ICanvasEffect { + private readonly options: HeartOptions; + + constructor(options: { [key: string]: any }) { + this.options = { ...DefaultOptions, ...options }; + } + + private context: CanvasRenderingContext2D | null = null; + private particles: Array = []; + private lastAnimationTime: number; + + private colours = [ + 'rgba(194,210,224,1)', + 'rgba(235,214,219,1)', + 'rgba(255,211,45,1)', + 'rgba(255,190,174,1)', + 'rgba(255,173,226,1)', + 'rgba(242,114,171,1)', + 'rgba(228,55,116,1)', + 'rgba(255,86,130,1)', + 'rgba(244,36,57,1)', + 'rgba(247,126,157,1)',//w + 'rgba(243,142,140,1)', + 'rgba(252,116,183,1)']; + + public isRunning: boolean; + + public start = async (canvas: HTMLCanvasElement, timeout = 3000) => { + if (!canvas) { + return; + } + this.context = canvas.getContext('2d'); + this.particles = []; + const count = this.options.maxCount; + while (this.particles.length < count) { + this.particles.push(this.resetParticle({} as Heart, canvas.width, canvas.height)); + } + this.isRunning = true; + requestAnimationFrame(this.renderLoop); + if (timeout) { + window.setTimeout(this.stop, timeout); + } + } + + public stop = async () => { + this.isRunning = false; + } + + private resetParticle = (particle: Heart, width: number, height: number): Heart => { + particle.color = this.colours[(Math.random() * this.colours.length) | 0]; + particle.x = Math.random() * width; + particle.y = Math.random() * height + height; + particle.xCol = particle.x; + particle.scale = (Math.random() * 0.07) + 0.04; + particle.maximumDrift = (Math.random() * this.options.maxDrift) + 3.5; + particle.maximumRot = (Math.random() * this.options.maxRot) + 3.5; + particle.gravity = this.options.gravity + (Math.random() * 4.8); + return particle; + } + + private renderLoop = (): void => { + if (!this.context || !this.context.canvas) { + return; + } + if (this.particles.length === 0) { + this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); + } else { + const timeDelta = Date.now() - this.lastAnimationTime; + if (timeDelta >= KEY_FRAME_INTERVAL || !this.lastAnimationTime) { + // Clear the screen first + this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); + + this.lastAnimationTime = Date.now(); + this.animateAndRenderSnowflakes(); + } + requestAnimationFrame(this.renderLoop); + } + }; + + private animateAndRenderSnowflakes() { + if (!this.context || !this.context.canvas) { + return; + } + const height = this.context.canvas.height; + for (const particle of arrayFastClone(this.particles)) { + particle.y -= particle.gravity; + + // We treat the drift as a sine function to have a more fluid-like movement instead + // of a pong-like movement off walls of the X column. This means that for + // $x=A\sin(\frac{2\pi}{P}y)$ we use the `maximumDrift` as the amplitude (A) and a + // large multiplier to create a very long waveform through P. + const peakDistance = 75 * particle.maximumDrift; + const PI2 = Math.PI * 2; + particle.x = 6 * particle.maximumDrift * Math.sin(0.7 * (PI2 / peakDistance) * particle.y); + particle.x += particle.xCol; // bring the particle to the right place + + let posScale = 1 / particle.scale; + let x = particle.x * posScale; + let y = particle.y * posScale; + + this.context.save(); + this.context.scale(particle.scale, particle.scale); + this.context.beginPath(); + + // Rotate the heart about its centre. + // The tilt of the heart is modelled similarly to its horizontal drift, + // using a sine function. + this.context.translate(248 + x, 215 + y); + this.context.rotate((1 / 10) * particle.maximumRot * Math.sin((PI2 / peakDistance) * particle.y * 0.8)); + this.context.translate(-248 - x, -215 - y); + + // Use bezier curves to draw a heart using pre-calculated coordinates. + this.context.moveTo(140 + x, 20 + y); + this.context.bezierCurveTo(73 + x, 20 + y, 20 + x, 74 + y, 20 + x, 140 + y); + this.context.bezierCurveTo(20 + x, 275 + y, 156 + x, 310 + y, 248 + x, 443 + y); + this.context.bezierCurveTo(336 + x, 311 + y, 477 + x, 270 + y, 477 + x, 140 + y); + this.context.bezierCurveTo(477 + x, 74 + y, 423 + x, 20 + y, 357 + x, 20 + y); + this.context.bezierCurveTo(309 + x, 20 + y, 267 + x, 48 + y, 248 + x, 89 + y); + this.context.bezierCurveTo(229 + x, 48 + y, 188 + x, 20 + y, 140 + x, 20 + y); + this.context.closePath(); + + this.context.fillStyle = particle.color; + this.context.fill(); + + this.context.restore(); + + // Remove any dead hearts after a 100px wide margin. + if (particle.y < -100 ) { + console.log("disappear") + const idx = this.particles.indexOf(particle); + this.particles.splice(idx, 1); + } + } + } +} diff --git a/src/effects/index.ts b/src/effects/index.ts index 8ecb80020d4..be1ab9c43e0 100644 --- a/src/effects/index.ts +++ b/src/effects/index.ts @@ -20,6 +20,7 @@ import { Effect } from "./effect"; import { FireworksOptions } from "./fireworks"; import { SnowfallOptions } from "./snowfall"; import { SpaceInvadersOptions } from "./spaceinvaders"; +import { HeartOptions } from "./hearts"; /** * This configuration defines room effects that can be triggered by custom message types and emojis @@ -73,6 +74,17 @@ export const CHAT_EFFECTS: Array> = [ gravity: 0.01, }, } as Effect, + { + emojis: ["💝", "💖", "💞", "💕"], + msgType: "io.element.effect.hearts", + command: "hearts", + description: () => _td("Sends the given message with hearts"), + fallbackMessage: () => _t("sends hearts") + " 💝", + options: { + maxCount: 120, + gravity: 3.2, + }, + } as Effect, ]; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 17d6f64c460..def5c093646 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -889,6 +889,8 @@ "sends snowfall": "sends snowfall", "Sends the given message with a space themed effect": "Sends the given message with a space themed effect", "sends space invaders": "sends space invaders", + "Sends the given message with hearts": "Sends the given message with hearts", + "sends hearts": "sends hearts", "unknown person": "unknown person", "Consulting with %(transferTarget)s. Transfer to %(transferee)s": "Consulting with %(transferTarget)s. Transfer to %(transferee)s", "You held the call Switch": "You held the call Switch", From 4d8aecf02363ef11418f94e77d24a774b780b1ee Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Tue, 15 Jun 2021 14:09:45 +0100 Subject: [PATCH 02/13] clean up syntax --- src/effects/hearts/index.ts | 6 ++---- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts index a0094693553..6a3705d20e0 100644 --- a/src/effects/hearts/index.ts +++ b/src/effects/hearts/index.ts @@ -128,17 +128,16 @@ export default class Hearts implements ICanvasEffect { this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); this.lastAnimationTime = Date.now(); - this.animateAndRenderSnowflakes(); + this.animateAndRenderHearts(); } requestAnimationFrame(this.renderLoop); } }; - private animateAndRenderSnowflakes() { + private animateAndRenderHearts() { if (!this.context || !this.context.canvas) { return; } - const height = this.context.canvas.height; for (const particle of arrayFastClone(this.particles)) { particle.y -= particle.gravity; @@ -183,7 +182,6 @@ export default class Hearts implements ICanvasEffect { // Remove any dead hearts after a 100px wide margin. if (particle.y < -100 ) { - console.log("disappear") const idx = this.particles.indexOf(particle); this.particles.splice(idx, 1); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index def5c093646..53d27270b71 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -889,7 +889,7 @@ "sends snowfall": "sends snowfall", "Sends the given message with a space themed effect": "Sends the given message with a space themed effect", "sends space invaders": "sends space invaders", - "Sends the given message with hearts": "Sends the given message with hearts", + "Sends the given message with hearts": "Sends the given message with hearts", "sends hearts": "sends hearts", "unknown person": "unknown person", "Consulting with %(transferTarget)s. Transfer to %(transferee)s": "Consulting with %(transferTarget)s. Transfer to %(transferee)s", From 08c16946774f8748d3e98eebef99cc614dd61ae8 Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Tue, 15 Jun 2021 14:14:38 +0100 Subject: [PATCH 03/13] convert indentation to spaces --- src/effects/hearts/index.ts | 318 ++++++++++++++++++------------------ src/effects/index.ts | 4 +- 2 files changed, 160 insertions(+), 162 deletions(-) diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts index 6a3705d20e0..c971b79eba4 100644 --- a/src/effects/hearts/index.ts +++ b/src/effects/hearts/index.ts @@ -17,174 +17,174 @@ import ICanvasEffect from '../ICanvasEffect'; import { arrayFastClone } from "../../utils/arrays"; export type HeartOptions = { - /** - * The maximum number of hearts to render at a given time - */ - maxCount: number; - /** - * The amount of gravity to apply to the hearts - */ - gravity: number; - /** - * The maximum amount of drift (horizontal sway) to apply to the hearts. Each heart varies. - */ - maxDrift: number; - /** - * The maximum amount of tilt to apply to the heart. Each heart varies. - */ - maxRot: number; + /** + * The maximum number of hearts to render at a given time + */ + maxCount: number; + /** + * The amount of gravity to apply to the hearts + */ + gravity: number; + /** + * The maximum amount of drift (horizontal sway) to apply to the hearts. Each heart varies. + */ + maxDrift: number; + /** + * The maximum amount of tilt to apply to the heart. Each heart varies. + */ + maxRot: number; } type Heart = { - x: number; - y: number; - xCol: number; - scale: number; - maximumDrift: number; - maximumRot: number; - gravity: number; - color: string, + x: number; + y: number; + xCol: number; + scale: number; + maximumDrift: number; + maximumRot: number; + gravity: number; + color: string, } export const DefaultOptions: HeartOptions = { - maxCount: 120, - gravity: 3.2, - maxDrift: 5, - maxRot: 5, + maxCount: 120, + gravity: 3.2, + maxDrift: 5, + maxRot: 5, }; const KEY_FRAME_INTERVAL = 15; // 15ms, roughly export default class Hearts implements ICanvasEffect { - private readonly options: HeartOptions; - - constructor(options: { [key: string]: any }) { - this.options = { ...DefaultOptions, ...options }; - } - - private context: CanvasRenderingContext2D | null = null; - private particles: Array = []; - private lastAnimationTime: number; - - private colours = [ - 'rgba(194,210,224,1)', - 'rgba(235,214,219,1)', - 'rgba(255,211,45,1)', - 'rgba(255,190,174,1)', - 'rgba(255,173,226,1)', - 'rgba(242,114,171,1)', - 'rgba(228,55,116,1)', - 'rgba(255,86,130,1)', - 'rgba(244,36,57,1)', - 'rgba(247,126,157,1)',//w - 'rgba(243,142,140,1)', - 'rgba(252,116,183,1)']; - - public isRunning: boolean; - - public start = async (canvas: HTMLCanvasElement, timeout = 3000) => { - if (!canvas) { - return; - } - this.context = canvas.getContext('2d'); - this.particles = []; - const count = this.options.maxCount; - while (this.particles.length < count) { - this.particles.push(this.resetParticle({} as Heart, canvas.width, canvas.height)); - } - this.isRunning = true; - requestAnimationFrame(this.renderLoop); - if (timeout) { - window.setTimeout(this.stop, timeout); - } - } - - public stop = async () => { - this.isRunning = false; - } - - private resetParticle = (particle: Heart, width: number, height: number): Heart => { - particle.color = this.colours[(Math.random() * this.colours.length) | 0]; - particle.x = Math.random() * width; - particle.y = Math.random() * height + height; - particle.xCol = particle.x; - particle.scale = (Math.random() * 0.07) + 0.04; - particle.maximumDrift = (Math.random() * this.options.maxDrift) + 3.5; - particle.maximumRot = (Math.random() * this.options.maxRot) + 3.5; - particle.gravity = this.options.gravity + (Math.random() * 4.8); - return particle; - } - - private renderLoop = (): void => { - if (!this.context || !this.context.canvas) { - return; - } - if (this.particles.length === 0) { - this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); - } else { - const timeDelta = Date.now() - this.lastAnimationTime; - if (timeDelta >= KEY_FRAME_INTERVAL || !this.lastAnimationTime) { - // Clear the screen first - this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); - - this.lastAnimationTime = Date.now(); - this.animateAndRenderHearts(); - } - requestAnimationFrame(this.renderLoop); - } - }; - - private animateAndRenderHearts() { - if (!this.context || !this.context.canvas) { - return; - } - for (const particle of arrayFastClone(this.particles)) { - particle.y -= particle.gravity; - - // We treat the drift as a sine function to have a more fluid-like movement instead - // of a pong-like movement off walls of the X column. This means that for - // $x=A\sin(\frac{2\pi}{P}y)$ we use the `maximumDrift` as the amplitude (A) and a - // large multiplier to create a very long waveform through P. - const peakDistance = 75 * particle.maximumDrift; - const PI2 = Math.PI * 2; - particle.x = 6 * particle.maximumDrift * Math.sin(0.7 * (PI2 / peakDistance) * particle.y); - particle.x += particle.xCol; // bring the particle to the right place - - let posScale = 1 / particle.scale; - let x = particle.x * posScale; - let y = particle.y * posScale; - - this.context.save(); - this.context.scale(particle.scale, particle.scale); - this.context.beginPath(); - - // Rotate the heart about its centre. - // The tilt of the heart is modelled similarly to its horizontal drift, - // using a sine function. - this.context.translate(248 + x, 215 + y); - this.context.rotate((1 / 10) * particle.maximumRot * Math.sin((PI2 / peakDistance) * particle.y * 0.8)); - this.context.translate(-248 - x, -215 - y); - - // Use bezier curves to draw a heart using pre-calculated coordinates. - this.context.moveTo(140 + x, 20 + y); - this.context.bezierCurveTo(73 + x, 20 + y, 20 + x, 74 + y, 20 + x, 140 + y); - this.context.bezierCurveTo(20 + x, 275 + y, 156 + x, 310 + y, 248 + x, 443 + y); - this.context.bezierCurveTo(336 + x, 311 + y, 477 + x, 270 + y, 477 + x, 140 + y); - this.context.bezierCurveTo(477 + x, 74 + y, 423 + x, 20 + y, 357 + x, 20 + y); - this.context.bezierCurveTo(309 + x, 20 + y, 267 + x, 48 + y, 248 + x, 89 + y); - this.context.bezierCurveTo(229 + x, 48 + y, 188 + x, 20 + y, 140 + x, 20 + y); - this.context.closePath(); - - this.context.fillStyle = particle.color; - this.context.fill(); - - this.context.restore(); - - // Remove any dead hearts after a 100px wide margin. - if (particle.y < -100 ) { - const idx = this.particles.indexOf(particle); - this.particles.splice(idx, 1); - } - } - } + private readonly options: HeartOptions; + + constructor(options: { [key: string]: any }) { + this.options = { ...DefaultOptions, ...options }; + } + + private context: CanvasRenderingContext2D | null = null; + private particles: Array = []; + private lastAnimationTime: number; + + private colours = [ + 'rgba(194,210,224,1)', + 'rgba(235,214,219,1)', + 'rgba(255,211,45,1)', + 'rgba(255,190,174,1)', + 'rgba(255,173,226,1)', + 'rgba(242,114,171,1)', + 'rgba(228,55,116,1)', + 'rgba(255,86,130,1)', + 'rgba(244,36,57,1)', + 'rgba(247,126,157,1)',//w + 'rgba(243,142,140,1)', + 'rgba(252,116,183,1)']; + + public isRunning: boolean; + + public start = async (canvas: HTMLCanvasElement, timeout = 3000) => { + if (!canvas) { + return; + } + this.context = canvas.getContext('2d'); + this.particles = []; + const count = this.options.maxCount; + while (this.particles.length < count) { + this.particles.push(this.resetParticle({} as Heart, canvas.width, canvas.height)); + } + this.isRunning = true; + requestAnimationFrame(this.renderLoop); + if (timeout) { + window.setTimeout(this.stop, timeout); + } + } + + public stop = async () => { + this.isRunning = false; + } + + private resetParticle = (particle: Heart, width: number, height: number): Heart => { + particle.color = this.colours[(Math.random() * this.colours.length) | 0]; + particle.x = Math.random() * width; + particle.y = Math.random() * height + height; + particle.xCol = particle.x; + particle.scale = (Math.random() * 0.07) + 0.04; + particle.maximumDrift = (Math.random() * this.options.maxDrift) + 3.5; + particle.maximumRot = (Math.random() * this.options.maxRot) + 3.5; + particle.gravity = this.options.gravity + (Math.random() * 4.8); + return particle; + } + + private renderLoop = (): void => { + if (!this.context || !this.context.canvas) { + return; + } + if (this.particles.length === 0) { + this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); + } else { + const timeDelta = Date.now() - this.lastAnimationTime; + if (timeDelta >= KEY_FRAME_INTERVAL || !this.lastAnimationTime) { + // Clear the screen first + this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); + + this.lastAnimationTime = Date.now(); + this.animateAndRenderHearts(); + } + requestAnimationFrame(this.renderLoop); + } + }; + + private animateAndRenderHearts() { + if (!this.context || !this.context.canvas) { + return; + } + for (const particle of arrayFastClone(this.particles)) { + particle.y -= particle.gravity; + + // We treat the drift as a sine function to have a more fluid-like movement instead + // of a pong-like movement off walls of the X column. This means that for + // $x=A\sin(\frac{2\pi}{P}y)$ we use the `maximumDrift` as the amplitude (A) and a + // large multiplier to create a very long waveform through P. + const peakDistance = 75 * particle.maximumDrift; + const PI2 = Math.PI * 2; + particle.x = 6 * particle.maximumDrift * Math.sin(0.7 * (PI2 / peakDistance) * particle.y); + particle.x += particle.xCol; // bring the particle to the right place + + let posScale = 1 / particle.scale; + let x = particle.x * posScale; + let y = particle.y * posScale; + + this.context.save(); + this.context.scale(particle.scale, particle.scale); + this.context.beginPath(); + + // Rotate the heart about its centre. + // The tilt of the heart is modelled similarly to its horizontal drift, + // using a sine function. + this.context.translate(248 + x, 215 + y); + this.context.rotate((1 / 10) * particle.maximumRot * Math.sin((PI2 / peakDistance) * particle.y * 0.8)); + this.context.translate(-248 - x, -215 - y); + + // Use bezier curves to draw a heart using pre-calculated coordinates. + this.context.moveTo(140 + x, 20 + y); + this.context.bezierCurveTo(73 + x, 20 + y, 20 + x, 74 + y, 20 + x, 140 + y); + this.context.bezierCurveTo(20 + x, 275 + y, 156 + x, 310 + y, 248 + x, 443 + y); + this.context.bezierCurveTo(336 + x, 311 + y, 477 + x, 270 + y, 477 + x, 140 + y); + this.context.bezierCurveTo(477 + x, 74 + y, 423 + x, 20 + y, 357 + x, 20 + y); + this.context.bezierCurveTo(309 + x, 20 + y, 267 + x, 48 + y, 248 + x, 89 + y); + this.context.bezierCurveTo(229 + x, 48 + y, 188 + x, 20 + y, 140 + x, 20 + y); + this.context.closePath(); + + this.context.fillStyle = particle.color; + this.context.fill(); + + this.context.restore(); + + // Remove any dead hearts after a 100px wide margin. + if (particle.y < -100 ) { + const idx = this.particles.indexOf(particle); + this.particles.splice(idx, 1); + } + } + } } diff --git a/src/effects/index.ts b/src/effects/index.ts index be1ab9c43e0..500e37625f9 100644 --- a/src/effects/index.ts +++ b/src/effects/index.ts @@ -74,7 +74,7 @@ export const CHAT_EFFECTS: Array> = [ gravity: 0.01, }, } as Effect, - { + { emojis: ["💝", "💖", "💞", "💕"], msgType: "io.element.effect.hearts", command: "hearts", @@ -86,5 +86,3 @@ export const CHAT_EFFECTS: Array> = [ }, } as Effect, ]; - - From 9f6ef9eb13772e12550b0180798d8f2de5a9bab2 Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Tue, 15 Jun 2021 14:29:37 +0100 Subject: [PATCH 04/13] appease the linter --- src/effects/hearts/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts index c971b79eba4..56447e810d5 100644 --- a/src/effects/hearts/index.ts +++ b/src/effects/hearts/index.ts @@ -76,7 +76,7 @@ export default class Hearts implements ICanvasEffect { 'rgba(228,55,116,1)', 'rgba(255,86,130,1)', 'rgba(244,36,57,1)', - 'rgba(247,126,157,1)',//w + 'rgba(247,126,157,1)', 'rgba(243,142,140,1)', 'rgba(252,116,183,1)']; @@ -150,9 +150,9 @@ export default class Hearts implements ICanvasEffect { particle.x = 6 * particle.maximumDrift * Math.sin(0.7 * (PI2 / peakDistance) * particle.y); particle.x += particle.xCol; // bring the particle to the right place - let posScale = 1 / particle.scale; - let x = particle.x * posScale; - let y = particle.y * posScale; + const posScale = 1 / particle.scale; + const x = particle.x * posScale; + const y = particle.y * posScale; this.context.save(); this.context.scale(particle.scale, particle.scale); From 03a5c2c8ecfa270aa0bb38e2c44b8244df65e2ec Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Wed, 6 Oct 2021 15:37:17 +0100 Subject: [PATCH 05/13] hopefully resolve merge conflict --- src/effects/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/index.ts b/src/effects/index.ts index 4812c91bce1..500e37625f9 100644 --- a/src/effects/index.ts +++ b/src/effects/index.ts @@ -84,5 +84,5 @@ export const CHAT_EFFECTS: Array> = [ maxCount: 120, gravity: 3.2, }, - } as Effect, + } as Effect, ]; From 53b6fd828a0bd05c4b2a2bb7ca09e4a01abc3bbc Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Wed, 6 Oct 2021 15:38:37 +0100 Subject: [PATCH 06/13] add missing semicolons --- src/effects/hearts/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts index 56447e810d5..9ef54b021fe 100644 --- a/src/effects/hearts/index.ts +++ b/src/effects/hearts/index.ts @@ -33,7 +33,7 @@ export type HeartOptions = { * The maximum amount of tilt to apply to the heart. Each heart varies. */ maxRot: number; -} +}; type Heart = { x: number; @@ -43,8 +43,8 @@ type Heart = { maximumDrift: number; maximumRot: number; gravity: number; - color: string, -} + color: string; +}; export const DefaultOptions: HeartOptions = { maxCount: 120, @@ -97,11 +97,11 @@ export default class Hearts implements ICanvasEffect { if (timeout) { window.setTimeout(this.stop, timeout); } - } + }; public stop = async () => { this.isRunning = false; - } + }; private resetParticle = (particle: Heart, width: number, height: number): Heart => { particle.color = this.colours[(Math.random() * this.colours.length) | 0]; @@ -113,7 +113,7 @@ export default class Hearts implements ICanvasEffect { particle.maximumRot = (Math.random() * this.options.maxRot) + 3.5; particle.gravity = this.options.gravity + (Math.random() * 4.8); return particle; - } + }; private renderLoop = (): void => { if (!this.context || !this.context.canvas) { From 5e83d9b9109f5f1922555484f7492596cc5966ff Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Wed, 6 Oct 2021 17:54:22 +0100 Subject: [PATCH 07/13] add label to toggle switch --- src/components/views/settings/SetIntegrationManager.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/settings/SetIntegrationManager.tsx b/src/components/views/settings/SetIntegrationManager.tsx index e083efae0ef..9db5c58b586 100644 --- a/src/components/views/settings/SetIntegrationManager.tsx +++ b/src/components/views/settings/SetIntegrationManager.tsx @@ -79,10 +79,13 @@ export default class SetIntegrationManager extends React.Component { _t("Manage integrations") } { managerName } - + - { bodyText }

{ _t( From f2a51abfae3965343acfdc107d6e3f587d7cbe75 Mon Sep 17 00:00:00 2001 From: ColonisationCaptain <52425971+ColonisationCaptain@users.noreply.github.com> Date: Thu, 7 Oct 2021 00:42:58 +0100 Subject: [PATCH 08/13] Revert "add label to toggle switch" This reverts commit 5e83d9b9109f5f1922555484f7492596cc5966ff. --- src/components/views/settings/SetIntegrationManager.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/views/settings/SetIntegrationManager.tsx b/src/components/views/settings/SetIntegrationManager.tsx index 9db5c58b586..e083efae0ef 100644 --- a/src/components/views/settings/SetIntegrationManager.tsx +++ b/src/components/views/settings/SetIntegrationManager.tsx @@ -79,13 +79,10 @@ export default class SetIntegrationManager extends React.Component { _t("Manage integrations") } { managerName } - + + { bodyText }

{ _t( From 3dea9c1f031806de74f2ed9ab270d85a54eb2660 Mon Sep 17 00:00:00 2001 From: CicadaCinema <52425971+CicadaCinema@users.noreply.github.com> Date: Sun, 13 Feb 2022 13:28:00 +0000 Subject: [PATCH 09/13] remove extra space --- src/effects/hearts/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts index 9ef54b021fe..8fd3a8ecbe7 100644 --- a/src/effects/hearts/index.ts +++ b/src/effects/hearts/index.ts @@ -181,7 +181,7 @@ export default class Hearts implements ICanvasEffect { this.context.restore(); // Remove any dead hearts after a 100px wide margin. - if (particle.y < -100 ) { + if (particle.y < -100) { const idx = this.particles.indexOf(particle); this.particles.splice(idx, 1); } From e1b68b0f05b37f5d2ceb77e50f97547c67f6f81b Mon Sep 17 00:00:00 2001 From: CicadaCinema <52425971+CicadaCinema@users.noreply.github.com> Date: Mon, 21 Feb 2022 22:04:04 +0000 Subject: [PATCH 10/13] replace gift heart with emoji heart in timeline message --- src/effects/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/index.ts b/src/effects/index.ts index 2c131d806d3..47f36484d41 100644 --- a/src/effects/index.ts +++ b/src/effects/index.ts @@ -91,7 +91,7 @@ export const CHAT_EFFECTS: Array> = [ msgType: "io.element.effect.hearts", command: "hearts", description: () => _td("Sends the given message with hearts"), - fallbackMessage: () => _t("sends hearts") + " 💝", + fallbackMessage: () => _t("sends hearts") + " 💞", options: { maxCount: 120, gravity: 3.2, From bc87cd9a7f81b80a83a6cea564507de2acf9724b Mon Sep 17 00:00:00 2001 From: CicadaCinema <52425971+CicadaCinema@users.noreply.github.com> Date: Tue, 8 Mar 2022 00:10:13 +0000 Subject: [PATCH 11/13] reduce number of emoji triggers --- src/effects/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/index.ts b/src/effects/index.ts index 47f36484d41..d165dd0ef51 100644 --- a/src/effects/index.ts +++ b/src/effects/index.ts @@ -87,7 +87,7 @@ export const CHAT_EFFECTS: Array> = [ }, } as Effect, { - emojis: ["💝", "💖", "💞", "💕"], + emojis: ["💝"], msgType: "io.element.effect.hearts", command: "hearts", description: () => _td("Sends the given message with hearts"), From da6d6d101c81d7190b0d6b740d29f34a841bc46f Mon Sep 17 00:00:00 2001 From: CicadaCinema <52425971+CicadaCinema@users.noreply.github.com> Date: Thu, 10 Mar 2022 14:36:37 +0000 Subject: [PATCH 12/13] copyright should be myself --- src/effects/hearts/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/effects/hearts/index.ts b/src/effects/hearts/index.ts index 8fd3a8ecbe7..1fb743f99c6 100644 --- a/src/effects/hearts/index.ts +++ b/src/effects/hearts/index.ts @@ -1,5 +1,6 @@ /* Copyright 2021 The Matrix.org Foundation C.I.C. + Copyright 2022 Arseny Uskov Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From ad5d1ad7351e16fc938b78bafe30f4e194a51bdc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 8 Apr 2022 14:54:06 -0600 Subject: [PATCH 13/13] Update src/effects/index.ts --- src/effects/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/index.ts b/src/effects/index.ts index d165dd0ef51..3468d4c5b6a 100644 --- a/src/effects/index.ts +++ b/src/effects/index.ts @@ -91,7 +91,7 @@ export const CHAT_EFFECTS: Array> = [ msgType: "io.element.effect.hearts", command: "hearts", description: () => _td("Sends the given message with hearts"), - fallbackMessage: () => _t("sends hearts") + " 💞", + fallbackMessage: () => _t("sends hearts") + " 💝", options: { maxCount: 120, gravity: 3.2,