commit #23
This commit is contained in:
parent
379fc8eebb
commit
a9ff97627b
8 changed files with 167 additions and 41 deletions
|
@ -261,7 +261,7 @@ fun ShowBuilderContext.fourthAct() = act("Vierter Akt") {
|
|||
+"Adrian / von links"
|
||||
}
|
||||
|
||||
leftSpotTarget = "Kai & Adrian (rechtzeitig positionieren!)"
|
||||
leftSpotTarget = "Kai & Adrian"
|
||||
|
||||
onRun {
|
||||
Washs.left.colorWheelMode.static(CoemarProWash.ColorWheelMode.Rotate(5.percent, true))
|
||||
|
|
|
@ -62,7 +62,7 @@ fun ShowBuilderContext.secondAct() = act("Zweiter Akt") {
|
|||
+"Astronaut / liegt in der Mitte der Bühne"
|
||||
}
|
||||
|
||||
rightSpotTarget = "Paula (rechtzeitig positionieren!)"
|
||||
rightSpotTarget = "Paula"
|
||||
|
||||
onRun {
|
||||
FrontLights.center.forEach { it.brightness.off() }
|
||||
|
|
|
@ -86,8 +86,8 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.()
|
|||
val actorsOnStage = mutableListOf<String>()
|
||||
val props = PropPosition.values().associateWith<PropPosition, StringWithDetails?> { null }.toMutableMap()
|
||||
|
||||
var leftSpotTarget: String?
|
||||
var rightSpotTarget: String?
|
||||
var leftSpotTarget_: String? = null
|
||||
var rightSpotTarget_: String? = null
|
||||
var curtainState_ = CurtainState.CLOSED
|
||||
|
||||
object : ActBuilderContext {
|
||||
|
@ -107,10 +107,21 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.()
|
|||
val actorExits = mutableSetOf<StringWithDetails>()
|
||||
var runner: StepRunner? = null
|
||||
|
||||
val builderContext = object : StepDataBuilderContext {
|
||||
object : StepDataBuilderContext {
|
||||
override val props = PropsBuilderMap(changedProps)
|
||||
override var rightSpotTarget: String? = null
|
||||
override var leftSpotTarget: String? = null
|
||||
|
||||
override var rightSpotTarget: String?
|
||||
get() = rightSpotTarget_
|
||||
set(value) {
|
||||
rightSpotTarget_ = value
|
||||
}
|
||||
|
||||
override var leftSpotTarget: String?
|
||||
get() = leftSpotTarget_
|
||||
set(value) {
|
||||
leftSpotTarget_ = value
|
||||
}
|
||||
|
||||
override var curtainState: CurtainState
|
||||
get() = curtainState_
|
||||
set(value) {
|
||||
|
@ -124,11 +135,7 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.()
|
|||
override fun onRun(block: StepRunner) {
|
||||
runner = block
|
||||
}
|
||||
}
|
||||
|
||||
builderContext.also(build)
|
||||
leftSpotTarget = builderContext.leftSpotTarget
|
||||
rightSpotTarget = builderContext.rightSpotTarget
|
||||
}.build()
|
||||
|
||||
val logger = KotlinLogging.logger("createAct / $actName / $sceneName / #${steps.size + 1} ${cue.format()}")
|
||||
|
||||
|
@ -173,8 +180,8 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.()
|
|||
actorsOnStage.toImmutableList(),
|
||||
props.toImmutableMap(),
|
||||
changedProps.isNotEmpty(),
|
||||
leftSpotTarget,
|
||||
rightSpotTarget,
|
||||
leftSpotTarget_,
|
||||
rightSpotTarget_,
|
||||
curtainState_,
|
||||
runner
|
||||
)
|
||||
|
|
43
ui/src/components/ChangeBlinkingBox.vue
Normal file
43
ui/src/components/ChangeBlinkingBox.vue
Normal file
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center py-4"
|
||||
:class="$style.root"
|
||||
:data-blinking="isBlinking"
|
||||
>
|
||||
<slot/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
.root[data-blinking="true"] {
|
||||
animation: alternate infinite 1000ms ease-in-out pulse;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
from {
|
||||
@apply bg-red-900;
|
||||
}
|
||||
|
||||
to {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRef, watch } from "vue"
|
||||
import { autoResetRef } from "@vueuse/core"
|
||||
import { computed } from "vue"
|
||||
|
||||
const props = defineProps<{
|
||||
value: unknown
|
||||
blinkSeconds: number
|
||||
}>()
|
||||
|
||||
const value = toRef(props, "value")
|
||||
const isBlinking = autoResetRef(false, computed(() => props.blinkSeconds * 1000))
|
||||
|
||||
watch(value, () => {
|
||||
isBlinking.value = true
|
||||
})
|
||||
</script>
|
|
@ -1,9 +1,5 @@
|
|||
<template>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center py-4"
|
||||
:class="$style.box"
|
||||
:data-blinking="isBlinking"
|
||||
>
|
||||
<ChangeBlinkingBox :blink-seconds="20" :value="prop">
|
||||
<div class="text-s1 tracking-wide text-gray-500">
|
||||
{{ positionName }}
|
||||
</div>
|
||||
|
@ -21,27 +17,9 @@
|
|||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</ChangeBlinkingBox>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
.box {
|
||||
&[data-blinking="true"] {
|
||||
animation: alternate infinite 1000ms ease-in-out pulse;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
from {
|
||||
@apply bg-red-900;
|
||||
}
|
||||
|
||||
to {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
|
@ -58,6 +36,7 @@
|
|||
import { toRef, watch } from "vue"
|
||||
import { autoResetRef } from "@vueuse/core"
|
||||
import { parseStringWithDetails } from "../state"
|
||||
import ChangeBlinkingBox from "./ChangeBlinkingBox.vue"
|
||||
|
||||
const props = defineProps<{
|
||||
prop: string | null
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
<StepSelection class="w-1/2"/>
|
||||
<div class="w-1/2 flex flex-col space-y-4">
|
||||
<MessageEdit class="h-1/2"/>
|
||||
<ActorsOnStageBox class="h-1/2"/>
|
||||
<ActorsOnStageBox class="flex-grow"/>
|
||||
<FogControl/>
|
||||
</div>
|
||||
</div>
|
||||
<MusicProgressBar class="h-10"/>
|
||||
|
@ -22,6 +23,7 @@
|
|||
import ActorsOnStageBox from "../components/ActorsOnStageBox.vue"
|
||||
import { goToPosition } from "../syncing"
|
||||
import { current, getNextValidPosition, getPreviousValidPosition, state } from "../state"
|
||||
import FogControl from "../components/FogControl.vue"
|
||||
|
||||
onKeyStroke("ArrowRight", () => {
|
||||
const position = getNextValidPosition(state.position)
|
||||
|
|
77
ui/src/pages/spot.vue
Normal file
77
ui/src/pages/spot.vue
Normal file
|
@ -0,0 +1,77 @@
|
|||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<h1 class="font-800 text-9 p-4 pb-0">
|
||||
{{ current.act === null ? "" : `${current.act.name} — `}}{{ current.scene.name }}
|
||||
</h1>
|
||||
<div class="h-full flex flex-col space-y-10 p-10 text-10">
|
||||
<div class="flex gap-5 items-center h-18">
|
||||
<div>
|
||||
Aktuelles Ziel:
|
||||
</div>
|
||||
<ChangeBlinkingBox class="px-8 h-full min-w-50" :value="currentTarget" :blink-seconds="10">
|
||||
{{ currentTarget ?? "Niemand" }}
|
||||
</ChangeBlinkingBox>
|
||||
</div>
|
||||
<div v-if="nextStepWithChange !== null" class="h-full flex flex-col space-y-2 text-7">
|
||||
<div class="flex gap-5 items-center">
|
||||
<div>Nächstes Ziel:</div>
|
||||
<div>{{ nextStepWithChange.target }}</div>
|
||||
</div>
|
||||
<div>
|
||||
{{ nextStepWithChange.delta === 0
|
||||
? "in dieser Szene (rechtzeitig positionieren!)"
|
||||
: nextStepWithChange.delta === 1
|
||||
? "in der nächsten Szene"
|
||||
: `in ${nextStepWithChange.delta} Szenen`
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MusicProgressBar class="h-10"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router"
|
||||
import { computed } from "vue"
|
||||
import { current, getNextValidPosition, getSceneIndex, getStep, ShowPosition, START_STEP } from "../state"
|
||||
import ChangeBlinkingBox from "../components/ChangeBlinkingBox.vue"
|
||||
import MusicProgressBar from "../components/MusicProgressBar.vue"
|
||||
|
||||
const route = useRoute()
|
||||
const isLeft = computed(() => route.query.side === "left")
|
||||
const targetProperty = computed<"leftSpotTarget" | "rightSpotTarget">(() => isLeft.value ? "leftSpotTarget" : "rightSpotTarget")
|
||||
const currentTarget = computed(() => current.step[targetProperty.value])
|
||||
|
||||
interface StepWithChange {
|
||||
delta: number
|
||||
position: ShowPosition
|
||||
target: string
|
||||
}
|
||||
|
||||
const nextStepWithChange = computed<StepWithChange | null>(() => {
|
||||
let position: ShowPosition | null = getNextValidPosition(current.step.position)
|
||||
let lastTarget: string | null = currentTarget.value
|
||||
|
||||
while(position !== null) {
|
||||
const step = getStep(position)
|
||||
|
||||
if (step[targetProperty.value] !== null && step[targetProperty.value] !== lastTarget) {
|
||||
return {
|
||||
position: step.position,
|
||||
delta: getSceneIndex(step.position) - current.sceneIndex,
|
||||
target: step[targetProperty.value]!
|
||||
}
|
||||
}
|
||||
|
||||
lastTarget = step[targetProperty.value]
|
||||
position = getNextValidPosition(position)
|
||||
}
|
||||
|
||||
return null
|
||||
})
|
||||
</script>
|
|
@ -19,6 +19,8 @@ export interface Step {
|
|||
actorsOnStage: string[]
|
||||
props: PropMap
|
||||
hasChangedProps: boolean
|
||||
leftSpotTarget: string | null
|
||||
rightSpotTarget: string | null
|
||||
}
|
||||
|
||||
export type StepCue = {
|
||||
|
@ -95,7 +97,9 @@ export const START_STEP: Step = {
|
|||
},
|
||||
hasChangedProps: false,
|
||||
actorEntrances: [],
|
||||
actorExits: []
|
||||
actorExits: [],
|
||||
leftSpotTarget: null,
|
||||
rightSpotTarget: null
|
||||
}
|
||||
|
||||
const START_SCENE: Scene = {
|
||||
|
@ -129,6 +133,16 @@ export function getAct(position: ShowPosition) {
|
|||
return show.value.acts[position.act]
|
||||
}
|
||||
|
||||
export function getSceneIndex(position: ShowPosition) {
|
||||
let index = position.scene
|
||||
|
||||
for (let actIndex = 0; actIndex < position.act; actIndex++) {
|
||||
index += show.value.acts[actIndex]!.scenes.length
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
export function getActiveMusicAt(position: ShowPosition): ShowMusic | null {
|
||||
let activeMusic: ShowMusic | null = null
|
||||
|
||||
|
@ -162,13 +176,17 @@ export function getActiveMusicAt(position: ShowPosition): ShowMusic | null {
|
|||
export const current = reactiveComputed<{
|
||||
act: Act | null
|
||||
scene: Scene
|
||||
sceneIndex: number
|
||||
step: Step
|
||||
activeMusic: ShowMusic | null
|
||||
allScenes: Scene[]
|
||||
}>(() => ({
|
||||
act: getAct(state.position),
|
||||
scene: getScene(state.position),
|
||||
sceneIndex: getSceneIndex(state.position),
|
||||
step: getStep(state.position),
|
||||
activeMusic: state.activeMusic
|
||||
activeMusic: state.activeMusic,
|
||||
allScenes: show.value.acts.flatMap(act => act.scenes)
|
||||
}))
|
||||
|
||||
export function parseStringWithDetails(string: string) {
|
||||
|
|
Loading…
Add table
Reference in a new issue