confetti file added
This commit is contained in:
parent
a7567b2e31
commit
77de63bf4b
1 changed files with 121 additions and 131 deletions
|
@ -1,52 +1,48 @@
|
||||||
import React from "react";
|
const confetti = {
|
||||||
import SettingsStore from "../../../../lib/settings/SettingsStore";
|
//set max confetti count
|
||||||
import PropTypes from "prop-types";
|
maxCount: 150,
|
||||||
|
//syarn addet the particle animation speed
|
||||||
|
speed: 3,
|
||||||
|
//the confetti animation frame interval in milliseconds
|
||||||
|
frameInterval: 15,
|
||||||
|
//the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible)
|
||||||
|
alpha: 1.0,
|
||||||
|
//call to start confetti animation (with optional timeout in milliseconds)
|
||||||
|
start: null,
|
||||||
|
//call to stop adding confetti
|
||||||
|
stop: null,
|
||||||
|
//call to stop the confetti animation and remove all confetti immediately
|
||||||
|
remove: null,
|
||||||
|
isRunning: null,
|
||||||
|
//call and returns true or false depending on whether the animation is running
|
||||||
|
animate: null,
|
||||||
|
};
|
||||||
|
|
||||||
export default class Confetti extends React.Component {
|
(function() {
|
||||||
displayName: 'confetti';
|
confetti.start = startConfetti;
|
||||||
constructor(props) {
|
confetti.stop = stopConfetti;
|
||||||
super(props);
|
confetti.remove = removeConfetti;
|
||||||
this.animateConfetti = this.animateConfetti.bind(this);
|
confetti.isRunning = isConfettiRunning;
|
||||||
this.confetti.start = this.startConfetti;
|
confetti.animate = animateConfetti;
|
||||||
this.startConfetti = this.startConfetti.bind(this);
|
const supportsAnimationFrame = window.requestAnimationFrame ||
|
||||||
this.confetti.stop = this.stopConfetti;
|
|
||||||
this.confetti.remove = this.removeConfetti;
|
|
||||||
this.confetti.isRunning = this.isConfettiRunning;
|
|
||||||
}
|
|
||||||
static propTypes = {
|
|
||||||
width: PropTypes.string.isRequired,
|
|
||||||
height: PropTypes.string.isRequired,
|
|
||||||
}
|
|
||||||
confetti = {
|
|
||||||
//set max confetti count
|
|
||||||
maxCount: 150,
|
|
||||||
//set the particle animation speed
|
|
||||||
speed: 3,
|
|
||||||
//the confetti animation frame interval in milliseconds
|
|
||||||
frameInterval: 15,
|
|
||||||
//the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible)
|
|
||||||
alpha: 1.0,
|
|
||||||
start: null,
|
|
||||||
};
|
|
||||||
colors = ["rgba(30,144,255,", "rgba(107,142,35,", "rgba(255,215,0,",
|
|
||||||
"rgba(255,192,203,", "rgba(106,90,205,", "rgba(173,216,230,",
|
|
||||||
"rgba(238,130,238,", "rgba(152,251,152,", "rgba(70,130,180,",
|
|
||||||
"rgba(244,164,96,", "rgba(210,105,30,", "rgba(220,20,60,"];
|
|
||||||
streamingConfetti = false;
|
|
||||||
animationTimer = null;
|
|
||||||
lastFrameTime = Date.now();
|
|
||||||
particles = [];
|
|
||||||
waveAngle = 0;
|
|
||||||
context = null;
|
|
||||||
supportsAnimationFrame = window.requestAnimationFrame ||
|
|
||||||
window.webkitRequestAnimationFrame ||
|
window.webkitRequestAnimationFrame ||
|
||||||
window.mozRequestAnimationFrame ||
|
window.mozRequestAnimationFrame ||
|
||||||
window.oRequestAnimationFrame ||
|
window.oRequestAnimationFrame ||
|
||||||
window.msRequestAnimationFrame;
|
window.msRequestAnimationFrame;
|
||||||
|
const colors = ["rgba(30,144,255,", "rgba(107,142,35,", "rgba(255,215,0,",
|
||||||
|
"rgba(255,192,203,", "rgba(106,90,205,", "rgba(173,216,230,",
|
||||||
|
"rgba(238,130,238,", "rgba(152,251,152,", "rgba(70,130,180,",
|
||||||
|
"rgba(244,164,96,", "rgba(210,105,30,", "rgba(220,20,60,"];
|
||||||
|
let streamingConfetti = false;
|
||||||
|
let animationTimer = null;
|
||||||
|
let lastFrameTime = Date.now();
|
||||||
|
let particles = [];
|
||||||
|
let waveAngle = 0;
|
||||||
|
let context = null;
|
||||||
|
|
||||||
resetParticle(particle, width, height) {
|
function resetParticle(particle, width, height) {
|
||||||
particle.color = this.colors[(Math.random() * this.colors.length) | 0] + (this.confetti.alpha + ")");
|
particle.color = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")");
|
||||||
particle.color2 = this.colors[(Math.random() * this.colors.length) | 0] + (this.confetti.alpha + ")");
|
particle.color2 = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")");
|
||||||
particle.x = Math.random() * width;
|
particle.x = Math.random() * width;
|
||||||
particle.y = Math.random() * height - height;
|
particle.y = Math.random() * height - height;
|
||||||
particle.diameter = Math.random() * 10 + 5;
|
particle.diameter = Math.random() * 10 + 5;
|
||||||
|
@ -56,154 +52,148 @@ export default class Confetti extends React.Component {
|
||||||
return particle;
|
return particle;
|
||||||
}
|
}
|
||||||
|
|
||||||
startConfetti(timeout) {
|
function runAnimation() {
|
||||||
const width = window.innerWidth;
|
if (particles.length === 0) {
|
||||||
|
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||||
|
animationTimer = null;
|
||||||
|
} else {
|
||||||
|
const now = Date.now();
|
||||||
|
const delta = now - lastFrameTime;
|
||||||
|
if (!supportsAnimationFrame || delta > confetti.frameInterval) {
|
||||||
|
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||||
|
updateParticles();
|
||||||
|
drawParticles(context);
|
||||||
|
lastFrameTime = now - (delta % confetti.frameInterval);
|
||||||
|
}
|
||||||
|
animationTimer = requestAnimationFrame(runAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startConfetti(roomWidth, timeout) {
|
||||||
|
const width = roomWidth;
|
||||||
const height = window.innerHeight;
|
const height = window.innerHeight;
|
||||||
window.requestAnimationFrame = () => {
|
window.requestAnimationFrame = (function () {
|
||||||
return window.requestAnimationFrame ||
|
return window.requestAnimationFrame ||
|
||||||
window.webkitRequestAnimationFrame ||
|
window.webkitRequestAnimationFrame ||
|
||||||
window.mozRequestAnimationFrame ||
|
window.mozRequestAnimationFrame ||
|
||||||
window.oRequestAnimationFrame ||
|
window.oRequestAnimationFrame ||
|
||||||
window.msRequestAnimationFrame ||
|
window.msRequestAnimationFrame ||
|
||||||
function(callback) {
|
function (callback) {
|
||||||
return window.setTimeout(callback, this.confetti.frameInterval);
|
return window.setTimeout(callback, confetti.frameInterval);
|
||||||
};
|
};
|
||||||
};
|
})();
|
||||||
let canvas = document.getElementById("confetti-canvas");
|
let canvas = document.getElementById("confetti-canvas");
|
||||||
if (canvas === null) {
|
if (canvas === null) {
|
||||||
canvas = document.createElement("canvas");
|
canvas = document.createElement("canvas");
|
||||||
canvas.setAttribute("id", "confetti-canvas");
|
canvas.setAttribute("id", "confetti-canvas");
|
||||||
canvas.setAttribute("style", "display:block;z-index:999999;pointer-events:none;position:fixed;top:0");
|
canvas.setAttribute("style", "display:block;z-index:999999;pointer-events:none;position:fixed;top:0; right:0");
|
||||||
document.body.prepend(canvas);
|
document.body.prepend(canvas);
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
window.addEventListener("resize", function () {
|
window.addEventListener("resize", function() {
|
||||||
canvas.width = window.innerWidth;
|
canvas.width = roomWidth;
|
||||||
canvas.height = window.innerHeight;
|
canvas.height = window.innerHeight;
|
||||||
}, true);
|
}, true);
|
||||||
this.context = canvas.getContext("2d");
|
context = canvas.getContext("2d");
|
||||||
} else if (this.context === null) {
|
} else if (context === null) {
|
||||||
this.context = canvas.getContext("2d");
|
context = canvas.getContext("2d");
|
||||||
}
|
}
|
||||||
const count = this.confetti.maxCount;
|
const count = confetti.maxCount;
|
||||||
while (this.particles.length < count) {
|
while (particles.length < count) {
|
||||||
this.particles.push(this.resetParticle({}, width, height));
|
particles.push(resetParticle({}, width, height));
|
||||||
}
|
}
|
||||||
this.streamingConfetti = true;
|
streamingConfetti = true;
|
||||||
this.runAnimation();
|
runAnimation();
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
window.setTimeout(this.stopConfetti, timeout);
|
window.setTimeout(stopConfetti, timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stopConfetti() {
|
function stopConfetti() {
|
||||||
this.streamingConfetti = false;
|
streamingConfetti = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
runAnimation() {
|
function removeConfetti() {
|
||||||
if (this.particles.length === 0) {
|
|
||||||
this.context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
|
||||||
this.animationTimer = null;
|
|
||||||
} else {
|
|
||||||
const now = Date.now();
|
|
||||||
const delta = now - this.lastFrameTime;
|
|
||||||
if (!this.supportsAnimationFrame || delta > this.confetti.frameInterval) {
|
|
||||||
this.context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
|
||||||
this.updateParticles();
|
|
||||||
this.drawParticles(this.context);
|
|
||||||
this.lastFrameTime = now - (delta % this.confetti.frameInterval);
|
|
||||||
}
|
|
||||||
this.animationTimer = requestAnimationFrame(this.runAnimation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeConfetti() {
|
|
||||||
stop();
|
stop();
|
||||||
this.particles = [];
|
particles = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
isConfettiRunning() {
|
function isConfettiRunning() {
|
||||||
return this.streamingConfetti;
|
return streamingConfetti;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawParticles(context) {
|
function drawParticles(context) {
|
||||||
let particle;
|
let particle;
|
||||||
let x;
|
let x; let x2; let y2;
|
||||||
let x2;
|
for (let i = 0; i < particles.length; i++) {
|
||||||
let y2;
|
particle = particles[i];
|
||||||
for (let i = 0; i < this.particles.length; i++) {
|
|
||||||
particle = this.particles[i];
|
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.lineWidth = particle.diameter;
|
context.lineWidth = particle.diameter;
|
||||||
x2 = particle.x + particle.tilt;
|
x2 = particle.x + particle.tilt;
|
||||||
x = x2 + particle.diameter / 2;
|
x = x2 + particle.diameter / 2;
|
||||||
y2 = particle.y + particle.tilt + particle.diameter / 2;
|
y2 = particle.y + particle.tilt + particle.diameter / 2;
|
||||||
context.strokeStyle = particle.color;
|
if (confetti.gradient) {
|
||||||
|
const gradient = context.createLinearGradient(x, particle.y, x2, y2);
|
||||||
|
gradient.addColorStop("0", particle.color);
|
||||||
|
gradient.addColorStop("1.0", particle.color2);
|
||||||
|
context.strokeStyle = gradient;
|
||||||
|
} else {
|
||||||
|
context.strokeStyle = particle.color;
|
||||||
|
}
|
||||||
context.moveTo(x, particle.y);
|
context.moveTo(x, particle.y);
|
||||||
context.lineTo(x2, y2);
|
context.lineTo(x2, y2);
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateParticles() {
|
function updateParticles() {
|
||||||
const width = window.innerWidth;
|
const width = window.innerWidth;
|
||||||
const height = window.innerHeight;
|
const height = window.innerHeight;
|
||||||
let particle;
|
let particle;
|
||||||
this.waveAngle += 0.01;
|
waveAngle += 0.01;
|
||||||
for (let i = 0; i < this.particles.length; i++) {
|
for (let i = 0; i < particles.length; i++) {
|
||||||
particle = this.particles[i];
|
particle = particles[i];
|
||||||
if (!this.streamingConfetti && particle.y < -15) {
|
if (!streamingConfetti && particle.y < -15) {
|
||||||
particle.y = height + 100;
|
particle.y = height + 100;
|
||||||
} else {
|
} else {
|
||||||
particle.tiltAngle += particle.tiltAngleIncrement;
|
particle.tiltAngle += particle.tiltAngleIncrement;
|
||||||
particle.x += Math.sin(this.waveAngle) - 0.5;
|
particle.x += Math.sin(waveAngle) - 0.5;
|
||||||
particle.y += (Math.cos(this.waveAngle) + particle.diameter + this.confetti.speed) * 0.5;
|
particle.y += (Math.cos(waveAngle) + particle.diameter + confetti.speed) * 0.5;
|
||||||
particle.tilt = Math.sin(particle.tiltAngle) * 15;
|
particle.tilt = Math.sin(particle.tiltAngle) * 15;
|
||||||
}
|
}
|
||||||
if (particle.x > width + 20 || particle.x < -20 || particle.y > height) {
|
if (particle.x > width + 20 || particle.x < -20 || particle.y > height) {
|
||||||
if (this.streamingConfetti && this.particles.length <= this.confetti.maxCount) {
|
if (streamingConfetti && particles.length <= confetti.maxCount) {
|
||||||
this.resetParticle(particle, width, height);
|
resetParticle(particle, width, height);
|
||||||
} else {
|
} else {
|
||||||
this.particles.splice(i, 1);
|
particles.splice(i, 1);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
convertToHex(content) {
|
export function convertToHex(content) {
|
||||||
const contentBodyToHexArray = [];
|
const contentBodyToHexArray = [];
|
||||||
let hex;
|
let hex;
|
||||||
|
if (content.body) {
|
||||||
for (let i = 0; i < content.body.length; i++) {
|
for (let i = 0; i < content.body.length; i++) {
|
||||||
hex = content.body.codePointAt(i).toString(16);
|
hex = content.body.codePointAt(i).toString(16);
|
||||||
contentBodyToHexArray.push(hex);
|
contentBodyToHexArray.push(hex);
|
||||||
}
|
}
|
||||||
return contentBodyToHexArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
isChatEffectsDisabled() {
|
|
||||||
console.log('return value', SettingsStore.getValue('dontShowChatEffects'));
|
|
||||||
return SettingsStore.getValue('dontShowChatEffects');
|
|
||||||
}
|
|
||||||
|
|
||||||
isConfettiEmoji(content) {
|
|
||||||
const hexArray = this.convertToHex(content);
|
|
||||||
return !!(hexArray.includes('1f389') || hexArray.includes('1f38a'));
|
|
||||||
}
|
|
||||||
|
|
||||||
animateConfetti(userId, message) {
|
|
||||||
// const shortendUserId = userId.slice(1).split(":").slice(0, 1);
|
|
||||||
console.log('in animate confetti method');
|
|
||||||
if (!this.isChatEffectsDisabled()) {
|
|
||||||
this.confetti.start(3000);
|
|
||||||
}
|
|
||||||
if (!message) {
|
|
||||||
return ('*' + userId + ' throws confetti ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (<canvas id="confetti-canvas" style="display:block;z-index:999999;pointer-events:none;position:fixed;top:0"
|
|
||||||
> </canvas>);
|
|
||||||
}
|
}
|
||||||
|
return contentBodyToHexArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isConfettiEmoji(content) {
|
||||||
|
const hexArray = convertToHex(content);
|
||||||
|
return !!(hexArray.includes('1f389') || hexArray.includes('1f38a'));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function animateConfetti(roomWidth) {
|
||||||
|
confetti.start(roomWidth, 3000);
|
||||||
|
}
|
||||||
|
export function forceStopConfetti() {
|
||||||
|
console.log('confetti should stop');
|
||||||
|
confetti.remove();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue