Forum Discussion

KrisShenenbe782's avatar
KrisShenenbe782
Community Member
2 months ago

Fake a Blinking Cursor

Hi all. I'm simulating entering text in a DOS command window. I have instructions and a text entry field. The text entry field is the bottom layer so when landing on the page the cursor is already blinking. That's how it works in the real system. But, doing that means Jaws won't read the directions first. Does anyone know how to fake a blinking cursor that stops when users click in the field or have a work around so when users land on the page the cursor is already blinking but the instructions are read first? I'm using the Pick 1 quiz slide.

 

Thanks,

Kris

  • AndrewHanley's avatar
    AndrewHanley
    Community Member

    Hi Kris,... firstly, respect for mentioning DOS and the command prompt - takes me back to my good old days of games programming! ;)

    Second, you can absolutely fake a blinking cursor in a text field. The blink is fairly easy to do. Set up two layers, each one 0.5 seconds long (thats about how long a "blink" lasts)

    On Layer 1 you will show your white cursor

    On Layer 2, it wont show anytihng (but the timeline is still set to 0.5s)

    Now on Layer 1, add a trigger that says SHOW LAYER "Layer 2" WHEN TIMELINE ENDS on THIS LAYER

    And the same for Layer 2 (except of course you are showing Layer 1 when timeline ends)

    This is a nice little timer hack, so SL will automatically swap between the layers at the right time and it will look like a blinking cursor.

    If you then need to MOVE your cursor as the user types (just like in DOS), then I would just use a state in Layer 1 for each position of your cursor (1,2,3,4,5... etc)

    Once you have the states set up, you just need to show the correct state WHEN TIMELINE STARTS on Layer 1. TO do this, you could use JS if you are comfortable with it, or a Numeric SL variable could hold the character count of the text field, and  show the corresponding blinking cursor state.

    Does that help at all?

    • KrisShenenbe782's avatar
      KrisShenenbe782
      Community Member

      This is very helpful! I'm going to try it today. A few questions.

      What do you mean by this:
      If you then need to MOVE your cursor as the user types (just like in DOS), then I would just use a state in Layer 1 for each position of your cursor (1,2,3,4,5... etc)

      Do I set the layers to show the base layer?

      How would the javascript go? 

      Thank you so much!

      • AndrewHanley's avatar
        AndrewHanley
        Community Member

        Sorry Kris, only now did I realise your questions were to me!

        So yes, when you need to move that cursor when the user types, you will simply move from one state to another in Layer 1. Each position of the cursor will be set up as a different state in the layer.

        Im not sure what you mean with this one - "do i set the layers to show the base layer?", but dont worry too much here. The base layer will show automatically, and this is where you will have your text input field. The additional Layer 1 and Layer 2 are only there to make a fake cursor blink.
        Therefore, as long as you show Layer 1 when you start to type, the rest will take care of itself.

        You asked about the javascript...
        Ive attached an actual Storyline project file here with the JS in it.


        It works!... and I messed around a little to refine it (for example I noticed when comparing it to DOS, that the DOS cursor doesnt blink uniformly, it actually doesnt blink when you type, so I have tweaked my SL file to mimic this behaviour)

        It could do with more polish though! :)

        Does this help for a solution?

  • Respect!

    If it's timed on the timeline, doesn't it stop blinking when the timeline ends? I'd like it to blink continuously until someone types in the text enter field.

  • AndrewHanley's avatar
    AndrewHanley
    Community Member

    No it will blink until the Second Coming if you leave it XD

    Each layer will call the other, so it will show, then hide, then show, hide, etc etc

    Its a great little timer hack that I use alot for timers, countdowns etc.

  • You could also insert a pipe or vertical bar (|), align it with the cursor, and animate it with CSS. Initially, hide the pipe. When the text field is not in focus, the pipe will show and start blinking. When the text field is in focus, the pipe will be hidden, and the cursor will show. I know it might be a bit much, but it's the only solution I can think of right now. I did not have time to try Andrew's solution but it looks like it could work too. It sounds like JAWS is automatically focusing on the data entry field as soon as it’s loaded, which might be interfering with your testing or development. I think the issue is due to the removal of the data entry field placeholder. To fix it, create a new data entry field, remove the placeholder from this new field, position it off-screen, and exclude it from the focus order. This way your original data entry field will not get immediate focus. Anyway, a fake cursor code:

    const addCSS = css => {
        const style = document.createElement("style");
        style.textContent = css;
        document.head.appendChild(style);
    };

    addCSS(`
        .blink {
        -webkit-animation: blink 1.1s step-start infinite;
                animation: blink 1.1s step-start infinite;
    }

    @-webkit-keyframes blink {
        0%, 50% {
            opacity: 1;
        }
        50.01%, 100% {
            opacity: 0;
        }
    }

    @keyframes blink {
        0%, 50% {
            opacity: 1;
        }
        50.01%, 100% {
            opacity: 0;
        }
    }
    `);

    const pipe = document.querySelector('[data-acc-text="pipe"]');
    const textField = document.querySelector('.acc-textinput');

    textField.addEventListener('focus', function() {
        pipe.classList.remove('blink');
        pipe.classList.add('hidden');
    });

    textField.addEventListener('blur', function() {
        pipe.classList.remove('hidden');
        pipe.classList.add('blink');
    });

    • KrisShenenbe782's avatar
      KrisShenenbe782
      Community Member

      This is also helpful. I'm going to try this as well. A few questions.

      How do you add css to Storyline?

      You wrote this:
      I think the issue is due to the removal of the data entry field placeholder

      What is the placeholder? The "Type your response here" text?

      You wrote this:
      This way your original data entry field will not get immediate focus. 

      But won't it still read the text entry field first?

       

      Thank you!

  • How do you add css to Storyline?
    CSS is added dynamically with JavaScript. You can find the code in my previous post. This approach would only be relevant if you decide to use a pipe/vertical bar solution to ensure continuous cursor/fake cursor blinking.

    What is the placeholder? The "Type your response here" text?
    Yes.

    You wrote this: I think the issue is due to the removal of the data entry field placeholder
    Put the placeholder back and run the slide with JAWS to see what happens.

    You wrote this: This way your original data entry field will not get immediate focus. 
    Having two data entry fields on the slide will prevent immediate focus on the first one without a placeholder. Place the second field off-screen and remove it from the focus order to ensure it is not visible on the slide or to screen readers (it won't be outlined). Keep in mind that this is not a standard procedure; we are doing this solely to implement the continuous cursor blinking effect. You can see it in action in the attached video.   

  • AndrewHanley's avatar
    AndrewHanley
    Community Member

    P.S. for the project file above, simply run it and type - the text field is already auto selected (focussed) for you, so you can just start typing.

    Ive added up to 10 positions for the cursor. You can add way more if you want, but I was just messing around for now.

    Finally, if you open up the console window (press F12 when previewing the slide, then click the CONSOLE tab) , you will see some JS messages being shown which monitor the character count of the input field in realtime (using an eventListener)

    Now.... how do we get it to play Doom 2?! :P

    • KrisShenenbe782's avatar
      KrisShenenbe782
      Community Member

      Andrew, that is so cool! Let me add some things and I'll let you know how it goes. Thank you!

  • Andrew, do you think it's possible to use your technique with a freeform quiz slide (Pick 1)?

  • AndrewHanley's avatar
    AndrewHanley
    Community Member

    Absolutely! The technique should be pretty portable to any slide/question type.

    Are you thinking for something like they enter in the answer and it checks to see if they are correct/incorrect?

  • I should have tested before texting! Yes, it works with the quiz slide. I wish there was a way to get rid of the vertical bar. 

    What you've done is really cool. Thank you so much for teaching me something new!

  • AndrewHanley's avatar
    AndrewHanley
    Community Member

    Yeah I was thinking the same thing about the vertical i bar... maybe we could actually focus on another text field that is off slide (so invisible).
    As the user types there, we copy the value of that text field immediately in to another text field that IS on screen.

    That might work?!.... :D

    I'll leave that juicy nugget up to you! Good luck with the development. It sounds intriguing!