Random letters

Hi can I ask some help please, I’m trying to randomize the letters then animate to going up, this is working fine if I statically put the letters inside the div “balloon-area”, but now I want to dynamically randomize the letters and animate it, I tried to append the HTML to the div, but the problem is that the image is getting thicker or the balloon and sometimes the balloons are blinking ? Because it adds every 1 sec.

To give some idea I want to achieve to show to the users random letters going up inside the balloon, and the user can click the balloon, but before this clicking the balloon I need to fix first the random letters display going up.

I apologize, I uploaded the images balloon, but I don’t know how can I reference it to the URL.

Thank you in advance.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

</head>

<style type="text/css">
    .balloon-area{
        border:solid 1px red;
        height:600px;
        width:600px;
        margin-top:50px;
    }
    .balloon {
        width: 20%;
        height: 35%;
        position: absolute;

    }
    .balloon-area {
        border: solid 1px red;
        height: 600px;
        width: 600px;
        margin: 50px auto 0;
        overflow: hidden;
        position: relative;
    }
    .balloon-hit-area {
        width: 100%;
        height: 55%;
        background: transparent;
        font-size: 40px;
        color: #fff;
    }
    .balloon {
        width: 20%;
        height: 35%;
        position: absolute;
    }
    .balloon {
        border: 5px solid transparent; /* hide animation bug with border on button*/
        animation: float 15s infinite 1s;
        opacity: 0;
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;

    }
   .balloon button {
        position: relative;
    }

    .balloon[data-style="1"]::before{
        background-image:url("'/img/balloon/blue.png");
    }
    .balloon[data-style="2"]::before{
        background-image:url("'/img/balloon/red.png");
    }
    .balloon[data-style="3"]::before{
        background-image:url("/img/balloon/orange.png'");
    }
    .balloon[data-style="4"]::before{
        background-image:url("/img/balloon/green.png'");
    }
    .balloon[data-style="5"]::before{
        background-image:url("/img/balloon/purple.png') ");
    }
    .balloon[data-style="6"]::before{
        background-image:url("/img/balloon/blue.png')");
    }

    [data-style] button {
        border: 0;
    }
    .balloon::before{
        content:'';
        position: absolute;
        top:0;
        left:0;
        width:100%;
        height:130%;
        background-size: 90%;
        background-position-x:50%;
        background-repeat:no-repeat;
    }
    [data-position="1"]{
         left:5%;
     }
    [data-position="2"]{
        left:70%;
    }
    [data-position="3"]{
        left:35%;
    }
    [data-position="4"]{
        left:42.5%;
    }
    [data-position="5"]{
        left:75%;
    }

    .delay1 {
        -webkit-animation-delay:  250ms;
        animation-delay: 250ms;
    }

    .delay2 {
        -webkit-animation-delay: 2s;
        animation-delay: 2s;
    }

    @keyframes float {
        0% {
            transform: translate3d(0, 600px, 0);
            opacity: 0;
        }
        10% {
            opacity: 1;
        }
        90% {
            opacity: 1;
        }
        100% {
            transform: translate3d(0, -1000px, 0);
            opacity: 0;
        }
    }


</style>
<body>

<div class="container">

    <div class="content">
        <div class="row">
            <div class="row balloon-area">

                
            </div>
            <div class="questionword text-center text-success"><h1>WING</h1></div>
        </div>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>


<script type="text/javascript">

    let word = "WING";

    let answerWord = [];

    setInterval(function(){

        let str = genereteLetter(3);
        let myArr = str.split("");

        let word = '<div class="balloon  delay1" style="top: 40.1%;opacity: 1;" data-style="1" data-position="1">' +
                            +'<button type="button" class="balloon-hit-area">'+myArr[0]+'</button>'+
                    '</div>' +
                    '<div class="balloon delay1" style="top: 85.455%;opacity: 1;" data-style="2" data-position="2">'+
                        +'<button type="button" class="balloon-hit-area">'+myArr[1]+'</button>'+
                    '</div>'+
                    '<div class="balloon delay1" style="top: 60.455%; opacity: 1;" data-style="3" data-position="3">'+
                            '<button type="button" class="balloon-hit-area" >'+myArr[2]+'</button>'+
                    '</div>';

         // $('.balloon-area').append(word);
    }, 1000);


    $('.balloon-hit-area').on('click',function(){

        console.log($(this).text());

    });

    function genereteLetter(length) {
        var result           = '';
        var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        var charactersLength = characters.length;
        for ( var i = 0; i < length; i++ ) {
            result += characters.charAt(Math.floor(Math.random() *
                charactersLength));
        }
        return result;
    }

</script>

</body>
</html>

blue

green

orange

purple

red

Ok a few things… first of all I think you should probably use a template string for your appending HTML.

let word = `<div class="balloon  delay1" style="top: 40.1%;opacity: 1;" data-style="1" data-position="1">
                <button type="button" class="balloon-hit-area">${myArr[0]}</button>
            </div>
            <div class="balloon delay1" style="top: 85.455%;opacity: 1;" data-style="2" data-position="2">
                <button type="button" class="balloon-hit-area" >${myArr[1]}</button>
            </div>
            <div class="balloon delay1" style="top: 60.455%; opacity: 1;" data-style="3" data-position="3">
                <button type="button" class="balloon-hit-area" >${myArr[2]}</button>
            </div>`;

Notice this starts and ends with backticks. Then each variable is set off with ${} so you can print the values right into the HTML without all the concatenation. I tried your code and because of all the concats it was through a bunch of NaN errors.

On top of this, I noticed you had issues in your background-image definitions. You have extra single quotes and parenthesis that shouldn’t be there.

.balloon[data-style="1"]::before{
        background-image:url("'/img/balloon/blue.png"); //<-- Problem with single quote
    }
    .balloon[data-style="2"]::before{
        background-image:url("'/img/balloon/red.png"); //<-- Problem with single quote
    }
    .balloon[data-style="3"]::before{
        background-image:url("/img/balloon/orange.png'"); //<-- Problem with single quote
    }
    .balloon[data-style="4"]::before{
        background-image:url("/img/balloon/green.png'"); //<-- Problem with single quote
    }
    .balloon[data-style="5"]::before{
        background-image:url("/img/balloon/purple.png') "); //<-- Problem with single quote and parenthesis
    }
    .balloon[data-style="6"]::before{
        background-image:url("/img/balloon/blue.png')"); //<-- Problem with single quote and parenthesis
    }

Next, you don’t want to be endlessly appending to the balloon area. That is what is causing your thickening wording/balloons. You want to append off screen (outside the view of the balloon area) and then scroll them into view and once off the screen, remove them from the balloon area. That or once they are off the screen, reset them to the bottom, change the letters on the balloons and scroll them into view again.

Think of the balloon area like a window that someone is walking past. But once they pass, they duck their head down, sneak back across, pop up and then walk past the window again.

Give that some thought and see if this helps.

2 Likes

Hi, Thank you for the reply, don’t worry about the background-image it works at my end , just wrong typo :slight_smile:

@Martyr2

then scroll them into view and once off the screen

Is this what you mean ?

  <div class="row balloon-area">
     <div class="lettersarea"></div>
  </div>
setInterval(function(){

        let str = genereteLetter(3);
        let myArr = str.split("");

        let word = `<div class="balloon  delay1" style="top: 40.1%;opacity: 1;" data-style="1" data-position="1">
                <button type="button" class="balloon-hit-area">${myArr[0]}</button>
            </div>
            <div class="balloon delay1" style="top: 85.455%;opacity: 1;" data-style="2" data-position="2">
                <button type="button" class="balloon-hit-area" >${myArr[1]}</button>
            </div>
            <div class="balloon delay1" style="top: 60.455%; opacity: 1;" data-style="3" data-position="3">
                <button type="button" class="balloon-hit-area" >${myArr[2]}</button>
            </div>`;

        $('.lettersarea').append(word);
        $('.lettersarea').scrollTop(600);
    }, 1000);

But how can I remove if it reaches at the end of my (.ballon-area) ?

Thank you in advance.

Hi @Martyr2 @PaulOB

here is my codepen I find way to upload image so that you can see how the balloon displays

Thank you in advance.

If you set the opacity to zero to start with you won’t see the balloon appear in the middle of the div each time it restarts.

e.g.

<div class="balloon  delay1" style="top: 40.1%;opacity: 0;" data-style="1" data-position="1">
                <button type="button" class="balloon-hit-area">${myArr[0]}</button>
            </div>
            <div class="balloon delay1" style="top: 85.455%;opacity: 0;" data-style="2" data-position="2">
                <button type="button" class="balloon-hit-area" >${myArr[1]}</button>
            </div>
            <div class="balloon delay1" style="top: 60.455%; opacity: 0;" data-style="3" data-position="3">
                <button type="button" class="balloon-hit-area" >${myArr[2]}</button>
            </div>`;

As @Martyr2 already said you are continually appending 3 new divs so eventually the browser will probably crawl to a halt. Also as the animation is set to infinite you have thousands of divs continually animating when in fact they could each just animate once.

I think you would be better off having a finite number of divs in the html to start with and as you seem to have about 12 balloons visible at any one time it would seem 12 divs would do.

You could set the delay for each set of 3 so they don’t overlap. When the first set of 3 ends it’s animation it will start again if using the infinite value.

That means you only have to change the letters in the existing balloons and not keep adding divs.

You’ll have to time it so that you add the new letters on each new iteration of the animation. That’s really a question for the JS forum perhaps as my JS skills are basic :slight_smile:

1 Like

Here’s a rough idea where css does the continuous animation and js randomizes the letters at the end of each animation.

I’m sure it could be tidied up a lot (and the html auto generated) but I’m away from home and on a toy computer but hopefully it can help with your task.

You now need to add your functions to test which letter was clicked and then match it to your word etc.

2 Likes

Hi @PaulOB,

Thank you so much, this is what I want.

You now need to add your functions to test which letter was clicked and then match it to your word etc

Yes I can proceed now thank you :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.