commit #6
This commit is contained in:
parent
d1d326cfa8
commit
202d0ff272
27 changed files with 474 additions and 639 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@ build/
|
|||
/run/
|
||||
|
||||
/.idea/
|
||||
/src/main/resources/ui/*
|
||||
|
|
|
@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||
plugins {
|
||||
kotlin("jvm")
|
||||
kotlin("plugin.serialization")
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
application
|
||||
}
|
||||
|
||||
|
@ -11,7 +12,7 @@ version = "1.0-SNAPSHOT"
|
|||
|
||||
allprojects {
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "16"
|
||||
kotlinOptions.jvmTarget = "19"
|
||||
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
|
||||
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.ExperimentalUnsignedTypes"
|
||||
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.contracts.ExperimentalContracts"
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package de.moritzruth.lampenfieber
|
||||
|
||||
import de.moritzruth.lampenfieber.device.CoemarProWash
|
||||
import de.moritzruth.lampenfieber.device.FuturelightDmh160
|
||||
import de.moritzruth.lampenfieber.device.SimpleDimmer
|
||||
import de.moritzruth.lampenfieber.device.StairvilleTriLedBar
|
||||
import de.moritzruth.lampenfieber.device.Wash
|
||||
import de.moritzruth.theaterdsl.dmx.DmxAddress
|
||||
import de.moritzruth.theaterdsl.dmx.EnttecOpenDmxUsb
|
||||
import de.moritzruth.theaterdsl.show.StepCue
|
||||
|
@ -12,11 +13,12 @@ import de.moritzruth.theaterdsl.value.Color
|
|||
import de.moritzruth.theaterdsl.value.degrees
|
||||
import de.moritzruth.theaterdsl.value.percent
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
val bar = StairvilleTriLedBar(DmxAddress(400u))
|
||||
|
||||
object FrontLights {
|
||||
val left = listOf(SimpleDimmer(DmxAddress(1u)), SimpleDimmer(DmxAddress(2u)))
|
||||
val center = listOf(SimpleDimmer(DmxAddress(4u)), SimpleDimmer(DmxAddress(5u)))
|
||||
|
@ -27,62 +29,174 @@ object FrontLights {
|
|||
val spotLeft = SimpleDimmer(DmxAddress(10u))
|
||||
val spotRight = SimpleDimmer(DmxAddress(11u))
|
||||
|
||||
// Nebel: SF-1500
|
||||
|
||||
object Washs {
|
||||
val left = Wash(DmxAddress(85u))
|
||||
val right = Wash(DmxAddress(101u))
|
||||
val all = listOf(left, right)
|
||||
object Tops {
|
||||
val left = FuturelightDmh160(DmxAddress(37u))
|
||||
val right = FuturelightDmh160(DmxAddress(53u))
|
||||
val both = listOf(left, right)
|
||||
}
|
||||
|
||||
val devices = persistentSetOf(bar, *FrontLights.all.toTypedArray(), spotLeft, spotRight, *Washs.all.toTypedArray())
|
||||
object Washs {
|
||||
val left = CoemarProWash(DmxAddress(85u), false)
|
||||
val right = CoemarProWash(DmxAddress(101u), true)
|
||||
val both = listOf(left, right)
|
||||
}
|
||||
|
||||
val bar = StairvilleTriLedBar(DmxAddress(121u)) // TODO: Change address on the device
|
||||
|
||||
val devices = persistentSetOf(*FrontLights.all.toTypedArray(), spotLeft, spotRight, *Tops.both.toTypedArray(), *Washs.both.toTypedArray(), bar)
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
val show = createShow {
|
||||
act("Erster Akt") {
|
||||
scene("I") {
|
||||
step {
|
||||
trigger = StepCue.MusicStart("Lampenfieber", 69.seconds)
|
||||
scene("Intro") {
|
||||
step(StepCue.MusicStart("Lampenfieber", 5.minutes + 30.seconds)) {
|
||||
props {
|
||||
|
||||
}
|
||||
|
||||
onRun {
|
||||
// Lichteffekte in der Aula
|
||||
spotRight.brightness.static(100.percent)
|
||||
Washs.both.forEach {
|
||||
it.pointAtCeiling()
|
||||
it.colorWheelMode.static(CoemarProWash.ColorWheelMode.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Einsatz (Takt 17)")) {
|
||||
Washs.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
|
||||
FrontLights.all.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds, start = 20.percent) }
|
||||
|
||||
Tops.both.forEach { it.startRoomMovement(5.5) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
launch {
|
||||
delay(500)
|
||||
Washs.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
}
|
||||
|
||||
Tops.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
Washs.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
|
||||
FrontLights.all.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds, start = 20.percent) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
launch {
|
||||
delay(500)
|
||||
Washs.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
}
|
||||
|
||||
Tops.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
Washs.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
|
||||
FrontLights.all.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds, start = 20.percent) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
launch {
|
||||
delay(500)
|
||||
Washs.both.forEach {
|
||||
it.brightness.pulseOnce(500.milliseconds, 5.seconds)
|
||||
}
|
||||
}
|
||||
|
||||
Tops.both.forEach { it.brightness.pulseOnce(500.milliseconds, 5.seconds) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
Washs.both.forEach { it.brightness.fade(100.percent, 500.milliseconds) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
Tops.both.forEach { it.brightness.fade(100.percent, 500.milliseconds) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
FrontLights.center.forEach { it.brightness.pulseOnce(500.milliseconds, 3.seconds, end = 50.percent) }
|
||||
}
|
||||
|
||||
lightStep(StepCue.Custom("Gitarren-Ton")) {
|
||||
FrontLights.center.forEach { it.brightness.fade(0.percent, 30.seconds) }
|
||||
Washs.both.forEach { it.colorWheelMode.static(CoemarProWash.ColorWheelMode.Rotate(20.percent)) }
|
||||
Tops.both.forEach { it.colorWheelMode.static(FuturelightDmh160.ColorWheelMode.Rotate(20.percent)) }
|
||||
}
|
||||
|
||||
step(StepCue.Text("Chor", "fangen wir an")) {
|
||||
onRun {
|
||||
FrontLights.center.forEach { it.brightness.fade(0.percent, 3.seconds) }
|
||||
Washs.both.forEach { it.brightness.fade(0.percent, 3.seconds) }
|
||||
Tops.both.forEach { it.brightness.fade(0.percent, 3.seconds) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene("I.1") {
|
||||
step {
|
||||
trigger = StepCue.MusicEnd
|
||||
scene("1.1") {
|
||||
step(StepCue.MusicEnd) {
|
||||
actors {
|
||||
+"Richy / durch den Mittelgang"
|
||||
+"Christine / steht auf der Vorbühne"
|
||||
+"Andreas / steht auf der Vorbühne"
|
||||
+"Steffi / steht auf der Vorbühne"
|
||||
+"Jakob / steht auf der Vorbühne"
|
||||
+"Tina / steht auf der Vorbühne"
|
||||
}
|
||||
|
||||
onRun {
|
||||
spotRight.brightness.static(0.percent)
|
||||
|
||||
spotRight.brightness.fade(100.percent, 6.seconds)
|
||||
FrontLights.center.forEach { it.brightness.fade(75.percent, 10.seconds) }
|
||||
Washs.both.forEach {
|
||||
it.pointAtStageCenter()
|
||||
it.colorWheelMode.static(CoemarProWash.ColorWheelMode.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
step {
|
||||
trigger = StepCue.MusicStart("Rap", 69.seconds)
|
||||
step(StepCue.MusicStart("Rap", 2.minutes + 30.seconds)) {
|
||||
actors {
|
||||
// Rapper, Tänzer
|
||||
}
|
||||
|
||||
onRun {
|
||||
// sehr viel
|
||||
// Nebel, rot-orange faden
|
||||
FrontLights.center.forEach { it.brightness.fade(20.percent, 10.seconds) }
|
||||
bar.color.static(Color(100.degrees))
|
||||
bar.brightness.fade(75.percent, 10.seconds)
|
||||
bar.brightness.fade(50.percent, 10.seconds)
|
||||
bar.color.fadeRandomAround(20.degrees, 10.degrees, 1500.milliseconds)
|
||||
}
|
||||
}
|
||||
|
||||
step {
|
||||
trigger = StepCue.MusicEnd
|
||||
lightStep(StepCue.Custom("T5 S2")) {
|
||||
Washs.both.forEach {
|
||||
it.brightness.static(100.percent)
|
||||
it.beamAngle.sine(0.percent, 100.percent, 3.seconds)
|
||||
}
|
||||
}
|
||||
|
||||
onRun {
|
||||
FrontLights.center.forEach { it.brightness.fade(0.percent, 10.seconds) }
|
||||
bar.brightness.fade(0.percent, 2.seconds)
|
||||
lightStep(StepCue.Custom("Schlussschlag")) {
|
||||
Washs.both.forEach {
|
||||
it.beamAngle.fade(100.percent, 200.milliseconds)
|
||||
it.brightness.fade(0.percent, 4.seconds)
|
||||
}
|
||||
|
||||
bar.brightness.fade(0.percent, 1.seconds)
|
||||
FrontLights.center.forEach { it.brightness.pulseOnce(200.milliseconds, 4.seconds, end = 50.percent) }
|
||||
}
|
||||
|
||||
step(StepCue.MusicEnd) {
|
||||
actors {
|
||||
// Rapper, Tänzer ab
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene("I.2") {
|
||||
scene("1.2") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -100,7 +214,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("I.3") {
|
||||
scene("1.3") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -111,7 +225,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("I.3") {
|
||||
scene("1.3") {
|
||||
step {
|
||||
trigger = StepCue.Custom("Bühne erreicht")
|
||||
|
||||
|
@ -124,7 +238,7 @@ val show = createShow {
|
|||
// David spielt: Licht links
|
||||
}
|
||||
|
||||
scene("I.5") {
|
||||
scene("1.5") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -132,7 +246,7 @@ val show = createShow {
|
|||
FrontLights.all.forEach { it.brightness.fade(0.percent, 10.seconds) }
|
||||
FrontLights.right.forEach { it.brightness.fade(50.percent, 10.seconds) }
|
||||
|
||||
Washs.all.forEach {
|
||||
Washs.both.forEach {
|
||||
it.brightness.fade(75.percent, 10.seconds)
|
||||
// Blau
|
||||
}
|
||||
|
@ -148,7 +262,7 @@ val show = createShow {
|
|||
onRun {
|
||||
FrontLights.right.forEach { it.brightness.fade(0.percent, 10.seconds) }
|
||||
|
||||
Washs.all.forEach {
|
||||
Washs.both.forEach {
|
||||
it.brightness.fade(100.percent, 10.seconds)
|
||||
}
|
||||
|
||||
|
@ -161,13 +275,13 @@ val show = createShow {
|
|||
|
||||
onRun {
|
||||
FrontLights.right.forEach { it.brightness.off() }
|
||||
Washs.all.forEach { it.brightness.off() }
|
||||
Washs.both.forEach { it.brightness.off() }
|
||||
// Nebel aus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene("II.1") {
|
||||
scene("2.1") {
|
||||
step {
|
||||
trigger = StepCue.MusicStart("Computerspiel", 69.seconds)
|
||||
|
||||
|
@ -177,7 +291,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("II.2") {
|
||||
scene("2.2") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -188,7 +302,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("II.3") {
|
||||
scene("2.3") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -240,7 +354,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("III.1") {
|
||||
scene("3.1") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -253,7 +367,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("III.2") {
|
||||
scene("3.2") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -272,14 +386,14 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("III.3") {
|
||||
scene("3.3") {
|
||||
step {
|
||||
trigger = StepCue.MusicStart("Tischballet", 69.seconds)
|
||||
// Instrumental, Umbau zu Musiksaal
|
||||
}
|
||||
}
|
||||
|
||||
scene("III.4") {
|
||||
scene("3.4") {
|
||||
step {
|
||||
trigger = StepCue.MusicEnd
|
||||
// Vorhang auf
|
||||
|
@ -298,7 +412,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("III.5") {
|
||||
scene("3.5") {
|
||||
step {
|
||||
trigger = StepCue.Custom("Ende")
|
||||
|
||||
|
@ -311,7 +425,7 @@ val show = createShow {
|
|||
// Umbau-Musik
|
||||
}
|
||||
|
||||
scene("III.6") {
|
||||
scene("3.6") {
|
||||
step {
|
||||
trigger = StepCue.Custom("Vorhang auf, Musik Ende")
|
||||
|
||||
|
@ -322,7 +436,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("III.7") {
|
||||
scene("3.7") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -333,7 +447,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("III.8") {
|
||||
scene("3.8") {
|
||||
step {
|
||||
trigger = StepCue.MusicEnd
|
||||
|
||||
|
@ -372,7 +486,7 @@ val show = createShow {
|
|||
|
||||
// RnR entfällt
|
||||
|
||||
scene("IV.1") {
|
||||
scene("4.1") {
|
||||
step {
|
||||
trigger = StepCue.MusicStart("Pause", 69.seconds)
|
||||
}
|
||||
|
@ -413,7 +527,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.2") {
|
||||
scene("4.2") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -432,7 +546,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.3") {
|
||||
scene("4.3") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -443,7 +557,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.4") {
|
||||
scene("4.4") {
|
||||
step {
|
||||
trigger = StepCue.Custom("Auftritt David")
|
||||
|
||||
|
@ -475,7 +589,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.5") {
|
||||
scene("4.5") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -493,7 +607,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.6") {
|
||||
scene("4.6") {
|
||||
step {
|
||||
trigger = StepCue.MusicEnd
|
||||
|
||||
|
@ -516,7 +630,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.7") {
|
||||
scene("4.7") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -545,7 +659,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.8") {
|
||||
scene("4.8") {
|
||||
step {
|
||||
trigger = StepCue.MusicStart("Angstballet", 69.seconds)
|
||||
|
||||
|
@ -559,7 +673,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.9") {
|
||||
scene("4.9") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
@ -577,7 +691,7 @@ val show = createShow {
|
|||
}
|
||||
}
|
||||
|
||||
scene("IV.10") {
|
||||
scene("4.10") {
|
||||
step {
|
||||
trigger = StepCue.Stub
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package de.moritzruth.lampenfieber.device
|
||||
|
||||
import de.moritzruth.theaterdsl.device.AngleDV
|
||||
import de.moritzruth.theaterdsl.device.ConcreteDV
|
||||
import de.moritzruth.theaterdsl.device.Device
|
||||
import de.moritzruth.theaterdsl.device.PercentageDV
|
||||
import de.moritzruth.theaterdsl.dmx.DmxAddress
|
||||
import de.moritzruth.theaterdsl.dmx.DmxDataWriter
|
||||
import de.moritzruth.theaterdsl.dmx.DmxValue
|
||||
import de.moritzruth.theaterdsl.value.Percentage
|
||||
import de.moritzruth.theaterdsl.value.degrees
|
||||
import de.moritzruth.theaterdsl.value.percent
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class CoemarProWash(override val firstChannel: DmxAddress, private val isRight: Boolean) : Device {
|
||||
companion object {
|
||||
private const val PAN_LIMIT = 530f // degrees
|
||||
private const val TILT_LIMIT = 284f // degrees
|
||||
}
|
||||
|
||||
override val numberOfChannels: UInt = 16u
|
||||
|
||||
override fun writeDmxData(writer: DmxDataWriter) {
|
||||
val pan = (pan.getCurrentValue().degrees.mod(PAN_LIMIT) / PAN_LIMIT * 65536).roundToInt().toUShort()
|
||||
val tilt = (tilt.getCurrentValue().degrees.mod(TILT_LIMIT) / TILT_LIMIT * 65536).roundToInt().toUShort()
|
||||
|
||||
writer.writeHighByte(pan)
|
||||
writer.writeHighByte(tilt)
|
||||
writer.writeLowByte(pan)
|
||||
writer.writeLowByte(tilt)
|
||||
writer.writeRaw(DmxValue(0u)) // pan/tilt speed = maximum
|
||||
writer.writeRaw(DmxValue(255u)) // fan speed and lamp control = no function
|
||||
writer.writeRaw(colorWheelMode.getCurrentValue().getDmxValue())
|
||||
writer.writePercentage(cyan.getCurrentValue())
|
||||
writer.writePercentage(magenta.getCurrentValue())
|
||||
writer.writePercentage(yellow.getCurrentValue())
|
||||
writer.writeRaw(DmxValue(0u)) // dimmer and color speed = maximum
|
||||
writer.writeRaw(DmxValue(0u)) // colour macro = off
|
||||
writer.writeRaw(DmxValue((beamAngle.getCurrentValue().value * 109 + 71).roundToInt().toUByte()))
|
||||
writer.writeRaw(DmxValue(0u)) // no function
|
||||
writer.writeRaw(DmxValue((strobeSpeed.getCurrentValue().value * 32 + 63).roundToInt().toUByte()))
|
||||
writer.writePercentage(brightness.getCurrentValue())
|
||||
}
|
||||
|
||||
sealed interface ColorWheelMode {
|
||||
fun getDmxValue(): DmxValue
|
||||
sealed class Simple(dmxValue: Int) : ColorWheelMode {
|
||||
val dmxValue = DmxValue(dmxValue.toUByte())
|
||||
override fun getDmxValue() = dmxValue
|
||||
}
|
||||
|
||||
class Rotate(val speed: Percentage, val backwards: Boolean = false) : ColorWheelMode {
|
||||
override fun getDmxValue() = run {
|
||||
if (backwards) ((1f - speed.value) * 62).roundToInt() + 193
|
||||
else (speed.value * 62).roundToInt() + 128
|
||||
}.let { DmxValue(it.toUByte()) }
|
||||
}
|
||||
|
||||
object White : Simple(0)
|
||||
object Red : Simple(20)
|
||||
object DarkBlue : Simple(48)
|
||||
object Green : Simple(70)
|
||||
object WarmWhite : Simple(81)
|
||||
object Violet : Simple(118)
|
||||
}
|
||||
|
||||
val pan = AngleDV()
|
||||
val tilt = AngleDV()
|
||||
val brightness = PercentageDV()
|
||||
val beamAngle = PercentageDV(100.percent)
|
||||
val strobeSpeed = PercentageDV(0.percent)
|
||||
|
||||
val colorWheelMode = ConcreteDV<ColorWheelMode>(ColorWheelMode.White)
|
||||
val cyan = PercentageDV()
|
||||
val magenta = PercentageDV()
|
||||
val yellow = PercentageDV()
|
||||
|
||||
override val dvs = persistentSetOf(
|
||||
pan, tilt, brightness, beamAngle, strobeSpeed, colorWheelMode, cyan, magenta, yellow
|
||||
)
|
||||
|
||||
fun pointAtStageCenter() {
|
||||
tilt.static(80.degrees)
|
||||
pan.static(if (isRight) 270.degrees else 90.degrees)
|
||||
}
|
||||
|
||||
fun pointAtCeiling() {
|
||||
tilt.static(180.degrees)
|
||||
pan.static(0.degrees)
|
||||
}
|
||||
}
|
|
@ -1,13 +1,18 @@
|
|||
package de.moritzruth.lampenfieber.device
|
||||
|
||||
import de.moritzruth.theaterdsl.device.AngleDV
|
||||
import de.moritzruth.theaterdsl.device.ConcreteDV
|
||||
import de.moritzruth.theaterdsl.device.Device
|
||||
import de.moritzruth.theaterdsl.device.PercentageDV
|
||||
import de.moritzruth.theaterdsl.dmx.DmxAddress
|
||||
import de.moritzruth.theaterdsl.dmx.DmxDataWriter
|
||||
import de.moritzruth.theaterdsl.dmx.get16BitChannelValues
|
||||
import de.moritzruth.theaterdsl.dmx.DmxValue
|
||||
import de.moritzruth.theaterdsl.value.Percentage
|
||||
import de.moritzruth.theaterdsl.value.degrees
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class FuturelightDmh160(override val firstChannel: DmxAddress) : Device {
|
||||
companion object {
|
||||
|
@ -18,22 +23,72 @@ class FuturelightDmh160(override val firstChannel: DmxAddress) : Device {
|
|||
override val numberOfChannels: UInt = 16u
|
||||
|
||||
override fun writeDmxData(writer: DmxDataWriter) {
|
||||
val fullPan = (pan.getCurrentValue().degrees.mod(PAN_LIMIT) / PAN_LIMIT * 65536).roundToInt()
|
||||
val (mPan, lPan) = fullPan.get16BitChannelValues()
|
||||
val pan = (pan.getCurrentValue().degrees.mod(PAN_LIMIT) / PAN_LIMIT * 65536).roundToInt().toUShort()
|
||||
val tilt = (tilt.getCurrentValue().degrees.mod(TILT_LIMIT) / TILT_LIMIT * 65536).roundToInt().toUShort()
|
||||
|
||||
val fullTilt = (tilt.getCurrentValue().degrees.mod(TILT_LIMIT) / TILT_LIMIT * 65536).roundToInt()
|
||||
val (mTilt, lTilt) = fullTilt.get16BitChannelValues()
|
||||
|
||||
writer.writeRaw(mPan)
|
||||
writer.writeRaw(lPan)
|
||||
writer.writeRaw(mTilt)
|
||||
writer.writeRaw(lTilt)
|
||||
writer.writeHighByte(pan)
|
||||
writer.writeLowByte(pan)
|
||||
writer.writeHighByte(tilt)
|
||||
writer.writeLowByte(tilt)
|
||||
writer.writeRaw(DmxValue(0u)) // pan/tilt speed
|
||||
writer.writeRaw(DmxValue(0u)) // blackout while moving = off
|
||||
writer.writeRaw(DmxValue((strobeSpeed.getCurrentValue().value * 32 + 63).roundToInt().toUByte()))
|
||||
writer.writePercentage(brightness.getCurrentValue())
|
||||
writer.writeRaw(colorWheelMode.getCurrentValue().getDmxValue())
|
||||
writer.writeRaw(DmxValue(0u)) // gobo wheel = open
|
||||
writer.writeRaw(DmxValue(0u)) // gobo wheel = open
|
||||
writer.writeRaw(prismMode.getCurrentValue().dmxValue)
|
||||
writer.writeRaw(DmxValue((prismRotationSpeed.getCurrentValue().value * 123 + 4).roundToInt().toUByte()))
|
||||
writer.writeRaw(DmxValue(255u)) // focus = maximum distance
|
||||
writer.writeRaw(DmxValue(0u)) // iris = ?
|
||||
writer.writeRaw(DmxValue(0u)) // functions = noop
|
||||
}
|
||||
|
||||
sealed interface ColorWheelMode {
|
||||
fun getDmxValue(): DmxValue
|
||||
sealed class Simple(dmxValue: Int) : ColorWheelMode {
|
||||
val dmxValue = DmxValue(dmxValue.toUByte())
|
||||
override fun getDmxValue() = dmxValue
|
||||
}
|
||||
|
||||
class Rotate(val speed: Percentage, val backwards: Boolean = false) : ColorWheelMode {
|
||||
override fun getDmxValue() = run {
|
||||
if (backwards) (speed.value * 15).roundToInt() + 240
|
||||
else (speed.value * 15).roundToInt() + 224
|
||||
}.let { DmxValue(it.toUByte()) }
|
||||
}
|
||||
|
||||
object White : Simple(0)
|
||||
object Pink : Simple(0)
|
||||
object Red : Simple(0)
|
||||
object Orange : Simple(0)
|
||||
object Green : Simple(0)
|
||||
object LightBlue : Simple(0)
|
||||
object DarkBlue : Simple(0)
|
||||
object Violet : Simple(0)
|
||||
}
|
||||
|
||||
enum class PrismMode(val dmxValue: DmxValue) {
|
||||
OPEN(DmxValue(0u)),
|
||||
FACETS_3(DmxValue(64u)),
|
||||
FACETS_8(DmxValue(128u)),
|
||||
FROST(DmxValue(192u))
|
||||
}
|
||||
|
||||
val pan = AngleDV()
|
||||
val tilt = AngleDV()
|
||||
val brightness = PercentageDV()
|
||||
val colorWheelMode = ConcreteDV<ColorWheelMode>(ColorWheelMode.White)
|
||||
val strobeSpeed = PercentageDV()
|
||||
val prismMode = ConcreteDV(PrismMode.OPEN)
|
||||
val prismRotationSpeed = PercentageDV()
|
||||
|
||||
override val dvs = persistentSetOf(brightness)
|
||||
fun startRoomMovement(rotationsPerMinute: Double) {
|
||||
pan.sine(0.degrees, 360.degrees, 1.minutes / rotationsPerMinute)
|
||||
tilt.fade(120.degrees, 3.seconds)
|
||||
}
|
||||
|
||||
override val dvs = persistentSetOf(
|
||||
pan, tilt, brightness, colorWheelMode, strobeSpeed
|
||||
)
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package de.moritzruth.lampenfieber.device
|
||||
|
||||
import de.moritzruth.theaterdsl.device.AngleDV
|
||||
import de.moritzruth.theaterdsl.device.Device
|
||||
import de.moritzruth.theaterdsl.device.PercentageDV
|
||||
import de.moritzruth.theaterdsl.dmx.DmxAddress
|
||||
import de.moritzruth.theaterdsl.dmx.DmxDataWriter
|
||||
import de.moritzruth.theaterdsl.dmx.DmxValue
|
||||
import de.moritzruth.theaterdsl.dmx.get16BitChannelValues
|
||||
import de.moritzruth.theaterdsl.value.percent
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class Wash(override val firstChannel: DmxAddress) : Device {
|
||||
companion object {
|
||||
private const val PAN_LIMIT = 630f // degrees
|
||||
private const val TILT_LIMIT = 270f // degrees
|
||||
}
|
||||
|
||||
override val numberOfChannels: UInt = 16u
|
||||
|
||||
override fun writeDmxData(writer: DmxDataWriter) {
|
||||
val fullPan = (pan.getCurrentValue().degrees.mod(PAN_LIMIT) / PAN_LIMIT * 65536).roundToInt()
|
||||
val (mPan, lPan) = fullPan.get16BitChannelValues()
|
||||
|
||||
val fullTilt = (tilt.getCurrentValue().degrees.mod(TILT_LIMIT) / TILT_LIMIT * 65536).roundToInt()
|
||||
val (mTilt, lTilt) = fullTilt.get16BitChannelValues()
|
||||
|
||||
writer.writeRaw(DmxValue(130u))
|
||||
writer.writeRaw(DmxValue(200u))
|
||||
writer.writeRaw(lPan)
|
||||
writer.writeRaw(lTilt)
|
||||
writer.writeRaw(DmxValue(0u))
|
||||
writer.writeRaw(DmxValue(0u))
|
||||
writer.writePercentage(white.getCurrentValue())
|
||||
writer.writePercentage(cyan.getCurrentValue())
|
||||
writer.writePercentage(magenta.getCurrentValue())
|
||||
writer.writePercentage(yellow.getCurrentValue())
|
||||
writer.writeRaw(DmxValue(0u))
|
||||
writer.writeRaw(DmxValue(0u))
|
||||
writer.writePercentage(beamSize.getCurrentValue())
|
||||
writer.writeRaw(DmxValue(0u))
|
||||
writer.writeRaw(DmxValue(47u))
|
||||
writer.writePercentage(brightness.getCurrentValue())
|
||||
}
|
||||
|
||||
val pan = AngleDV()
|
||||
val tilt = AngleDV()
|
||||
val brightness = PercentageDV()
|
||||
|
||||
val white = PercentageDV()
|
||||
val cyan = PercentageDV()
|
||||
val magenta = PercentageDV()
|
||||
val yellow = PercentageDV()
|
||||
val beamSize = PercentageDV(100.percent)
|
||||
|
||||
override val dvs = persistentSetOf(
|
||||
pan,
|
||||
tilt,
|
||||
brightness,
|
||||
white,
|
||||
cyan,
|
||||
magenta,
|
||||
yellow,
|
||||
beamSize
|
||||
)
|
||||
}
|
|
@ -8,6 +8,7 @@ import kotlin.math.PI
|
|||
import kotlin.math.asin
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sin
|
||||
import kotlin.random.Random
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.TimeSource
|
||||
|
@ -40,10 +41,13 @@ abstract class FloatDV<T>(private val initialStaticValue: Float) : DynamicValue<
|
|||
}
|
||||
|
||||
data class Step(val steps: ImmutableList<Float>, val interval: Duration, val startIndex: Int) : State
|
||||
data class PulseOnce(val rampUpDuration: Duration, val rampDownDuration: Duration, val peakValue: Float, val start: Float, val end: Float) : State
|
||||
}
|
||||
|
||||
protected abstract fun toDomain(value: Float): T
|
||||
protected abstract fun fromDomain(value: T): Float
|
||||
protected abstract val minimumValue: T
|
||||
protected abstract val maximumValue: T
|
||||
|
||||
private var stateChangeMark = TimeSource.Monotonic.markNow()
|
||||
private var state: State = State.Static(initialStaticValue)
|
||||
|
@ -74,6 +78,18 @@ abstract class FloatDV<T>(private val initialStaticValue: Float) : DynamicValue<
|
|||
val index = (elapsedTime / s.interval).toInt() + s.startIndex
|
||||
s.steps[index.mod(s.steps.size)]
|
||||
}
|
||||
|
||||
is State.PulseOnce -> {
|
||||
if (elapsedTime <= s.rampUpDuration) {
|
||||
val progress = elapsedTime / s.rampUpDuration
|
||||
val delta = s.peakValue - s.start
|
||||
(progress * delta + s.start).toFloat()
|
||||
} else {
|
||||
val progress = min(elapsedTime / s.rampDownDuration, 1.0)
|
||||
val delta = s.end - s.peakValue
|
||||
(progress * delta + s.end).toFloat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toDomain(float)
|
||||
|
@ -107,16 +123,44 @@ abstract class FloatDV<T>(private val initialStaticValue: Float) : DynamicValue<
|
|||
|
||||
steps(persistentListOf(a, b), interval, startIndex)
|
||||
}
|
||||
|
||||
fun pulseOnce(rampUpDuration: Duration, rampDownDuration: Duration, peakValue: T = maximumValue, end: T = minimumValue, start: T = getCurrentValue()) {
|
||||
state = State.PulseOnce(rampUpDuration, rampDownDuration, fromDomain(peakValue), fromDomain(start), fromDomain(end))
|
||||
}
|
||||
}
|
||||
|
||||
class PercentageDV(initialStaticValue: Percentage = 0.percent) : FloatDV<Percentage>(initialStaticValue.value) {
|
||||
override fun fromDomain(value: Percentage): Float = value.value
|
||||
override fun toDomain(value: Float): Percentage = Percentage(value)
|
||||
override val minimumValue: Percentage = 0.percent
|
||||
override val maximumValue: Percentage = 100.percent
|
||||
}
|
||||
|
||||
class AngleDV(initialStaticValue: Angle = 0.degrees) : FloatDV<Angle>(initialStaticValue.degrees) {
|
||||
override fun fromDomain(value: Angle): Float = value.degrees
|
||||
override fun toDomain(value: Float): Angle = Angle(value)
|
||||
override val minimumValue: Angle = 0.degrees
|
||||
override val maximumValue: Angle = 360.degrees
|
||||
}
|
||||
|
||||
class ConcreteDV<T>(private val initialStaticValue: T) : DynamicValue<T> {
|
||||
sealed interface State<T> {
|
||||
class Static<T>(val value: T) : State<T>
|
||||
}
|
||||
|
||||
var state: State<T> = State.Static(initialStaticValue)
|
||||
|
||||
override fun reset() {
|
||||
state = State.Static(initialStaticValue)
|
||||
}
|
||||
|
||||
override fun getCurrentValue(): T = when (val s = state) {
|
||||
is State.Static -> s.value
|
||||
}
|
||||
|
||||
fun static(value: T) {
|
||||
state = State.Static(value)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTime::class)
|
||||
|
@ -128,6 +172,8 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu
|
|||
val deltaSaturation = end.saturation.value - start.saturation.value
|
||||
val deltaBrightness = end.brightness.value - start.brightness.value
|
||||
}
|
||||
|
||||
data class FadeRandomAround(val hue: Angle, val deviation: Angle, val interval: Duration) : State
|
||||
}
|
||||
|
||||
private var stateChangeMark = TimeSource.Monotonic.markNow()
|
||||
|
@ -155,6 +201,11 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu
|
|||
brightness = Percentage((s.start.brightness.value + s.deltaBrightness * progress).toFloat())
|
||||
)
|
||||
}
|
||||
|
||||
is State.FadeRandomAround -> {
|
||||
val random = Random((elapsedTime / s.interval).toInt())
|
||||
Color(hue = Angle(s.hue.degrees - (s.deviation.degrees / 2) + random.nextFloat() * s.deviation.degrees))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,4 +216,8 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu
|
|||
fun fade(end: Color, duration: Duration, start: Color = getCurrentValue()) {
|
||||
state = State.Fade(start, end, duration)
|
||||
}
|
||||
|
||||
fun fadeRandomAround(hue: Angle, deviation: Angle, interval: Duration) {
|
||||
state = State.FadeRandomAround(hue, deviation, interval)
|
||||
}
|
||||
}
|
|
@ -12,4 +12,7 @@ interface DmxDataWriter {
|
|||
*/
|
||||
fun writeInRange(range: ClosedFloatingPointRange<Float>, value: Float, startAtOne: Boolean = false) =
|
||||
writeRaw(Percentage((value - range.start) / (range.endInclusive - range.start)).roundToDmxValue(startAtOne))
|
||||
|
||||
fun writeHighByte(value: UShort) = writeRaw(DmxValue(value.toUInt().shr(8).toUByte()))
|
||||
fun writeLowByte(value: UShort) = writeRaw(DmxValue(value.toUByte()))
|
||||
}
|
||||
|
|
|
@ -18,8 +18,3 @@ value class DmxValue(val value: UByte) : Comparable<UByte> {
|
|||
fun Percentage.roundToDmxValue(startAtOne: Boolean = false): DmxValue =
|
||||
if (startAtOne) DmxValue(((value * (DmxValue.VALUE_RANGE.last.toFloat() - 1f)).roundToInt() + 1).toUByte())
|
||||
else DmxValue((value * DmxValue.VALUE_RANGE.last.toFloat()).roundToInt().toUByte())
|
||||
|
||||
fun Int.get16BitChannelValues(): Pair<DmxValue, DmxValue> = Pair(
|
||||
DmxValue((this.rotateRight(7) and 0x11111111).toUByte()),
|
||||
DmxValue((this and 0x11111111).toUByte())
|
||||
)
|
|
@ -66,8 +66,7 @@ object EnttecOpenDmxUsb {
|
|||
Thread.sleep(23)
|
||||
}
|
||||
} catch (exception: SerialPortIOException) {
|
||||
exception.printStackTrace()
|
||||
port.closePort()
|
||||
// only thrown when the program is stopped
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,13 @@ interface ActBuilderContext {
|
|||
|
||||
@TheaterDslMarker
|
||||
interface SceneBuilderContext {
|
||||
fun step(build: StepDataBuilderContext.() -> Unit)
|
||||
fun step(cue: StepCue = StepCue.Stub, build: StepDataBuilderContext.() -> Unit)
|
||||
fun lightStep(cue: StepCue, runner: StepRunner)
|
||||
}
|
||||
|
||||
@TheaterDslMarker
|
||||
interface StepDataBuilderContext {
|
||||
@Deprecated("")
|
||||
var trigger: StepCue
|
||||
val props: PropsBuilderMap
|
||||
|
||||
|
@ -88,8 +90,13 @@ private fun buildAct(actIndex: Int, name: String, build: ActBuilderContext.() ->
|
|||
val steps = mutableListOf<Step>()
|
||||
|
||||
object : SceneBuilderContext {
|
||||
override fun step(build: StepDataBuilderContext.() -> Unit) {
|
||||
var nullableTrigger: StepCue? = null
|
||||
override fun lightStep(cue: StepCue, runner: StepRunner) {
|
||||
step(cue) {
|
||||
onRun(runner)
|
||||
}
|
||||
}
|
||||
|
||||
override fun step(cue: StepCue, build: StepDataBuilderContext.() -> Unit) {
|
||||
val changedProps = mutableMapOf<PropPosition, StringWithDetails?>()
|
||||
val actorEntrances = mutableSetOf<StringWithDetails>()
|
||||
val actorExits = mutableSetOf<StringWithDetails>()
|
||||
|
@ -97,10 +104,8 @@ private fun buildAct(actIndex: Int, name: String, build: ActBuilderContext.() ->
|
|||
|
||||
object : StepDataBuilderContext {
|
||||
override var trigger: StepCue
|
||||
get() = nullableTrigger ?: throw IllegalStateException("trigger was not set yet")
|
||||
set(value) {
|
||||
nullableTrigger = value
|
||||
}
|
||||
get() = cue
|
||||
set(value) {}
|
||||
|
||||
override val props = PropsBuilderMap(changedProps)
|
||||
|
||||
|
@ -113,9 +118,7 @@ private fun buildAct(actIndex: Int, name: String, build: ActBuilderContext.() ->
|
|||
}
|
||||
}.build()
|
||||
|
||||
@Suppress("KotlinConstantConditions")
|
||||
val trigger = nullableTrigger ?: throw IllegalStateException("No trigger was specified")
|
||||
val logger = KotlinLogging.logger("createAct / $name / #${steps.size + 1} ${trigger.format()}")
|
||||
val logger = KotlinLogging.logger("createAct / $name / #${steps.size + 1} ${cue.format()}")
|
||||
|
||||
val actorEntrancesNames = actorEntrances.map { it.main }
|
||||
val actorExitsNames = actorExits.map { it.main }
|
||||
|
@ -152,7 +155,7 @@ private fun buildAct(actIndex: Int, name: String, build: ActBuilderContext.() ->
|
|||
steps.add(
|
||||
Step(
|
||||
ShowPosition(actIndex, scenes.size, steps.size),
|
||||
trigger,
|
||||
cue,
|
||||
actorEntrances.toImmutableSet(),
|
||||
actorExits.toImmutableSet(),
|
||||
actorsOnStage.toImmutableList(),
|
||||
|
|
|
@ -141,7 +141,7 @@ fun CoroutineScope.startStepRunning(context: ShowContext) = launch {
|
|||
|
||||
val step = context.show.acts[lastPosition]
|
||||
lastStepJob?.cancelAndJoin()
|
||||
lastStepJob = launch(SupervisorJob(currentCoroutineContext().job)) {
|
||||
lastStepJob = launch(SupervisorJob(currentCoroutineContext().job), CoroutineStart.UNDISPATCHED) {
|
||||
val runContext = object : StepRunContext, CoroutineScope by this {}
|
||||
|
||||
step.runner?.let { runContext.it() }
|
||||
|
@ -170,6 +170,7 @@ private fun CoroutineScope.startWebsocketServer(context: ShowContext) = launch(D
|
|||
}
|
||||
|
||||
val showJson = Json.encodeToString(context.show)
|
||||
val indexHtmlContent = this::class.java.getResourceAsStream("/ui/index.html")!!.reader().use { it.readText() }
|
||||
|
||||
embeddedServer(CIO, port = 8000) {
|
||||
install(WebSockets) {
|
||||
|
@ -227,9 +228,13 @@ private fun CoroutineScope.startWebsocketServer(context: ShowContext) = launch(D
|
|||
}
|
||||
}
|
||||
|
||||
staticResources("/", "ui") {
|
||||
staticResources("/assets", "ui/assets") {
|
||||
enableAutoHeadResponse()
|
||||
}
|
||||
|
||||
get("/{...}") {
|
||||
call.respondText(indexHtmlContent, ContentType.Text.Html, HttpStatusCode.OK)
|
||||
}
|
||||
}
|
||||
}.start(wait = true)
|
||||
}
|
|
@ -5,8 +5,7 @@
|
|||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"dev": "vite --port 3000 --host",
|
||||
"build": "vite build",
|
||||
"start": "vite preview --port 3000 --host"
|
||||
"build": "vite build --emptyOutDir --outDir ../src/main/resources/ui"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/ph": "^1.1.5",
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/main.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.1",
|
||||
"@types/ws": "^8.5.3",
|
||||
"tsx": "^3.7.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"bufferutil": "^4.0.6",
|
||||
"utf-8-validate": "^5.0.9",
|
||||
"ws": "^8.8.0"
|
||||
}
|
||||
}
|
344
ui/server/pnpm-lock.yaml
generated
344
ui/server/pnpm-lock.yaml
generated
|
@ -1,344 +0,0 @@
|
|||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@types/node': ^18.0.1
|
||||
'@types/ws': ^8.5.3
|
||||
bufferutil: ^4.0.6
|
||||
tsx: ^3.7.1
|
||||
typescript: ^4.7.4
|
||||
utf-8-validate: ^5.0.9
|
||||
ws: ^8.8.0
|
||||
|
||||
dependencies:
|
||||
bufferutil: 4.0.6
|
||||
utf-8-validate: 5.0.9
|
||||
ws: 8.8.0_22kvxa7zeyivx4jp72v2w3pkvy
|
||||
|
||||
devDependencies:
|
||||
'@types/node': 18.0.1
|
||||
'@types/ws': 8.5.3
|
||||
tsx: 3.7.1
|
||||
typescript: 4.7.4
|
||||
|
||||
packages:
|
||||
|
||||
/@esbuild-kit/cjs-loader/2.3.0:
|
||||
resolution: {integrity: sha512-KInrVt8wlKLhWy7+y4a+E+0uBJoWgdx6Xupy+rrF4MFHA/dEt22ACvvChOZSyiqtQieYPtbPkVYSjbC7mOrFVw==}
|
||||
dependencies:
|
||||
'@esbuild-kit/core-utils': 2.0.2
|
||||
get-tsconfig: 4.1.0
|
||||
dev: true
|
||||
|
||||
/@esbuild-kit/core-utils/2.0.2:
|
||||
resolution: {integrity: sha512-clNYQUsqtc36pzW5EufMsahcbLG45EaW3YDyf0DlaS0eCMkDXpxIlHwPC0rndUwG6Ytk9sMSD5k1qHbwYEC/OQ==}
|
||||
dependencies:
|
||||
esbuild: 0.14.48
|
||||
source-map-support: 0.5.21
|
||||
dev: true
|
||||
|
||||
/@esbuild-kit/esm-loader/2.4.0:
|
||||
resolution: {integrity: sha512-zS720jXh06nfg5yAzm6oob4sWN9VTP2E1SonhFgEb6zCBswa4S8fOQ/4Bksz1flDgn56NPqoTTDn2XmWRyMG9Q==}
|
||||
dependencies:
|
||||
'@esbuild-kit/core-utils': 2.0.2
|
||||
get-tsconfig: 4.1.0
|
||||
dev: true
|
||||
|
||||
/@types/node/18.0.1:
|
||||
resolution: {integrity: sha512-CmR8+Tsy95hhwtZBKJBs0/FFq4XX7sDZHlGGf+0q+BRZfMbOTkzkj0AFAuTyXbObDIoanaBBW0+KEW+m3N16Wg==}
|
||||
dev: true
|
||||
|
||||
/@types/ws/8.5.3:
|
||||
resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==}
|
||||
dependencies:
|
||||
'@types/node': 18.0.1
|
||||
dev: true
|
||||
|
||||
/buffer-from/1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
dev: true
|
||||
|
||||
/bufferutil/4.0.6:
|
||||
resolution: {integrity: sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==}
|
||||
engines: {node: '>=6.14.2'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
node-gyp-build: 4.5.0
|
||||
dev: false
|
||||
|
||||
/esbuild-android-64/0.14.48:
|
||||
resolution: {integrity: sha512-3aMjboap/kqwCUpGWIjsk20TtxVoKck8/4Tu19rubh7t5Ra0Yrpg30Mt1QXXlipOazrEceGeWurXKeFJgkPOUg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-android-arm64/0.14.48:
|
||||
resolution: {integrity: sha512-vptI3K0wGALiDq+EvRuZotZrJqkYkN5282iAfcffjI5lmGG9G1ta/CIVauhY42MBXwEgDJkweiDcDMRLzBZC4g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-64/0.14.48:
|
||||
resolution: {integrity: sha512-gGQZa4+hab2Va/Zww94YbshLuWteyKGD3+EsVon8EWTWhnHFRm5N9NbALNbwi/7hQ/hM1Zm4FuHg+k6BLsl5UA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-arm64/0.14.48:
|
||||
resolution: {integrity: sha512-bFjnNEXjhZT+IZ8RvRGNJthLWNHV5JkCtuOFOnjvo5pC0sk2/QVk0Qc06g2PV3J0TcU6kaPC3RN9yy9w2PSLEA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-64/0.14.48:
|
||||
resolution: {integrity: sha512-1NOlwRxmOsnPcWOGTB10JKAkYSb2nue0oM1AfHWunW/mv3wERfJmnYlGzL3UAOIUXZqW8GeA2mv+QGwq7DToqA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-arm64/0.14.48:
|
||||
resolution: {integrity: sha512-gXqKdO8wabVcYtluAbikDH2jhXp+Klq5oCD5qbVyUG6tFiGhrC9oczKq3vIrrtwcxDQqK6+HDYK8Zrd4bCA9Gw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-32/0.14.48:
|
||||
resolution: {integrity: sha512-ghGyDfS289z/LReZQUuuKq9KlTiTspxL8SITBFQFAFRA/IkIvDpnZnCAKTCjGXAmUqroMQfKJXMxyjJA69c/nQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-64/0.14.48:
|
||||
resolution: {integrity: sha512-vni3p/gppLMVZLghI7oMqbOZdGmLbbKR23XFARKnszCIBpEMEDxOMNIKPmMItQrmH/iJrL1z8Jt2nynY0bE1ug==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm/0.14.48:
|
||||
resolution: {integrity: sha512-+VfSV7Akh1XUiDNXgqgY1cUP1i2vjI+BmlyXRfVz5AfV3jbpde8JTs5Q9sYgaoq5cWfuKfoZB/QkGOI+QcL1Tw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm64/0.14.48:
|
||||
resolution: {integrity: sha512-3CFsOlpoxlKPRevEHq8aAntgYGYkE1N9yRYAcPyng/p4Wyx0tPR5SBYsxLKcgPB9mR8chHEhtWYz6EZ+H199Zw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-mips64le/0.14.48:
|
||||
resolution: {integrity: sha512-cs0uOiRlPp6ymknDnjajCgvDMSsLw5mST2UXh+ZIrXTj2Ifyf2aAP3Iw4DiqgnyYLV2O/v/yWBJx+WfmKEpNLA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-ppc64le/0.14.48:
|
||||
resolution: {integrity: sha512-+2F0vJMkuI0Wie/wcSPDCqXvSFEELH7Jubxb7mpWrA/4NpT+/byjxDz0gG6R1WJoeDefcrMfpBx4GFNN1JQorQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-riscv64/0.14.48:
|
||||
resolution: {integrity: sha512-BmaK/GfEE+5F2/QDrIXteFGKnVHGxlnK9MjdVKMTfvtmudjY3k2t8NtlY4qemKSizc+QwyombGWTBDc76rxePA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-s390x/0.14.48:
|
||||
resolution: {integrity: sha512-tndw/0B9jiCL+KWKo0TSMaUm5UWBLsfCKVdbfMlb3d5LeV9WbijZ8Ordia8SAYv38VSJWOEt6eDCdOx8LqkC4g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-netbsd-64/0.14.48:
|
||||
resolution: {integrity: sha512-V9hgXfwf/T901Lr1wkOfoevtyNkrxmMcRHyticybBUHookznipMOHoF41Al68QBsqBxnITCEpjjd4yAos7z9Tw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-openbsd-64/0.14.48:
|
||||
resolution: {integrity: sha512-+IHf4JcbnnBl4T52egorXMatil/za0awqzg2Vy6FBgPcBpisDWT2sVz/tNdrK9kAqj+GZG/jZdrOkj7wsrNTKA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-sunos-64/0.14.48:
|
||||
resolution: {integrity: sha512-77m8bsr5wOpOWbGi9KSqDphcq6dFeJyun8TA+12JW/GAjyfTwVtOnN8DOt6DSPUfEV+ltVMNqtXUeTeMAxl5KA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-32/0.14.48:
|
||||
resolution: {integrity: sha512-EPgRuTPP8vK9maxpTGDe5lSoIBHGKO/AuxDncg5O3NkrPeLNdvvK8oywB0zGaAZXxYWfNNSHskvvDgmfVTguhg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-64/0.14.48:
|
||||
resolution: {integrity: sha512-YmpXjdT1q0b8ictSdGwH3M8VCoqPpK1/UArze3X199w6u8hUx3V8BhAi1WjbsfDYRBanVVtduAhh2sirImtAvA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-arm64/0.14.48:
|
||||
resolution: {integrity: sha512-HHaOMCsCXp0rz5BT2crTka6MPWVno121NKApsGs/OIW5QC0ggC69YMGs1aJct9/9FSUF4A1xNE/cLvgB5svR4g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild/0.14.48:
|
||||
resolution: {integrity: sha512-w6N1Yn5MtqK2U1/WZTX9ZqUVb8IOLZkZ5AdHkT6x3cHDMVsYWC7WPdiLmx19w3i4Rwzy5LqsEMtVihG3e4rFzA==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
esbuild-android-64: 0.14.48
|
||||
esbuild-android-arm64: 0.14.48
|
||||
esbuild-darwin-64: 0.14.48
|
||||
esbuild-darwin-arm64: 0.14.48
|
||||
esbuild-freebsd-64: 0.14.48
|
||||
esbuild-freebsd-arm64: 0.14.48
|
||||
esbuild-linux-32: 0.14.48
|
||||
esbuild-linux-64: 0.14.48
|
||||
esbuild-linux-arm: 0.14.48
|
||||
esbuild-linux-arm64: 0.14.48
|
||||
esbuild-linux-mips64le: 0.14.48
|
||||
esbuild-linux-ppc64le: 0.14.48
|
||||
esbuild-linux-riscv64: 0.14.48
|
||||
esbuild-linux-s390x: 0.14.48
|
||||
esbuild-netbsd-64: 0.14.48
|
||||
esbuild-openbsd-64: 0.14.48
|
||||
esbuild-sunos-64: 0.14.48
|
||||
esbuild-windows-32: 0.14.48
|
||||
esbuild-windows-64: 0.14.48
|
||||
esbuild-windows-arm64: 0.14.48
|
||||
dev: true
|
||||
|
||||
/fsevents/2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/get-tsconfig/4.1.0:
|
||||
resolution: {integrity: sha512-bhshxJhpfmeQ8x4fAvDqJV2VfGp5TfHdLpmBpNZZhMoVyfIrOippBW4mayC3DT9Sxuhcyl56Efw61qL28hG4EQ==}
|
||||
dev: true
|
||||
|
||||
/node-gyp-build/4.5.0:
|
||||
resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/source-map-support/0.5.21:
|
||||
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
||||
dependencies:
|
||||
buffer-from: 1.1.2
|
||||
source-map: 0.6.1
|
||||
dev: true
|
||||
|
||||
/source-map/0.6.1:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/tsx/3.7.1:
|
||||
resolution: {integrity: sha512-dwl1GBdkwVQ9zRxTmETGi+ck8pewNm2QXh+HK6jHxdHmeCjfCL+Db3b4VX/dOMDSS2hle1j5LzQoo8OpVXu6XQ==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@esbuild-kit/cjs-loader': 2.3.0
|
||||
'@esbuild-kit/core-utils': 2.0.2
|
||||
'@esbuild-kit/esm-loader': 2.4.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/typescript/4.7.4:
|
||||
resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/utf-8-validate/5.0.9:
|
||||
resolution: {integrity: sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==}
|
||||
engines: {node: '>=6.14.2'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
node-gyp-build: 4.5.0
|
||||
dev: false
|
||||
|
||||
/ws/8.8.0_22kvxa7zeyivx4jp72v2w3pkvy:
|
||||
resolution: {integrity: sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
dependencies:
|
||||
bufferutil: 4.0.6
|
||||
utf-8-validate: 5.0.9
|
||||
dev: false
|
|
@ -1,46 +0,0 @@
|
|||
import { WebSocketServer } from "ws"
|
||||
|
||||
const server = new WebSocketServer({
|
||||
clientTracking: true,
|
||||
host: "0.0.0.0",
|
||||
port: 8000
|
||||
})
|
||||
|
||||
let state = {
|
||||
music: null,
|
||||
message: "",
|
||||
position: {
|
||||
scene: 0,
|
||||
step: 0
|
||||
}
|
||||
}
|
||||
|
||||
server.on("connection", (client, request) => {
|
||||
const address = request.connection.remoteAddress
|
||||
console.log(`Connected: ${address}`)
|
||||
client.send(JSON.stringify({
|
||||
state,
|
||||
timestamp: Date.now()
|
||||
}))
|
||||
|
||||
client.on("message", rawData => {
|
||||
state = JSON.parse(rawData.toString())
|
||||
|
||||
console.log("Update: ", state)
|
||||
|
||||
server.clients.forEach(c => {
|
||||
if (c !== client) {
|
||||
c.send(JSON.stringify({
|
||||
state,
|
||||
timestamp: Date.now()
|
||||
}))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
client.on("close", () => {
|
||||
console.log(`Disconnected: ${address}`)
|
||||
})
|
||||
})
|
||||
|
||||
console.log("Listening on ws://0.0.0.0:8000")
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="flex items-start space-x-2">
|
||||
<component :is="icon" class="text-4 mt-0.5 flex-shrink-0"/>
|
||||
<div class="text-4" :class="singleLine && 'truncate'">
|
||||
<div class="flex items-start space-x-2" :class="textClass ?? 'text-4'">
|
||||
<component :is="icon" class="mt-0.5 flex-shrink-0"/>
|
||||
<div :class="singleLine && 'truncate'">
|
||||
{{ text }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,6 +24,7 @@
|
|||
const props = defineProps<{
|
||||
step: Step,
|
||||
singleLine?: boolean
|
||||
textClass?: string
|
||||
}>()
|
||||
|
||||
const icon = computed(() => {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
v-for="(scene, sceneIndex) in scenes"
|
||||
:key="sceneIndex"
|
||||
>
|
||||
<div class="text-gray-400 pl-3">
|
||||
{{ scene.name }}
|
||||
<div class="text-gray-400 pl-3 text-5">
|
||||
Szene {{ scene.name }}
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<template v-for="step in scene.steps" :key="step.position">
|
||||
|
@ -22,7 +22,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { show } from "../state"
|
||||
import { Scene, show, ShowPosition, Step } from "../state"
|
||||
import { computed } from "vue"
|
||||
import MotionsListStep from "./MotionsListStep.vue"
|
||||
|
||||
|
@ -31,5 +31,41 @@
|
|||
scrollable?: boolean
|
||||
}>()
|
||||
|
||||
const scenes = computed(() => show.value.acts.flatMap(a => a.scenes))
|
||||
interface MotionStep extends Step {
|
||||
morePositions: ShowPosition[]
|
||||
}
|
||||
|
||||
interface MotionScene extends Scene {
|
||||
steps: MotionStep[]
|
||||
}
|
||||
|
||||
const scenes = computed(() => {
|
||||
const all = show.value.acts.flatMap(a => a.scenes)
|
||||
const result: MotionScene[] = []
|
||||
|
||||
for (const scene of all) {
|
||||
const steps: MotionStep[] = []
|
||||
let accStep: MotionStep | null = null
|
||||
|
||||
for (const step of scene.steps) {
|
||||
if (step.actorEntrances.length > 0 || step.actorExits.length > 0) {
|
||||
if (accStep !== null) steps.push(accStep)
|
||||
|
||||
accStep = {
|
||||
...step,
|
||||
morePositions: []
|
||||
}
|
||||
} else {
|
||||
if (accStep !== null) accStep.morePositions.push(step.position)
|
||||
}
|
||||
}
|
||||
|
||||
if (steps.length > 0) result.push({
|
||||
...scene,
|
||||
steps: steps
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div class="transition p-3" :class="isActive && 'bg-green-800'">
|
||||
<div class="flex space-x-2">
|
||||
<div class="flex-grow">
|
||||
<CueBox :step="step"/>
|
||||
<div class="py-2 pl-8 space-y-2 text-6">
|
||||
<CueBox text-class="text-7" :step="step"/>
|
||||
<div class="py-2 pl-8 space-y-2 text-7">
|
||||
<div class="flex flex-col space-y-1">
|
||||
<div
|
||||
v-for="motion in step.actorEntrances"
|
||||
|
@ -47,7 +47,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { parseStringWithDetails, START_STEP, state, Step } from "../state"
|
||||
import { parseStringWithDetails, ShowPosition, START_STEP, state, Step } from "../state"
|
||||
import CueBox from "./CueBox.vue"
|
||||
import CaretDoubleRightIcon from "virtual:icons/ph/caret-double-right"
|
||||
import CaretDoubleLeftIcon from "virtual:icons/ph/caret-double-left"
|
||||
|
@ -58,12 +58,14 @@
|
|||
|
||||
const props = defineProps<{
|
||||
step: Step,
|
||||
morePositions?: ShowPosition[]
|
||||
centerCurrent: boolean
|
||||
}>()
|
||||
|
||||
const position = toRef(state, "position")
|
||||
const element = useCurrentElement()
|
||||
const isActive = computed(() => isEqual(props.step.position, position.value))
|
||||
const allPositions = computed(() => [props.step.position, ...(props.morePositions ?? [])])
|
||||
const isActive = computed(() => allPositions.value.some(p => isEqual(p, position.value)))
|
||||
|
||||
watchEffect(() => {
|
||||
const p = props.step.position
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
:class="scene === current.scene ? 'bg-green-900' : ''"
|
||||
>
|
||||
<div class="pb-1 pt-4 px-4 text-4 font-bold">
|
||||
{{ scene.name }}
|
||||
Szene {{ scene.name }}
|
||||
</div>
|
||||
<div class="flex flex-col pb-2">
|
||||
<StepSelectionStep v-for="step in scene.steps" :key="step.position" :step="step"/>
|
||||
|
|
|
@ -4,10 +4,7 @@
|
|||
:class="isActive ? 'bg-green-700' : ''"
|
||||
>
|
||||
<CueBox :step="step"/>
|
||||
<button
|
||||
class="flex items-center text-4"
|
||||
@click="goToPosition(step.position)"
|
||||
>
|
||||
<button class="flex items-center text-4" @click="goToPosition(step.position)">
|
||||
<KeyReturnIcon/>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<template>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<h1 class="font-800 text-9 px-4 pt-10 pb-0">
|
||||
{{ current.scene.name }}
|
||||
</h1>
|
||||
<div class="flex flex-col space-y-4 p-4 pt-8 flex-grow h-full overflow-hidden">
|
||||
<div class="flex justify-end">
|
||||
<button class="px-5 py-3 bg-green-600 font-bold text-5" @click="goNext()">
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<h1 class="font-800 text-9 p-10 pb-0">
|
||||
{{ current.scene.name }}
|
||||
</h1>
|
||||
<div class="h-full flex space-x-4 p-10 pt-8 flex-grow overflow-hidden">
|
||||
<StepSelection class="w-1/2"/>
|
||||
<div class="w-1/2 flex flex-col space-y-4">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<h1 class="font-800 text-9 p-4 pb-0">
|
||||
{{ current.scene.name }}
|
||||
Szene {{ current.scene.name }}
|
||||
</h1>
|
||||
<div class="h-full flex space-x-4 p-4 pt-8 flex-grow overflow-hidden">
|
||||
<MotionsList center-current class="w-3/7"/>
|
||||
|
@ -14,14 +14,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import MusicProgressBar from "../../components/MusicProgressBar.vue"
|
||||
import MessageBox from "../../components/MessageEdit.vue"
|
||||
import ActorsOnStageBox from "../../components/ActorsOnStageBox.vue"
|
||||
import { current } from "../../state"
|
||||
import MotionsList from "../../components/MotionsList.vue"
|
||||
import StageTopDownView from "../../components/StageTopDownView.vue"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<h1 class="font-800 text-9 p-4 pb-0">
|
||||
{{ current.scene.name }}
|
||||
Szene {{ current.scene.name }}
|
||||
</h1>
|
||||
<div class="h-full flex space-x-4 p-4 pt-8 flex-grow overflow-hidden">
|
||||
<MotionsList scrollable center-current class="w-3/7"/>
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<h1 class="font-800 text-9 p-4 pb-0">
|
||||
{{ current.scene.name }}
|
||||
</h1>
|
||||
<div class="h-full flex space-x-4 p-4 pt-8 flex-grow overflow-hidden">
|
||||
<MotionsList center-current class="w-3/7" scrollable/>
|
||||
<div class="w-4/7 flex flex-col space-y-4">
|
||||
<StageTopDownView class="h-full"/>
|
||||
<MessageEdit class="h-30"/>
|
||||
</div>
|
||||
</div>
|
||||
<MusicProgressBar class="h-10"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import MusicProgressBar from "../components/MusicProgressBar.vue"
|
||||
import MessageBox from "../components/MessageEdit.vue"
|
||||
import ActorsOnStageBox from "../components/ActorsOnStageBox.vue"
|
||||
import { current } from "../state"
|
||||
import MotionsList from "../components/MotionsList.vue"
|
||||
import StageTopDownView from "../components/StageTopDownView.vue"
|
||||
import MessageDisplay from "../components/MessageDisplay.vue"
|
||||
import MessageEdit from "../components/MessageEdit.vue"
|
||||
|
||||
export default {
|
||||
name: "ReinPage",
|
||||
components: { MessageEdit, MessageDisplay, StageTopDownView, MotionsList, ActorsOnStageBox, MessageBox, MusicProgressBar },
|
||||
setup() {
|
||||
return {
|
||||
current: current
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -9,7 +9,7 @@ export default defineConfig({
|
|||
splitVendorChunkPlugin(),
|
||||
vuePlugin(),
|
||||
pagesPlugin({
|
||||
syncIndex: false
|
||||
importMode: "sync"
|
||||
}),
|
||||
windicssPlugin(),
|
||||
iconsPlugin()
|
||||
|
@ -21,5 +21,8 @@ export default defineConfig({
|
|||
ws: true
|
||||
}
|
||||
}
|
||||
},
|
||||
build: {
|
||||
reportCompressedSize: false
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue