UNPKG

@pilotlab/lux-tools

Version:

A luxurious user experience framework, developed by your friends at Pilot.

117 lines 5.46 kB
"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