Basic Effects
This commit is contained in:
parent
a56fac5bfd
commit
0679766f6c
4 changed files with 166 additions and 74 deletions
158
js/effects.js
vendored
Normal file
158
js/effects.js
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
|
||||
/*
|
||||
The interface is like a flywheel.
|
||||
*/
|
||||
export class Flywheel {
|
||||
constructor() {
|
||||
this.value = 0.; // start at 0 - gradual meter
|
||||
this.stage = 0.; // start at 0 - the various stages
|
||||
|
||||
this.f_falloff = (value) => value / 20; // value at which it reduces per second
|
||||
this.f_stage = (value) => 5 * Math.log10(value); // value to stage calculation
|
||||
|
||||
this.value_min = 0;
|
||||
this.value_max = 100; // gives stage 0-9
|
||||
|
||||
// this.interval = window.setInterval(this.step, 50)
|
||||
this.time = null;
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
// TODO: once/twice per second should be enough! + on release (add())
|
||||
|
||||
this.effects = {
|
||||
'shape': new ShapeEffect(),
|
||||
'video': new VideoEffect(),
|
||||
}
|
||||
}
|
||||
|
||||
step(time) {
|
||||
if (this.time === null) {
|
||||
// first run
|
||||
this.time = time;
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (time - this.time < 500) {
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
return;
|
||||
}
|
||||
|
||||
const dt = time - this.time;
|
||||
this.time = time;
|
||||
|
||||
this.value -= this.f_falloff(this.value) * dt / 1000; // linear falloff
|
||||
|
||||
if (this.value < 0) {
|
||||
this.value = 0;
|
||||
}
|
||||
// console.log(this.value,this.falloff, dt,this.time);
|
||||
|
||||
// TODO: check if this should be different
|
||||
|
||||
const stage = Math.max(0, Math.floor(this.f_stage(this.value)));
|
||||
if (stage != this.stage) {
|
||||
this.changeStage(stage);
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
}
|
||||
|
||||
add(increment) {
|
||||
this.value += typeof increment == 'undefined' ? 1 : increment;
|
||||
// cap:
|
||||
if (this.value > this.value_max) this.value = this.value_max;
|
||||
}
|
||||
|
||||
changeStage(stage) {
|
||||
this.stage = stage;
|
||||
console.log('stage now at', this.stage);
|
||||
for (let fx of Object.values(this.effects)) {
|
||||
fx.setStageHandler(this.stage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function effect(start_stage, end_stage) {
|
||||
return class Effect {
|
||||
constructor() {
|
||||
this.enabled = false;
|
||||
this.start_stage = start_stage;
|
||||
this.end_stage = end_stage;
|
||||
this.intensity = 0;
|
||||
this.intensity_easing = (t) => t; // 0 < t <= 1: use this to make effect eg. more eased
|
||||
}
|
||||
|
||||
setStageHandler(stage) {
|
||||
if (stage < this.start_stage || stage > this.end_stage) {
|
||||
this.disable(stage);
|
||||
} else {
|
||||
this.enable(stage);
|
||||
}
|
||||
}
|
||||
|
||||
enable(stage) {
|
||||
if (!this.enabled) {
|
||||
this.enabled = true;
|
||||
this.enableHandler();
|
||||
}
|
||||
|
||||
const ds = this.end_stage - this.start_stage + 1;
|
||||
if (ds === 1) {
|
||||
this.setIntensity(1);
|
||||
} else {
|
||||
const s = stage - this.start_stage + 1;
|
||||
const t = s / ds;
|
||||
this.setIntensity(this.intensity_easing(t));
|
||||
}
|
||||
}
|
||||
|
||||
disable(stage) {
|
||||
if (this.enabled) {
|
||||
this.enabled = false;
|
||||
this.disableHandler();
|
||||
}
|
||||
}
|
||||
|
||||
setIntensity(intensity) {
|
||||
if (intensity !== this.intensity) {
|
||||
this.intensity = intensity;
|
||||
this.intensityHandler();
|
||||
}
|
||||
}
|
||||
|
||||
enableHandler() {/* to override */ }
|
||||
disableHandler() {/* to override */ }
|
||||
intensityHandler() {/* to override */ }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class ShapeEffect extends effect(3, 10) {
|
||||
getAngles() {
|
||||
if (!this.enabled) {
|
||||
return 4;
|
||||
}
|
||||
if (this.intensity < .3) {
|
||||
return 3;
|
||||
} else if (this.intensity < .7) {
|
||||
return 5;
|
||||
} else {
|
||||
// random pick
|
||||
const corners = [3, 4, 5, 7]
|
||||
return corners[Math.floor(Math.random() * corners.length)];
|
||||
}
|
||||
}
|
||||
}
|
||||
class VideoEffect extends effect(3, 10) {
|
||||
// override enable instead of using handler to apply it gradually
|
||||
disableHandler() {
|
||||
document.getElementById('video_background').style.opacity = 0;
|
||||
}
|
||||
|
||||
intensityHandler() {
|
||||
document.getElementById('video_background').style.opacity = this.intensity;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
|
||||
/*
|
||||
The interface is like a flywheel.
|
||||
*/
|
||||
export class Flywheel{
|
||||
constructor() {
|
||||
this.value = 0.; // start at 0 - gradual meter
|
||||
this.stage = 0.; // start at 0 - the various stages
|
||||
|
||||
this.f_falloff = (value) => value/20; // value at which it reduces per second
|
||||
this.f_stage = (value) => 5*Math.log10(value); // value to stage calculation
|
||||
|
||||
this.value_min = 0;
|
||||
this.value_max = 100; // gives stage 0-9
|
||||
|
||||
// this.interval = window.setInterval(this.step, 50)
|
||||
this.time = null;
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
// TODO: once/twice per second should be enough! + on release (add())
|
||||
}
|
||||
|
||||
step(time){
|
||||
if(this.time === null){
|
||||
// first run
|
||||
this.time = time;
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
return;
|
||||
}
|
||||
|
||||
if(time-this.time < 500){
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
return;
|
||||
}
|
||||
|
||||
const dt = time - this.time;
|
||||
this.time = time;
|
||||
|
||||
this.value -= this.f_falloff(this.value) * dt/1000; // linear falloff
|
||||
|
||||
if(this.value < 0){
|
||||
this.value = 0;
|
||||
}
|
||||
// console.log(this.value,this.falloff, dt,this.time);
|
||||
|
||||
// TODO: check if this should be different
|
||||
|
||||
const stage = Math.max(0,Math.floor(this.f_stage(this.value)));
|
||||
if (stage != this.stage){
|
||||
this.changeStage(stage);
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(this.step.bind(this));
|
||||
}
|
||||
|
||||
add(increment){
|
||||
this.value += typeof increment == 'undefined' ? 1 : increment;
|
||||
// cap:
|
||||
if(this.value > this.value_max) this.value = this.value_max;
|
||||
}
|
||||
|
||||
changeStage(stage){
|
||||
this.stage = stage;
|
||||
console.log('stage now at', this.stage);
|
||||
// TODO: handle stage change
|
||||
}
|
||||
}
|
13
js/game.js
13
js/game.js
|
@ -1,19 +1,16 @@
|
|||
import { Flywheel } from "./flywheel.js";
|
||||
import { Flywheel } from "./effects.js";
|
||||
import { getPathShapeBetweenPoints } from "./svg.js";
|
||||
|
||||
export function init(svgEl, crosshairXEl, crosshairYEl) {
|
||||
let flywheel = new Flywheel();
|
||||
|
||||
|
||||
// use ?3 and ?4 ?28 etc in query string to determine segments
|
||||
const segmentCount = window.location.search.substr(1).length ? window.location.search.substr(1) : 4;
|
||||
|
||||
// canvas position relative to mouse/screen
|
||||
// TODO: update on resize:
|
||||
svgEl.setAttribute('viewBox', '0 0 ' + window.innerWidth + ' ' + window.innerHeight);
|
||||
let rect = svgEl.getBoundingClientRect();
|
||||
// let cx = rect.left + rect.width / 2;
|
||||
// let cy = rect.top + rect.height / 2;
|
||||
// let center = { 'x': cx, 'y': cy };
|
||||
|
||||
// move crosshairs
|
||||
window.addEventListener('mousemove', function (mousemoveEv) {
|
||||
|
@ -27,16 +24,18 @@ export function init(svgEl, crosshairXEl, crosshairYEl) {
|
|||
});
|
||||
|
||||
svgEl.addEventListener('mousedown', function (mousedownEv) {
|
||||
// create shape to draw
|
||||
let shapeEl = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
shapeEl.classList.add('rect');
|
||||
let p1 = { 'x': mousedownEv.clientX - rect.left, 'y': mousedownEv.clientY - rect.top }
|
||||
let d = getPathShapeBetweenPoints(p1, p1, segmentCount);
|
||||
let corners = flywheel.effects.shape.getAngles();
|
||||
let d = getPathShapeBetweenPoints(p1, p1, corners);
|
||||
svgEl.appendChild(shapeEl);
|
||||
shapeEl.setAttribute('d', d);
|
||||
|
||||
let mouseMoveEv = function (mousemoveEv) {
|
||||
let p2 = { 'x': mousemoveEv.clientX - rect.left, 'y': mousemoveEv.clientY - rect.top }
|
||||
let d = getPathShapeBetweenPoints(p1, p2, segmentCount);
|
||||
let d = getPathShapeBetweenPoints(p1, p2, corners);
|
||||
shapeEl.setAttribute('d', d);
|
||||
};
|
||||
let mouseUpEv = function () {
|
||||
|
|
|
@ -5,4 +5,5 @@ let crosshairXEl = document.getElementById('crosshair_x');
|
|||
let crosshairYEl = document.getElementById('crosshair_y');
|
||||
|
||||
|
||||
let game = init(svgEl, crosshairXEl, crosshairYEl);
|
||||
var game = init(svgEl, crosshairXEl, crosshairYEl);
|
||||
console.log('Initialised game', game);
|
Loading…
Reference in a new issue