JavaScript
20 TopicsAlways on top
I just set myself the challenge of having elements that are "always on top". I've worked on a handful of courses in the past, that had an irregular shaped header graphic (sometimes with drop shadow), where it would have been great to be able to set some elements in the Master Template to appears always on top of other elements within the module. For those courses, I had to create a slice of the header (the irregular shaped part) and paste on each slide, where the header appeared over another element on the slide. I have had some success, and of course it is a JavaScript implementation. This is very much an ALPHA release. Here's the implementation if interested in having a play with it or extending it. I'm sure there will be some elements, that I haven't played with, that may need some extra logic in the JS. For each element you would like to appear always on top, add the string "{AOT}" in the "Alternative text" field. If the element is decorative, you can just add "{AOT}". This will be taken care of during processing (removed, and set to aria-hidden=true). If the element is non-decorative, for example an exit button, you would just add "{AOT}Exit" to the alternative text. This would also be process, and "{AOT}" removed and "Exit" retained in the ALT text. Add the following script to the "timeline starts" on the SLIDE MASTER. This ensures that the script will process on every slide. const init = () => { // inititial value for z-index let z = 999; // get all elements with data-acc-text attribute starting with "{AOT}" const elements = document.querySelectorAll('[data-acc-text^="{AOT}"]'); // loop through each element elements.forEach(element => { // get the modelId and accText from the element's dataset const { modelId, accText } = element.dataset; // get the root element with the same modelId const rootElement = document.querySelector(`[data-model-id="${modelId}"]`); // set the z-index of the root element (incrementing by 1 each time) rootElement.style.zIndex = z++; // get the alternative text by removing "{AOT}" from accText and trimming the result const alt = String(accText).replace('{AOT}', '').trim(); // get the alt element with the id "acc-${modelId}" const altElement = document.getElementById(`acc-${modelId}`); // set the alternative text to the element's dataset element.dataset.accText = alt; // re-write the inner text of the alt element altElement.innerText = alt; // if the alternative text is empty (decorative), set the aria-hidden attribute to true and the z-index to -1 if (!alt) { altElement.setAttribute('aria-hidden', 'true'); altElement.style.zIndex = '-1'; } else { if (altElement.hasAttribute('aria-label')) altElement.setAttribute('aria-label', alt); } }); }; requestAnimationFrame(() => { init(); }); I've also including a very simple example file. This just demonstrates that the designated "Always on top" elements will appear over the image on the slide.17Views1like0CommentsMagic JavaScript switch?
I have a drag and drop quiz with 95 drag options that are then added to a chart. This is all working beautifully and tiling onto the chart very nicely, but if I want to randomize the order that the 95 options appear in (on the drag sequence menu) then I have to manually drag them around to make them appear randomized. Has anyone ever incorporated javascript to make drag options appear in random order if they are appearing one by one? Apologies if this is unclear or not allowed to ask.172Views0likes6CommentsNew Tutorial! Better Organise Unruly Navigation Menus With Custom Line Separators and JS
Hi Heroes, I have a handy Storyline JavaScript hack I'd like to share with you! In this Storyline Magic Series episode, I'll be showing you how to set up an 'Execute JavaScript' trigger that can add custom line separators to the standard navigation menu bar in Articulate Storyline 360. It's a simple but effective technique which provides another option you can use to help visually separate and group slides together within your courses! Check out the full tutorial below, along with a link to all previous episodes in the series: Watch the full series here - https://lnkd.in/dNvyD7wv --- My name's Chris Hodgson, an eLearning developer and software trainer based in the UK. I enjoy creating fun, unique, and engaging online experiences using Articulate software! Connect with me on LinkedIn -https://www.linkedin.com/in/chrishodgson44/28Views1like0CommentsHow to implementing 180-Degree Slider Control
I want to connect a slider to the 360-degree image, enabling the user to control the horizontal movement, similar to how the 'A' and 'D' keys work. I'm unsure which method would result in smoother interaction, so I'd appreciate your recommendation on the best approach. Please refer to the attached image. Additionally, instead of rotating the image a full 360 degrees, I only want to rotate it 180 degrees using the slider. The process I’m describing differs from typical object rotation in product viewers (e.g., rotating a device with a dial). My image is equirectangular, commonly used for 360-degree panoramic views, and I only want to control 180 degrees of its movement through the slider. Based on the instructions provided, the image can be rotated and moved using the keyboard keys (W, A, S, D), but I’d like to replicate this interaction using a slider instead of keyboard input. I also came across a discussion here where someone mentioned difficulties with students using Chromebooks being unable to rotate 360-degree pictures on their touchscreens. They were seeking an alternative method, such as using a slider, to rotate the image. I’m facing a similar challenge, and I’d appreciate any guidance on how to best implement this functionality.97Views0likes1CommentExecuteScript its not working after reload/refresh in trigger.js
Hi, We have recently upgrade the storyline latest version (Build 3.92.33293.0) and we seems some changes in javascript. Earlier we had only user.js file to each slide script calling for jump on other slides. but after upgrade we can see the ExecuteScript moved to seperate file which is trigger.js file to execute the script on case basis. we noticed that trigger.js file having ExecuteScript calling only once while we cached clear and page reload but second time we just reload page its doesn't calling ExecuteScript from trigger.js file. we have added alert into ExecuteScript function it gives prompt on first time only. Can you please look into it and provide the solutions?58Views0likes2Commentsuser.js script error
Hello, all in need of serious help. All of a sudden when I preview my file that runs javascript that has multiple javascript that runs on different slides. I am getting an unexpected token "}". and is says user.js.4090. Can anyone tell me where I can fix this? I am not sure where to go since this is in my preview. I understand the error I just don't know where to go to fix it. I have attached a screenshot to show the error. Also, this shows up even before I run any of my scripts.27Views0likes4CommentsUsing Javascript to run complex mathematical simulations in a 'space survival' game
As a learning designer, I'm always looking for new ways to engage learners and create immersive experiences. I'm a big fan of board games like Catanand7 Wonders, where you have to manage resources and make strategic decisions. It struck me that similar game mechanics could make corporate e-learning more compelling and realistic and help people refine their decision-making skills. I started experimenting with this waaaay back inE-Learning Heroes Challenge #314, with myUsable Suspects game: In that game, the player has topick the best gang memberto crack a safe within 20 seconds. Fast forward toE-Learning Heroes Challenge #430, and I took this 'resource management' concept much further inNo Sushi!: This game involved a lot of complex math that nearly broke Storyline andme. (Yes, I did it all with triggers and, no, I wouldn't do that again!) Recently, I've discovered thatlarge language modelsare great at writing code - it's just another language after all - which makes it astonishingly easy to write custom Javascript for use in Storyline. No more triggers! No more headaches! With the help ofClaude.ai, I built this 'space survival' game: PLAY SURVIVAL HERE! The Concept The game is a first-person survival scenario set on a remote planet. Players must choose two out of three specialists, each with unique skills, to awaken from cryosleep and keep everyone alive for 90 days until rescue arrives. The challenge? Managing four critical resources: Food, Shelter, Security, and Communications. Collaborating with Claude To create the game's underlying simulation, I explained my idea to Claude, outlined what I wanted the code to do, and then defined the specific outcomes I was seeking in Storyline. The Development Process Establishing the Basics: We started by defining the core mechanics – how resources would deplete over time and how each specialist would influence these rates. Creating the Simulation: Claude generated JavaScript code that would run within Storyline, simulating the daily resource changes and determining the mission's outcome. Balancing Act: One of our biggest challenges was fine-tuning the resource depletion rates to ensure each team combination (A+B, A+C, B+C) presented unique challenges and outcomes. This required multiple iterations and careful adjustments. Implementing Cascading Effects: We introduced more complex mechanics, such as security breaches leading to rapid resource loss, and the effects of malnutrition on the crew's ability to maintain systems. Crafting Narratives: For each possible outcome, we developed detailed feedback messages to provide players with a clear understanding of their mission's fate. Debugging and Refinement: Throughout the process, we encountered and solved various issues, from unexpected behaviour in certain scenarios to ensuring the correct triggers for different endings. Lessons Learned Iterative Development is Key: Our back-and-forth process, constantly testing and refining the simulation, was crucial to creating a balanced and engaging game. Claude as a Collaborative Tool: Claude proved helpful in rapidly prototyping ideas, generating code, and problem-solving. However, human oversight and creative direction were essential in shaping the final product. Balancing Realism and Gameplay: We often had to strike a balance between realistic outcomes and maintaining engaging gameplay. For instance, we adjusted how quickly resources depleted to create tension without making the game overly difficult. The Importance of Narrative: While the underlying mechanics were crucial, we found that crafting compelling narratives for each outcome enhanced the player experience. The characters define the mechanic and vice versa. Flexibility in Design: Being open to unexpected outcomes led to more interesting gameplay. For example, we implemented a system where the communication beacon could continue functioning even after the crew had perished, adding a thoughtful touch to certain failure scenarios. Technical Challenges and Solutions One particular challenge we faced was ensuring that for certain team combinations (like A+B), security would fail before other resources reached critical levels. This required careful adjustment of depletion rates and the implementation of conditional penalties. We also had to be mindful of some limitations, particularly how Storyline displays text generated by variables. This led to problem-solving sessions, where Claude and I used the console log to dig into what was happening. Conclusion While collaborating with Claude felt very natural, we did at times have to go back a few steps to debug the code. I am not a coder, so I don't know whether 12 iterations to get this to work as I liked is unreasonable by human standards. But I'm really pleased with the results.SURVIVALteaches resource management and strategic thinking while also telling a story of survival against the odds. And it conveys this lesson in just two slides and a few minutes of your time. I haven't shared my master file as I'm still tinkering with the visual design and this will likely become a portfolio piece, but I'm happy to share what I've learned and answer any questions you may have. For anyone interested,here's the latest version of the code that powers the simulation. If you want to know more about any part of this demo, please ask. (This is a repost of this article from the 'Share Examples' group.)102Views2likes0CommentsJavascript not working in full screen
Hi all! I have two Javascript codes that execute when selected: one to copy a claim key, and another to add confetti. Both seem to work when completed normally, but once I'm in full screen, neither work! Is it because of the Javascript itself? To recreate the issue: 1. Claim key: if you have something copied, open the Storyline file in full screen, select the "Copy Claim Key" button, and paste in the text field below. If in full screen, it will paste your previous selection instead of the key (which is "S8AM83B2QDBBKKF89K3K")! The code used for this is below, using a "ClaimKey" variable already set in the Storyline file: var player = GetPlayer(); var text = player.GetVar("ClaimKey"); copyFunction (text); function copyFunction(tt) { const copyText = tt; const textArea = document.createElement('textarea'); textArea.textContent = copyText; document.body.append(textArea); textArea.select(); document.execCommand("copy"); textArea.style.display = "none"; } 2. Confetti: if you select the "Add Confetti" button, the confetti will appear on the page normally. If you select full screen and the "Add Confetti" button again, exit full screen early to see the last instances of confetti that don't show up in full screen. Two Javascript codes were used for confetti: var duration = 5 * 1000; var animationEnd = Date.now() + duration; var defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 }; function randomInRange(min, max) { return Math.random() * (max - min) + min; } var interval = setInterval(function() { var timeLeft = animationEnd - Date.now(); if (timeLeft <= 0) { return clearInterval(interval); } var particleCount = 50 * (timeLeft / duration); // since particles fall down, start a bit higher than random confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } })); confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } })); }, 250); var confettiScript = document.createElement('script'); confettiScript.setAttribute('src','https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js'); document.head.appendChild(confettiScript); *The second code is a workaround I used from this Little Man Project postto avoid updating the HTML file each time I publish :) I'm a JavaScript beginner, so any help is appreciated! You can preview the issue here in Review, and I've attached the file for reference. Thanks!Solved191Views1like5CommentsStoryline 360 JS: Pointing to a local file instead of a URL
Looking at JLiu's and Chris Hodgson's solution to integrate canvas-confetti.js into the Storyline slide stage and looking over this code: var confettiScript = document.createElement('script'); confettiScript.setAttribute('src','https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js'); document.head.appendChild(confettiScript); I am wondering if there is a way that the "src" attribute can point to a local file? I was wondering about a webobject. I am not sure if this would be the case?Solved84Views0likes2CommentsGSAP Articulate Storyline 360 Restart Issue
Greetings. I've posted my issue on the GSAP forums. But upon looking through there it seems there's only a handful of people who can relate with Articulate Storyline 360. So I decided to try my luck here in the e-learning heroes forums. This is my issue https://gsap.com/community/forums/topic/42498-gsap-articulate-storyline-360-restart-course-bug If anyone is knowledgable with GSAP and JS in general that could help. It would be really appreciated. Any input is welcome. Thank you! P.S. MathNotermans-9 if you can read this, I wanted to PM you specifically to inquire about this issue since I've seen your posts on JS and all that. But I can't find a PM function, so was hoping you can see this message and reach out hopefully.204Views0likes15Comments