@pilotlab/lux-tools
Version:
A luxurious user experience framework, developed by your friends at Pilot.
117 lines • 5.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const is_1 = require("@pilotlab/is");
const range_scale_1 = require("@pilotlab/range-scale");
const attributes_1 = require("@pilotlab/attributes");
const signals_1 = require("@pilotlab/signals");
class Spring {
constructor(maximumChaseDistance) {
this._isEnabled = false;
this.leaderPosition = new attributes_1.Vector(0, 0, 0);
this.chaserPosition = new attributes_1.Vector(0, 0, 0);
this.chaserRotation = 0;
this.maximumChaseDistance = 10000;
this.catchProximity = 1;
this.chaseSpeed = new attributes_1.Vector(0, 0, 0);
this.acceleration = 0.15;
this._OFFSET_FACTOR = 1.0;
this._direction = 0;
this._isLeaderCaught = true;
this._leaderCaughtTicks = 0;
this._WAIT_BEFORE_CATCHING_TICKS = 20;
this.updated = new signals_1.Signal();
this.leaderCaught = new signals_1.Signal();
if (is_1.default.notEmpty(maximumChaseDistance))
this.maximumChaseDistance = maximumChaseDistance;
this._progressRangeScale = new range_scale_1.RangeScale(-this.maximumChaseDistance, this.maximumChaseDistance, -1, 1);
}
get isEnabled() { return this._isEnabled; }
set isEnabled(value) {
if (value && !this._isEnabled) {
this.chaseSpeed.x = this.catchProximity;
this.chaseSpeed.y = this.catchProximity;
}
this._isEnabled = value;
}
tick() {
if (this.isEnabled) {
this._updateChase();
this._applyValues();
this.updated.dispatch(new attributes_1.Point(this.chaserPosition.x, this.chaserPosition.y));
}
}
get direction() { return this._direction; }
get isLeaderCaught() {
return this._isLeaderCaught;
}
get velocityNormalized() {
return new attributes_1.Point(this._progressRangeScale.output(this.leaderPosition.x - this.chaserPosition.x, false), this._progressRangeScale.output(this.leaderPosition.y - this.chaserPosition.y, false));
}
startChasing(leaderX, leaderY, chaserX, chaserY) {
this.leaderPosition.x = leaderX;
this.leaderPosition.y = leaderY;
this.chaserPosition.x = chaserX;
this.chaserPosition.y = chaserY;
this.chaseSpeed.x = this.catchProximity;
this.chaseSpeed.y = this.catchProximity;
this.isEnabled = true;
this._isLeaderCaught = false;
}
_updateChase() {
let vDiff = new attributes_1.Vector(this.leaderPosition.x - this.chaserPosition.x, this.leaderPosition.y - this.chaserPosition.y, 0);
let vDirection = new attributes_1.Vector(vDiff.x, vDiff.y, 0);
vDirection.normalize();
vDiff = vDiff.abs;
this.chaserPosition.x += vDirection.x * this.chaseSpeed.x;
this.chaserPosition.y += vDirection.y * this.chaseSpeed.y;
if (vDiff.x > this.maximumChaseDistance / this._OFFSET_FACTOR) {
vDiff.x = this.maximumChaseDistance / this._OFFSET_FACTOR;
this.chaserPosition.x = this.leaderPosition.x - ((this.maximumChaseDistance / this._OFFSET_FACTOR) * vDirection.x);
}
else if (vDiff.x < this.catchProximity)
this.chaserPosition.x = this.leaderPosition.x;
if (vDiff.y > this.maximumChaseDistance / this._OFFSET_FACTOR) {
vDiff.y = this.maximumChaseDistance / this._OFFSET_FACTOR;
this.chaserPosition.y = this.leaderPosition.y - ((this.maximumChaseDistance / this._OFFSET_FACTOR) * vDirection.y);
}
else if (vDiff.y < this.catchProximity)
this.chaserPosition.y = this.leaderPosition.y;
if (this.chaserPosition.x != this.leaderPosition.x && this.chaserPosition.y != this.leaderPosition.y) {
this.chaserRotation = Math.atan2((this.chaserPosition.y - this.leaderPosition.y), (this.chaserPosition.x - this.leaderPosition.x)) / (Math.PI / 180) - 90;
}
this.chaseSpeed = new attributes_1.Vector(vDiff.x * vDirection.x * this._OFFSET_FACTOR, vDiff.y * vDirection.y * this._OFFSET_FACTOR);
this.chaseSpeed.x = Math.ceil(Math.abs(this.chaseSpeed.x) * this.acceleration);
this.chaseSpeed.y = Math.ceil(Math.abs(this.chaseSpeed.y) * this.acceleration);
}
_applyValues() {
let chaseSpeed = this.chaseSpeed.y;
this._direction = -1;
if (chaseSpeed > 0) {
this._direction = 1;
this._isLeaderCaught = false;
this._leaderCaughtTicks = 0;
}
else if (chaseSpeed < 0) {
this._isLeaderCaught = false;
this._leaderCaughtTicks = 0;
}
else {
this._direction = 0;
if (!this._isLeaderCaught) {
if (this._leaderCaughtTicks < this._WAIT_BEFORE_CATCHING_TICKS)
this._leaderCaughtTicks += 1;
else {
this._leaderCaughtTicks = 0;
this._isLeaderCaught = true;
this.chaserPosition.x = this.leaderPosition.x;
this.chaserPosition.y = this.leaderPosition.y;
this.isEnabled = false;
this.leaderCaught.dispatch(new attributes_1.Point(this.leaderPosition.x, this.leaderPosition.y));
}
}
}
}
}
exports.Spring = Spring;
exports.default = Spring;
//# sourceMappingURL=index.js.map