alm
Version:
The best IDE for TypeScript
245 lines (244 loc) • 9.51 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ui = require("../../ui");
var onresize = require("onresize");
var utils = require("../../../common/utils");
var events_1 = require("../../../common/events");
var Blaster = /** @class */ (function () {
function Blaster(cm) {
var _this = this;
this.cm = cm;
this.disposible = new events_1.CompositeDisposible();
this.detached = false;
this.canvas = null;
this.ctx = null;
this.initCanvas = function () {
var cm = _this.cm;
_this.canvas = document.createElement('canvas');
cm.getDomNode().parentElement.appendChild(_this.canvas);
_this.ctx = _this.canvas.getContext('2d');
_this.canvas.style.position = 'absolute';
_this.canvas.style.top = "0";
_this.canvas.style.left = "0";
_this.canvas.style.bottom = "0";
_this.canvas.style.right = "0";
_this.canvas.style.zIndex = '1';
_this.canvas.style.pointerEvents = 'none';
var measureCanvas = function () {
var parent = cm.getDomNode();
_this.canvas.width = parent.clientWidth;
_this.canvas.height = parent.clientHeight;
};
_this.disposible.add(onresize.on(measureCanvas));
cm.layout = utils.intercepted({ context: cm, orig: cm.layout, intercept: measureCanvas });
measureCanvas();
};
this.loop = function () {
// If unmounted stop
if (_this.detached)
return;
// Setup for next loop
requestAnimationFrame(_this.loop);
_this.ctx.clearRect(0, 0, _this.canvas.width, _this.canvas.height);
_this.drawParticles();
};
this.particles = [];
this.drawParticles = function (timeDelta) {
// return if no particles
if (!_this.particles.length)
return;
// animate the particles
for (var _i = 0, _a = _this.particles; _i < _a.length; _i++) {
var particle = _a[_i];
if (particle.effect === Effect.Add) {
_this.effect1(particle);
}
else if (particle.effect === Effect.Delete) {
_this.effect2(particle);
}
}
// clear out the particles that are no longer relevant post animation
_this.particles = _this.particles.filter(function (particle) { return particle && particle.alpha > 0.01 && particle.size > 0.5; });
};
this.PARTICLE_GRAVITY = 0.08;
this.PARTICLE_ALPHA_FADEOUT = 0.96;
// spawn particles
this.PARTICLE_NUM_RANGE = { min: 5, max: 10 };
this.throttledSpawnParticles = utils.throttle(function (effect) {
var editor = _this.cm;
var cursorPos = editor.getPosition();
/** The position relative to dom node of editor */
var pos = editor.getScrolledVisiblePosition(cursorPos);
/** Get the color for the dom token */
var editorNode = editor.getDomNode();
var editorNodeRect = editorNode.getBoundingClientRect();
var posForNode = {
x: editorNodeRect.left + pos.left,
y: editorNodeRect.top + pos.top,
};
var node = document.elementFromPoint(posForNode.x - 5, posForNode.y + 5);
var color = getRGBComponents(node);
// Now create the particles
var numParticles = random(_this.PARTICLE_NUM_RANGE.min, _this.PARTICLE_NUM_RANGE.max);
for (var i = 0; i < numParticles; i++) {
_this.particles.push(_this.createParticle(pos.left + 15, pos.top - 5, color, effect));
}
}, 100);
this.PARTICLE_VELOCITY_RANGE = {
x: [-1, 1],
y: [-3.5, -1.5]
};
this.handleChange = function (change) {
// setup particles
if (change.text) {
_this.throttledSpawnParticles(Effect.Add);
}
else {
_this.throttledSpawnParticles(Effect.Delete);
}
};
this.disposible.add(cm.onDidChangeModelContent(this.handleChange));
this.initCanvas();
this.loop();
}
Blaster.prototype.dispose = function () {
this.detached = true;
this.disposible.dispose();
};
Blaster.prototype.effect1 = function (particle) {
particle.vy += this.PARTICLE_GRAVITY;
particle.x += particle.vx;
particle.y += particle.vy;
particle.alpha *= this.PARTICLE_ALPHA_FADEOUT;
this.ctx.fillStyle = 'rgba(' + particle.color[0] + ',' + particle.color[1] + ',' + particle.color[2] + ',' + particle.alpha + ')';
this.ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);
};
// Effect based on Soulwire's demo: http://codepen.io/soulwire/pen/foktm
Blaster.prototype.effect2 = function (particle) {
particle.x += particle.vx;
particle.y += particle.vy;
particle.vx *= particle.drag;
particle.vy *= particle.drag;
particle.theta += random(-0.5, 0.5);
particle.vx += Math.sin(particle.theta) * 0.1;
particle.vy += Math.cos(particle.theta) * 0.1;
particle.size *= 0.96;
this.ctx.fillStyle = 'rgba(' + particle.color[0] + ',' + particle.color[1] + ',' + particle.color[2] + ',' + particle.alpha + ')';
this.ctx.beginPath();
this.ctx.arc(particle.x - particle.size / 2, particle.y - particle.size / 2, particle.size, 0, 2 * Math.PI);
this.ctx.fill();
};
Blaster.prototype.createParticle = function (x, y, color, effect) {
var p = {
x: x,
y: y + 10,
alpha: 1,
color: color,
effect: effect,
// modifed below
drag: 0,
wander: 0,
theta: 0,
size: 0,
vx: 0,
vy: 0,
};
if (effect == Effect.Add) {
p.size = random(2, 4);
p.vx = this.PARTICLE_VELOCITY_RANGE.x[0] + Math.random() *
(this.PARTICLE_VELOCITY_RANGE.x[1] - this.PARTICLE_VELOCITY_RANGE.x[0]);
p.vy = this.PARTICLE_VELOCITY_RANGE.y[0] + Math.random() *
(this.PARTICLE_VELOCITY_RANGE.y[1] - this.PARTICLE_VELOCITY_RANGE.y[0]);
}
else if (effect == Effect.Delete) {
p.size = random(2, 8);
p.drag = 0.92;
p.vx = random(-3, 3);
p.vy = random(-3, 3);
p.wander = 0.15;
p.theta = random(0, 360) * Math.PI / 180;
}
return p;
};
return Blaster;
}());
exports.Blaster = Blaster;
/**
* General Utilities
*/
var Effect;
(function (Effect) {
Effect[Effect["Add"] = 1] = "Add";
Effect[Effect["Delete"] = 2] = "Delete";
})(Effect || (Effect = {}));
/** Get a random number in the min-max range, inclusive */
function random(min, max) {
if (!max) {
max = min;
min = 0;
}
return min + ~~(Math.random() * (max - min + 1));
}
/** Get the colors of the html node */
function getRGBComponents(node) {
if (node) {
try {
var color = getComputedStyle(node).color;
return color.match(/(\d+), (\d+), (\d+)/).slice(1);
}
catch (e) {
return ['255', '255', '255'];
}
}
else {
return ['255', '255', '255'];
}
}
/**
* Registering it with monaco
*/
var CommonEditorRegistry = monaco.CommonEditorRegistry;
var EditorAction = monaco.EditorAction;
var KeyMod = monaco.KeyMod;
var KeyCode = monaco.KeyCode;
var EditorContextKeys = monaco.EditorContextKeys;
var ToggleBlasterAction = /** @class */ (function (_super) {
__extends(ToggleBlasterAction, _super);
function ToggleBlasterAction() {
var _this = _super.call(this, {
id: 'editor.action.toggleBlaster',
label: 'Toggle Blaster',
alias: 'Toggle Blaster',
precondition: EditorContextKeys.Writable,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_O
}
}) || this;
_this.blaster = null;
return _this;
}
ToggleBlasterAction.prototype.run = function (accessor, editor) {
if (!this.blaster) {
this.blaster = new Blaster(editor);
ui.notifySuccessNormalDisappear('Have fun 🌹!');
}
else {
this.blaster.dispose();
this.blaster = null;
ui.notifyInfoQuickDisappear('Hope you had fun 💖');
}
};
return ToggleBlasterAction;
}(EditorAction));
CommonEditorRegistry.registerEditorAction(new ToggleBlasterAction());