confetti-explosion-react
Version:
A React lightweight css-animation based confetti exploder
110 lines • 6.99 kB
JavaScript
;
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var tss_react_1 = require("tss-react");
var tss_react_2 = require("tss-react");
var lodash_round_1 = __importDefault(require("lodash.round"));
var utils_1 = require("./utils");
var ROTATION_SPEED_MIN = 200; // minimum possible duration of single particle full rotation
var ROTATION_SPEED_MAX = 800; // maximum possible duration of single particle full rotation
var CRAZY_PARTICLES_FREQUENCY = 0.1; // 0-1 frequency of crazy curvy unpredictable particles
var CRAZY_PARTICLE_CRAZINESS = 0.3; // 0-1 how crazy these crazy particles are
var BEZIER_MEDIAN = 0.5; // utility for mid-point bezier curves, to ensure smooth motion paths
var rotationKeyframes = utils_1.rotationTransforms.reduce(function (acc, xyz, i) {
var _a;
var rotateKeyframe = (0, tss_react_1.keyframes)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n to {\n transform: rotate3d(", ", 360deg);\n }"], ["\n to {\n transform: rotate3d(", ", 360deg);\n }"])), xyz.join());
return __assign(__assign({}, acc), (_a = {}, _a["rotateKeyframe-".concat(i)] = rotateKeyframe, _a));
}, {});
var confettiKeyframes = function (degrees, height, width) {
var xLandingPoints = degrees.reduce(function (acc, degree, i) {
var _a;
var landingPoint = (0, utils_1.mapRange)(Math.abs((0, utils_1.rotate)(degree, 90) - 180), 0, 180, -width / 2, width / 2);
var xAxisIndexKeyframe = (0, tss_react_1.keyframes)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n to {\n transform: translateX(", "px);\n }"], ["\n to {\n transform: translateX(", "px);\n }"])), landingPoint);
return __assign(__assign({}, acc), (_a = {}, _a["xAxisIndexKeyframe-".concat(i)] = xAxisIndexKeyframe, _a));
}, {});
var yAxisKeyframes = (0, tss_react_1.keyframes)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n to {\n transform: translateY(", "px);\n }"], ["\n to {\n transform: translateY(", "px);\n }"])), height);
return __assign({ yAxisKeyframes: yAxisKeyframes }, xLandingPoints);
};
var confettoStyle = function (particle, duration, force, size, i, confettiKeyframesResult) {
var _a;
var rotation = Math.random() * (ROTATION_SPEED_MAX - ROTATION_SPEED_MIN) + ROTATION_SPEED_MIN;
var rotationIndex = Math.round(Math.random() * (utils_1.rotationTransforms.length - 1));
var durationChaos = duration - Math.round(Math.random() * 1000);
var shouldBeCrazy = Math.random() < CRAZY_PARTICLES_FREQUENCY;
var isCircle = (0, utils_1.shouldBeCircle)(rotationIndex);
// x-axis disturbance, roughly the distance the particle will initially deviate from its target
var x1 = shouldBeCrazy ? (0, lodash_round_1.default)(Math.random() * CRAZY_PARTICLE_CRAZINESS, 2) : 0;
var x2 = x1 * -1;
var x3 = x1;
// x-axis arc of explosion, so 90deg and 270deg particles have curve of 1, 0deg and 180deg have 0
var x4 = (0, lodash_round_1.default)(Math.abs((0, utils_1.mapRange)(Math.abs((0, utils_1.rotate)(particle.degree, 90) - 180), 0, 180, -1, 1)), 4);
// roughly how fast particle reaches end of its explosion curve
var y1 = (0, lodash_round_1.default)(Math.random() * BEZIER_MEDIAN, 4);
// roughly maps to the distance particle goes before reaching free-fall
var y2 = (0, lodash_round_1.default)(Math.random() * force * ((0, utils_1.coinFlip)() ? 1 : -1), 4);
// roughly how soon the particle transitions from explosion to free-fall
var y3 = BEZIER_MEDIAN;
// roughly the ease of free-fall
var y4 = (0, lodash_round_1.default)(Math.max((0, utils_1.mapRange)(Math.abs(particle.degree - 180), 0, 180, force, -force), 0), 4);
return _a = {},
_a["&#confetti-particle-".concat(i)] = {
animation: "".concat(confettiKeyframesResult["xAxisIndexKeyframe-".concat(i)], " ").concat(durationChaos, "ms forwards cubic-bezier(").concat(x1, ", ").concat(x2, ", ").concat(x3, ", ").concat(x4, ")"),
'& > div': {
width: isCircle ? size : Math.round(Math.random() * 4) + size / 2,
height: isCircle ? size : Math.round(Math.random() * 2) + size,
animation: "".concat(confettiKeyframesResult['yAxisKeyframes'], " ").concat(durationChaos, "ms forwards cubic-bezier(").concat(y1, ", ").concat(y2, ", ").concat(y3, ", ").concat(y4, ")"),
'&:after': __assign({ backgroundColor: particle.color, animation: "".concat(rotationKeyframes["rotateKeyframe-".concat(rotationIndex)], " ").concat(rotation, "ms infinite linear") }, (isCircle ? { borderRadius: '50%' } : {})),
},
},
_a;
};
var makeStyles = (0, tss_react_2.createMakeStyles)({
useTheme: function () { },
}).makeStyles;
var useStyles = function (_a) {
var particles = _a.particles, duration = _a.duration, height = _a.height, width = _a.width, force = _a.force, particleSize = _a.particleSize;
return makeStyles({ name: 'ConfettiExplosion' })(function (theme, _params, classes) {
var confettiKeyframesResult = confettiKeyframes(particles.map(function (particle) { return particle.degree; }), height, width);
var confettiStyles = particles.reduce(function (acc, particle, i) { return (__assign(__assign({}, acc), confettoStyle(particle, duration, force, particleSize, i, confettiKeyframesResult))); }, {});
return {
container: {
width: 0,
height: 0,
position: 'relative',
overflow: 'visible',
zIndex: 1200,
},
particle: __assign(__assign({}, confettiStyles), { '& > div': {
position: 'absolute',
left: 0,
top: 0,
'&:after': {
content: "''",
display: 'block',
width: '100%',
height: '100%',
},
} }),
};
});
};
exports.default = useStyles;
var templateObject_1, templateObject_2, templateObject_3;
//# sourceMappingURL=styles.js.map