UNPKG

senangwebs-story

Version:

Lightweight, dependency-free JavaScript library for creating interactive, visual novel-style story experiences.

408 lines (373 loc) โ€ข 19.9 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SenangWebs Story - JSON Example</title> <link rel="stylesheet" href="../dist/sws.css"> <style> body { margin: 0; padding: 20px; min-height: 100vh; } .container { max-width: 1000px; margin: 0 auto; background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 20px 40px rgba(0,0,0,0.1); } .header { background: linear-gradient(45deg, #ff6b6b, #ff8e8e); color: white; padding: 10px; text-align: center; } .controls { padding: 20px; background: #f8f9fa; border-bottom: 1px solid #e9ecef; text-align: center; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; } .controls button { padding: 10px 20px; border: none; border-radius: 4px; background: #007bff; color: white; cursor: pointer; font-size: 1em; } .controls button:hover { background: #0056b3; } .controls button:disabled { background: #6c757d; cursor: not-allowed; } #loading { text-align: center; padding: 40px; color: #6c757d; } </style> </head> <body> <div class="container"> <div class="header"> <p>A SenangWebs Story Example - JSON/Programmatic Approach</p> </div> <div class="controls"> <button onclick="loadStory1()">Load Story: The First Contact</button> <button onclick="loadStory2()">Load Story: The Ancient Civilization</button> <button onclick="loadDialogSpeedDemo()">Load Dialog Speed Demo</button> <button onclick="clearStory()">Clear Story</button> </div> <!-- This will be our story container --> <div id="story-container" style="height: 600px;"> <div id="loading"> <h3>๐Ÿ‘† Choose a story to load using the buttons above</h3> <p>This example demonstrates how to initialize SenangWebs Story using JSON data and JavaScript.</p> </div> </div> </div> <!-- Include the SenangWebs Story Library --> <script src="../dist/sws.js"></script> <script> let currentStoryInstance = null; // Story 1: The First Contact const story1Data = { "id": "first_contact", "scenes": [ { "sceneStart": "console.log('๐Ÿ›ธ First Contact scenario begins!'); playSound('space-ambience')", "background": "https://images.unsplash.com/photo-1446776653964-20c1d3a81b06?w=800&h=600&fit=crop", "subjects": [ { "id": "captain", "name": "Captain Sarah Chen", "src": "./images/captain_sarah_1.webp" }, { "id": "engineer", "name": "Engineer Marcus", "src": "./images/engineer.webp" } ], "dialogs": [ { "subjectId": "captain", "text": "Commander's log, stardate 2387.5. We've detected an unknown signal from the Proxima system. This could be the first evidence of extraterrestrial intelligence.", "dialogStart": "console.log('๐Ÿ“ Captain begins her log entry')" }, { "subjectId": "engineer", "text": "Captain, I'm reading massive energy signatures from the third planet. The pattern... it's too organized to be natural.", "dialogStart": "highlightControls('energy-readings')" }, { "subjectId": "captain", "text": "Set course for Proxima Centauri III. Red alert! All hands to stations. We're about to make history." }, { "text": "The ship's engines roar to life as it changes course toward the mysterious planet, leaving a trail of light across the cosmos." } ] }, { "sceneStart": "console.log('๐ŸŒ Approaching the alien planet!'); flashScreen('red')", "background": "https://images.unsplash.com/photo-1614730321146-b6fa6a46bcb4?w=800&h=600&fit=crop", "subjects": [ { "id": "captain", "name": "Captain Sarah Chen", "src": "./images/captain_sarah_2.webp" }, { "id": "alien", "name": "Zyx'thara", "src": "./images/alien.webp" } ], "dialogs": [ { "subjectId": "captain", "text": "My God... the cities are beautiful! Crystalline structures reaching into the clouds. How long have they been waiting for us?" }, { "text": "Suddenly, a shimmering portal opens on the bridge. A being of pure energy materializes before the crew!" }, { "subjectId": "alien", "text": "Greetings, travelers from the third planet of Sol. I am Zyx'thara. We have observed your species' growth and await peaceful contact.", "dialogStart": "console.log('๐Ÿ‘ฝ First alien contact established!')" }, { "subjectId": "captain", "text": "This is incredible! I'm Captain Sarah Chen of the Earth vessel Endeavor. We come in peace, seeking knowledge and friendship." }, { "subjectId": "alien", "text": "Your vessel may land in our capital. We have much to discuss about the future of both our species." } ] } ] }; // Story 2: The Ancient Civilization const story2Data = { "id": "ancient_civilization", "scenes": [ { "sceneStart": "console.log('๐Ÿ›๏ธ Discovering ancient ruins!'); changeBackgroundMusic('mystery')", "background": "https://images.unsplash.com/photo-1667070796157-d75b35434fa5?w=800&h=600&fit=crop", "subjects": [ { "id": "archaeologist", "name": "Dr. Elena Rodriguez", "src": "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=200&h=300&fit=crop&crop=face" }, { "id": "assistant", "name": "Jake Williams", "src": "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=200&h=300&fit=crop&crop=face" } ], "dialogs": [ { "subjectId": "archaeologist", "text": "Jake, look at these hieroglyphs! They're unlike anything we've seen before. The craftsmanship suggests a civilization far more advanced than we initially thought." }, { "subjectId": "assistant", "text": "Dr. Rodriguez, this inscription... it seems to be some kind of warning. And look here - these symbols appear to be coordinates!" }, { "subjectId": "archaeologist", "text": "Coordinates to what? Wait... hand me that translation device. If I'm reading this correctly, they're pointing to a hidden chamber beneath the temple." }, { "text": "The ground begins to rumble as ancient mechanisms activate. A secret passage opens in the temple floor, revealing stairs descending into darkness." } ] }, { "sceneStart": "console.log('๐Ÿ” Entering the hidden chamber!'); playSound('cave-echo')", "background": "https://images.unsplash.com/photo-1738226699315-d7323358d42b?w=800&h=600&fit=crop", "subjects": [ { "id": "archaeologist", "name": "Dr. Elena Rodriguez", "src": "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=200&h=300&fit=crop&crop=face" }, { "id": "guardian", "name": "Ancient Guardian", "src": "https://images.unsplash.com/photo-1551601651-2a8555f1a136?w=200&h=300&fit=crop" } ], "dialogs": [ { "subjectId": "archaeologist", "text": "The chamber is filled with artifacts that shouldn't exist! This technology is thousands of years ahead of its time." }, { "text": "Suddenly, a holographic figure materializes from one of the ancient devices - a guardian left behind by the lost civilization!" }, { "subjectId": "guardian", "text": "Seekers of knowledge, you have found the Archive of Eternity. I am the last guardian of my people's wisdom.", "dialogStart": "console.log('๐Ÿค– Ancient AI guardian activated!')" }, { "subjectId": "archaeologist", "text": "Incredible! You're an artificial intelligence from the ancient world. What happened to your civilization?" }, { "subjectId": "guardian", "text": "We transcended physical form eons ago, but left this archive for future seekers. The knowledge here will advance your species by millennia." }, { "text": "The guardian extends a glowing data crystal, containing the accumulated wisdom of an entire civilization. History will never be the same." } ] } ] }; // Story 3: Dialog Speed Demo const dialogSpeedDemoData = { "id": "dialog_speed_demo", "dialogSpeed": 15, // Fast dialog speed for demonstration "scenes": [ { "sceneStart": "console.log('โšก Dialog Speed Demo begins!'); playSound('demo-start')", "background": "https://images.unsplash.com/photo-1419242902214-272b3f66ee7a?w=800&h=600&fit=crop", "subjects": [ { "id": "developer", "name": "SWS Developer", "src": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200&h=300&fit=crop&crop=face" }, { "id": "user", "name": "Story User", "src": "https://images.unsplash.com/photo-1637249805971-59d7b9319df3?w=200&h=300&fit=crop&crop=face" } ], "dialogs": [ { "subjectId": "developer", "text": "Welcome to the Dialog Speed Demo! This story is configured with a fast dialog speed of 15ms per character. Notice how quickly the text appears!", "dialogStart": "console.log('๐ŸŽฏ Demonstrating fast dialog speed')" }, { "subjectId": "user", "text": "Wow, that was really fast! Now try clicking Next while this dialog is still typing to test the new behavior - it should complete the current dialog instead of skipping." }, { "subjectId": "developer", "text": "Perfect! That's the new feature in action. When a dialog is still animating and you click Next, it completes the current dialog first, ensuring you don't miss any content." }, { "subjectId": "user", "text": "This is so much better for user experience! No more accidentally skipping dialogs while they're still typing. The fast speed of 15ms makes testing really easy too." }, { "text": "The dialog speed can be set globally in JSON config using 'dialogSpeed' property, or per-story using the 'data-sws-dialog-speed' HTML attribute. Both approaches work seamlessly!" } ] }, { "sceneStart": "console.log('๐ŸŒ Switching to slow speed demo!'); changeBackgroundMusic('slow-demo')", "background": "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop", "subjects": [ { "id": "developer", "name": "SWS Developer", "src": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200&h=300&fit=crop&crop=face" } ], "dialogs": [ { "subjectId": "developer", "text": "Now let's imagine this scene had a much slower dialog speed - like 100ms per character. You'd have plenty of time to test the Next button behavior!" }, { "subjectId": "developer", "text": "The beauty of this feature is that it maintains backward compatibility. Existing stories without dialog speed settings continue to use the default 50ms timing." }, { "text": "Whether you prefer fast-paced storytelling or slower, more deliberate pacing, SenangWebs Story now gives you complete control over the dialog animation speed!" } ] } ] }; function loadStory1() { clearStory(); console.log('๐ŸŽฌ Loading Story 1: The First Contact'); const container = document.getElementById('story-container'); container.innerHTML = '<div id="story-content"></div>'; const storyElement = document.getElementById('story-content'); currentStoryInstance = new SWS(storyElement, story1Data); console.log('โœ… Story 1 loaded successfully!'); } function loadStory2() { clearStory(); console.log('๐ŸŽฌ Loading Story 2: The Ancient Civilization'); const container = document.getElementById('story-container'); container.innerHTML = '<div id="story-content"></div>'; const storyElement = document.getElementById('story-content'); currentStoryInstance = new SWS(storyElement, story2Data); console.log('โœ… Story 2 loaded successfully!'); } function loadDialogSpeedDemo() { clearStory(); console.log('โšก Loading Dialog Speed Demo'); const container = document.getElementById('story-container'); container.innerHTML = '<div id="story-content"></div>'; const storyElement = document.getElementById('story-content'); currentStoryInstance = new SWS(storyElement, dialogSpeedDemoData); console.log('โœ… Dialog Speed Demo loaded successfully!'); console.log('๐ŸŽฏ Dialog speed set to 15ms - try clicking Next while dialogs are typing!'); } function clearStory() { console.log('๐Ÿงน Clearing current story...'); currentStoryInstance = null; document.getElementById('story-container').innerHTML = ` <div id="loading"> <h3>Story cleared!</h3> <p>Choose another story to load using the buttons above.</p> </div> `; } // Helper functions that could be called by story callbacks function playSound(soundName) { console.log(`๐Ÿ”Š Playing sound: ${soundName}`); // In a real implementation, you would play actual sound files } function changeBackgroundMusic(musicName) { console.log(`๐ŸŽต Changing background music to: ${musicName}`); // In a real implementation, you would change background music } function highlightControls(controlName) { console.log(`โœจ Highlighting controls: ${controlName}`); // In a real implementation, you might highlight UI elements } function flashScreen(color) { console.log(`โšก Flashing screen with color: ${color}`); // In a real implementation, you might create a flash effect } // Initialize console.log('๐Ÿš€ SenangWebs Story JSON Example Loaded!'); console.log('This example demonstrates the programmatic JSON approach.'); console.log('Click the buttons above to dynamically load different stories.'); </script> </body> </html>