Added choices at end of scene
This commit is contained in:
parent
212a43ee6e
commit
1ad2fcd9cb
144
src/vn.rs
144
src/vn.rs
@ -26,18 +26,24 @@ fn render_scene(settings: &PlayerSettings, name: &str) -> Markup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn navigation_controls(total_sections: usize) -> Markup {
|
fn navigation_controls(total_scenes: usize) -> Markup {
|
||||||
html! {
|
html! {
|
||||||
div class="nav-controls" {
|
div class="nav-controls" {
|
||||||
button class="nav-button" onclick="prev()" { "←" }
|
button class="nav-button" onclick="prev()" { "←" }
|
||||||
span id="section-counter" { "1/" (total_sections) }
|
span id="section-counter" { "1/" (total_scenes) }
|
||||||
button class="nav-button" onclick="next()" { "→" }
|
button class="nav-button" onclick="next()" { "→" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_html(scenes: Vec<Markup>, sections: Vec<Markup>) -> Markup {
|
fn generate_html(mut scenes: Vec<Markup>, sections: Vec<Markup>, choices: Markup) -> Markup {
|
||||||
let total_sections = sections.len();
|
scenes.push(html! {
|
||||||
|
div class="choices-section" {
|
||||||
|
(choices)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let total_scenes = scenes.len();
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
div id="story-container" {
|
div id="story-container" {
|
||||||
@ -65,9 +71,9 @@ fn generate_html(scenes: Vec<Markup>, sections: Vec<Markup>) -> Markup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(navigation_controls(total_sections))
|
(navigation_controls(total_scenes))
|
||||||
(global_styles())
|
(global_styles())
|
||||||
(interactive_script(total_sections))
|
(interactive_script(total_scenes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,36 +235,109 @@ fn global_styles() -> Markup {
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.choices-section {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 3;
|
||||||
|
background: rgba(0, 0, 0, 0.85);
|
||||||
|
padding: 2rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-box:hover {
|
||||||
|
transform: translateX(-50%) translateY(-0.5vh);
|
||||||
|
box-shadow: 0 0.6vw 0.8vw rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.choices-section input[type='submit'] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 1rem;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-box {
|
||||||
|
width: 90%;
|
||||||
|
min-width: 85%;
|
||||||
|
border: 0.2vw solid #3a3a3a;
|
||||||
|
border-radius: 1vw;
|
||||||
|
padding: 2vw;
|
||||||
|
margin: 1vh auto;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
box-shadow: 0 0.4vw 0.6vw rgba(0, 0, 0, 0.1);
|
||||||
|
position: relative;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-button {
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 1.5vh 2vw;
|
||||||
|
font-size: 1.6vw;
|
||||||
|
line-height: 1.4;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #333;
|
||||||
|
text-align: left;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.choices-section {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-box {
|
||||||
|
width: 95%;
|
||||||
|
padding: 3vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-button {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
"))
|
"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interactive_script(total_sections: usize) -> Markup {
|
fn interactive_script(total_scenes: usize) -> Markup {
|
||||||
html! {
|
html! {
|
||||||
script {
|
script {
|
||||||
(maud::PreEscaped(format!(r"
|
(maud::PreEscaped(format!(r"
|
||||||
let currentSection = 0;
|
let currentScene = 0;
|
||||||
const totalSections = {total_sections};
|
const totalScenes = {total_scenes};
|
||||||
|
|
||||||
function updateSection() {{
|
function updateSection() {{
|
||||||
document.querySelectorAll('.story-section').forEach((el, index) => {{
|
document.querySelectorAll('.story-section').forEach((el, index) => {{
|
||||||
el.style.display = index === currentSection ? 'block' : 'none';
|
el.style.display = index === currentScene ? 'block' : 'none';
|
||||||
}});
|
}});
|
||||||
document.querySelectorAll('.scene-section').forEach((el, index) => {{
|
document.querySelectorAll('.scene-section').forEach((el, index) => {{
|
||||||
el.style.display = index === currentSection ? 'block' : 'none';
|
el.style.display = index === currentScene ? 'block' : 'none';
|
||||||
}});
|
}});
|
||||||
document.getElementById('section-counter').textContent =
|
document.getElementById('section-counter').textContent =
|
||||||
`${{currentSection + 1}}/${{totalSections}}`;
|
`${{currentScene + 1}}/${{totalScenes}}`;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
function prev() {{
|
function prev() {{
|
||||||
if (currentSection > 0) currentSection--;
|
if (currentScene > 0) currentScene--;
|
||||||
updateSection();
|
updateSection();
|
||||||
}}
|
}}
|
||||||
|
|
||||||
function next() {{
|
function next() {{
|
||||||
if (currentSection < totalSections - 1) currentSection++;
|
if (currentScene < totalScenes - 1) currentScene++;
|
||||||
updateSection();
|
updateSection();
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -300,30 +379,31 @@ pub fn render_novel(
|
|||||||
let dialogs = parse_map(pk_path, &mut settings_context)?;
|
let dialogs = parse_map(pk_path, &mut settings_context)?;
|
||||||
let (scenes, sections) = process_dialog(&dialogs[choice], &mut player_settings, start_level);
|
let (scenes, sections) = process_dialog(&dialogs[choice], &mut player_settings, start_level);
|
||||||
|
|
||||||
let html = generate_html(scenes, sections);
|
let mut choices_html = html! {};
|
||||||
let _ = write!(stream, "{}", html.into_string());
|
|
||||||
|
|
||||||
if let Some(_named_multilinear_info) = named_multilinear_info {
|
if let Some(_named_multilinear_info) = named_multilinear_info {
|
||||||
for (i, dialog_sequence) in dialogs.iter().enumerate() {
|
choices_html = html! {
|
||||||
if let Some(block) = dialog_sequence
|
div class="choices-section" {
|
||||||
.blocks
|
@for (i, dialog_sequence) in dialogs.iter().enumerate() {
|
||||||
.iter()
|
@if let Some(block) = dialog_sequence.blocks.first() {
|
||||||
.find(|block| !block.lines.is_empty())
|
div class="choice-box" {
|
||||||
{
|
form method="POST" {
|
||||||
let line_text = &block.lines.first().unwrap().text;
|
input type="hidden" name="progress" value=(progress);
|
||||||
|
input type="hidden" name="choice" value=(i);
|
||||||
let html = html! {
|
button type="submit" class="choice-button" {
|
||||||
form method="POST" {
|
(block.lines[0].text)
|
||||||
input type="hidden" name="progress" value=(progress);
|
}
|
||||||
input type="hidden" name="choice" value=(i);
|
}
|
||||||
input type="submit" value=(line_text);
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
let _ = write!(stream, "{}", html.into_string());
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let html = generate_html(scenes, sections, choices_html);
|
||||||
|
let _ = write!(stream, "{}", html.into_string());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user