Skip to content

Instantly share code, notes, and snippets.

@TF3RDL
Created May 26, 2023 08:35
Show Gist options
  • Save TF3RDL/6719807a99f7004fd31bb50514b9c487 to your computer and use it in GitHub Desktop.
Save TF3RDL/6719807a99f7004fd31bb50514b9c487 to your computer and use it in GitHub Desktop.
Trigger-based shake effect from musicvid.org
class TriggerBasedShake {
constructor(
returnSpeed = 0.1,
displacementThreshold = 4,
waveDuration = Math.PI/8,
movementAmount = 1,
maxShakeIntensity = 1,
maxShakeDisplacement = 4,
minShakeScalar = 0.9,
maxShakeScalar = 1.6,
minShakeAmount = 0.2
) {
this.returnSpeed = returnSpeed;
this.sumShakeX = 0;
this.sumShakeY = 0;
this.movementAmount = movementAmount;
this.waveSpeedX = 1;
this.waveSpeedY = 1;
this.waveFrameX = 0;
this.waveFrameY = 0;
this.waveAmplitudeX = 1;
this.waveAmplitudeY = 1;
this.trigX = Math.round(Math.random());
this.trigY = Math.round(Math.random());
this.waveDuration = waveDuration;
this.maxShakeIntensity = maxShakeIntensity;
this.maxShakeDisplacement = maxShakeDisplacement;
this.minShakeScalar = minShakeScalar;
this.maxShakeScalar = maxShakeScalar;
this.minShakeAmount = minShakeAmount;
}
shake (intensity) {
let step = this.maxShakeIntensity * intensity;
this.waveFrameX += step * this.waveSpeedX;
if (intensity <= this.minShakeAmount) {
if (Math.abs(this.sumShakeX) > this.displacementThreshold) {
const l = this.sumShakeX > 0 ? -1 : 1;
this.sumShakeX += this.returnSpeed * l;
}
if (Math.abs(this.sumShakeY) > 0) {
const l = this.sumShakeY > 0 ? -1 : 1;
this.sumShakeY += this.returnSpeed * l;
}
}
if (Math.abs(this.waveFrameX) > this.waveDuration) {
this.waveFrameX = 0;
this.waveAmplitudeX =
this.random(this.minShakeScalar, this.maxShakeScalar) *
this.direction(this.sumShakeX);
this.waveSpeedX =
this.random(this.minShakeScalar, this.maxShakeScalar) *
this.direction(this.sumShakeX);
this.trigX = Math.round(Math.random());
}
this.waveFrameY += step * this.waveSpeedY;
if (Math.abs(this.waveFrameY) > this.waveDuration) {
this.waveFrameY = 0;
this.waveAmplitudeY =
this.random(this.minShakeScalar, this.maxShakeScalar) *
this.direction(this.sumShakeY);
this.waveSpeedY =
this.random(this.minShakeScalar, this.maxShakeScalar) *
this.direction(this.sumShakeY);
this.trigY = Math.round(Math.random());
}
let trigFuncX = this.trigX === 0 ? Math.cos : Math.sin;
let trigFuncY = this.trigY === 0 ? Math.cos : Math.sin;
let dx =
trigFuncX(this.waveFrameX) *
this.maxShakeDisplacement *
this.waveAmplitudeX *
intensity *
this.movementAmount;
let dy =
trigFuncY(this.waveFrameY) *
this.maxShakeDisplacement *
this.waveAmplitudeY *
intensity *
this.movementAmount;
this.sumShakeX += dx;
this.sumShakeY += dy;
}
random(min, max) {
return Math.random() * (max - min) + min;
}
direction (cur) {
let d = cur > 0 ? 1 : -1;
const pull = d * Math.pow(Math.abs(cur), 0.08);
const dir = pull + Math.random();
return dir > 1.0 ? -1 : 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment