Compare commits

...

5 Commits

6 changed files with 136 additions and 21 deletions

View File

@ -6,3 +6,34 @@ early in development and only works on a single dance, Isaac Banner's
["Two Hearts in Time"](https://contradb.com/dances/2014), chosen as a
simple dance (i.e. single progression improper, no shadow or
next/previous neighbor interactions).
## Development
To develop locally, you need
[TypeScript](https://www.typescriptlang.org/download/) installed. You
can check if you have the **`tsc`** (TypeScript Compiler) command available.
While developing, leave the [watch-tsc.sh](./watch-tsc.sh) script running
or, equivalently, run the following the command from the root of the
repository:
```sh
tsc --watch
```
Also, serve the `www/` directory from a local webserver.
The [serve.sh](./serve.sh) script will do this or you can run the
following command from the `www/` directory of the repository:
```sh
python -m http.server --bind localhost 8085
```
(Nothing special about [Python](https://www.python.org/downloads/) here,
just the easiest web server to set up.)
Then open http://localhost:8085/ in a web browser. The site should work
in any modern browser (tested in Firefox and Chromium).
Any text editor/IDE works, but I find
[VS Code](https://code.visualstudio.com/Download)'s
[TypeScript support](https://code.visualstudio.com/Docs/languages/typescript)
works well.

7
serve.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# Change directory to www/ directory.
cd "$(dirname "$0")/www/" || exit
echo "Serving $(pwd)"
# From www/
python -m http.server --bind localhost 8085

7
watch-tsc.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
# Change directory to repo root.
cd "$(dirname "$0")" || exit
echo "Watching $(pwd)"
# From /
tsc --watch

View File

@ -58,29 +58,58 @@
position: sticky;
top: 0;
}
th.Ones.Lark {
background-color: hsl(0, 80%, 50%);
th.Ones {
background-color: hsl(27, 99%, 59%);
}
td.Ones.Lark {
background-color: hsl(0, 90%, 70%);
td.Ones {
background-color: hsl(27, 99%, 85%);
}
th.Ones.Robin {
background-color: hsl(39, 80%, 50%);
th.Twos {
background-color: hsl(249, 42%, 57%);
}
td.Ones.Robin {
background-color: hsl(39, 90%, 70%);
td.Twos {
background-color: hsl(249, 52%, 85%);
}
th.Twos.Lark {
background-color: hsl(240, 70%, 65%);
th.Lark::before {
content: "◠";
text-decoration: line-through;
padding-right: 1ex;
}
td.Twos.Lark {
background-color: hsl(240, 90%, 80%);
th.Robin::before {
content: "△";
padding-right: 1ex;
}
th.Twos.Robin {
background-color: hsl(180, 80%, 50%);
td.Lark.Ones {
background:
radial-gradient(circle at bottom left, hsl(27, 99%, 75%) 15%, transparent 16%),
radial-gradient(circle at bottom right, hsl(27, 99%, 75%) 15%, transparent 16%),
hsl(27, 99%, 85%);
background-size: 6em 3em;
}
td.Twos.Robin {
background-color: hsl(180, 90%, 70%);
td.Lark.Twos {
background:
radial-gradient(circle at bottom left, hsl(249, 42%, 75%) 15%, transparent 16%),
radial-gradient(circle at bottom right,hsl(249, 42%, 75%) 15%, transparent 16%),
hsl(249, 52%, 85%);
background-size: 6em 3em;
}
td.Robin.Ones {
background:
linear-gradient(45deg,hsl(27, 99%, 75%) 10%, transparent 10%),
linear-gradient(135deg, transparent 90%,hsl(27, 99%, 75%) 90%),
hsl(27, 99%, 85%);
background-size: 6em 3em;
}
td.Robin.Twos {
background:
linear-gradient(45deg,hsl(249, 42%, 75%) 10%, transparent 10%),
linear-gradient(135deg, transparent 90%,hsl(249, 42%, 75%) 90%),
hsl(249, 52%, 85%);
background-size: 6em 3em;
}
.move {

View File

@ -421,6 +421,46 @@ displaySettingsDiv.appendChild(document.createElement('br'));
displaySettingsDiv.appendChild(extraLinesLabel);
displaySettingsDiv.appendChild(extraLinesSelector);
const trailIncrementsSelector = document.createElement('input');
trailIncrementsSelector.type = 'number';
trailIncrementsSelector.min = '0';
trailIncrementsSelector.step = '1';
trailIncrementsSelector.value = r.trailIncrements!.toString();
trailIncrementsSelector.id = 'trailIncrements';
trailIncrementsSelector.style.width = '3em';
trailIncrementsSelector.addEventListener('input', (ev) => {
r.trailIncrements = trailIncrementsSelector.valueAsNumber;
drawAtCurrentBeat();
restartAnimation(false);
})
const trailIncrementsLabel = document.createElement('label');
trailIncrementsLabel.innerText = '# trails (faded previous positions): ';
trailIncrementsLabel.htmlFor = 'trailIncrements';
displaySettingsDiv.appendChild(document.createElement('br'));
displaySettingsDiv.appendChild(trailIncrementsLabel);
displaySettingsDiv.appendChild(trailIncrementsSelector);
const trailBeatsSelector = document.createElement('input');
trailBeatsSelector.type = 'number';
trailBeatsSelector.min = '0';
trailBeatsSelector.step = '0.1';
trailBeatsSelector.value = r.trailLengthInBeats!.toPrecision(1);
trailBeatsSelector.id = 'trailBeats';
trailBeatsSelector.style.width = '3em';
trailBeatsSelector.addEventListener('input', (ev) => {
r.trailLengthInBeats = trailBeatsSelector.valueAsNumber;
drawAtCurrentBeat();
restartAnimation(false);
})
const trailBeatsLabel = document.createElement('label');
trailBeatsLabel.innerText = '# max age of trails (faded previous positions) in beats: ';
trailBeatsLabel.htmlFor = 'trailBeats';
displaySettingsDiv.appendChild(document.createElement('br'));
displaySettingsDiv.appendChild(trailBeatsLabel);
displaySettingsDiv.appendChild(trailBeatsSelector);
displaySettingsDiv.appendChild(document.createElement('br'));
displaySettingsDiv.appendChild(debugRender);
displaySettingsDiv.appendChild(debugRenderLabel);

View File

@ -52,6 +52,8 @@ export class Renderer {
animation?: Animation;
extraSets?: number;
extraLines?: number;
trailIncrements: number = 6;
trailLengthInBeats: number = 1;
drawDebug: boolean = false;
constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D) {
@ -170,16 +172,15 @@ export class Renderer {
if (!this.animation) throw new Error("Attempted to render before setting animation.");
this.clear();
const increments = 7;
const trailLengthInBeats = 1;
const incrementLength = trailLengthInBeats / increments;
const increments = this.trailLengthInBeats > 0 && this.trailIncrements > 0 ? this.trailIncrements : 0;
const incrementLength = this.trailLengthInBeats / (increments + 1);
progression ??= 0;
const offsetSets = this.animation.progression.y === 0
? 0
: -((progression - (progression % 2)) / 2) / ((this.animation.progression.y * 2) / setDistance);
for (var i = increments; i >= 0; i--) {
const beatToDraw = beat - i*incrementLength;
this.ctx.globalAlpha = i == 0 ? 1 : (1 - i/increments)*0.3;
const beatToDraw = i == 0 ? beat : beat - i*incrementLength;
this.ctx.globalAlpha = i == 0 ? 1 : (1 - i / (increments + 1)) * 0.3;
const positions = this.animation.positionsAtBeat(beatToDraw, progression % 2);
if (this.drawDebug) this.drawSets(positions, offsetSets, true, true);
this.drawSets(positions, offsetSets, i === 0, false);