Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
i am trying to create a looping animation of a ball travelling to and fro across the canvas width and i used a sinusoidal function linked to the time parameter of the requestAnimationFrame() but instead the result is a steady increase in value. The code is as shown below:
<script>
        let container = document.getElementById("container");
        let mform = document.getElementById("former");
        let canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d");
        ctx.canvas.width = container.clientWidth; ctx.canvas.height = container.clientHeight;
        let  radius = Math.floor(0.05*ctx.canvas.width),location1 = {x:radius,y:(ctx.canvas.height/2)};
        let leftToRight = true;
        let  colorpick = mform.elements["color1"],color1 = colorpick.value || "red";
        let speedinput = mform.elements["speed1"],speedModifier = speedinput.value;
        function drawBall(radius,color,location1){
            clearBall();
            ctx.fillStyle = `${color}`;
            ctx.strokeStyle = "yellow"; ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.arc(location1.x,location1.y,radius,0,2*Math.PI,true);
            ctx.fill();
            ctx.beginPath();
            ctx.arc(location1.x,location1.y,radius,0,2*Math.PI,true);
            ctx.stroke();
        }
        function clearBall(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
        }
        
        function animate(timer){
            
            colorpick.onchange = function(evt){color1 = colorpick.value;
                //drawBall(radius,color1,location1);
            } ;
            speedinput.onchange = function(evt){speedModifier = speedinput.value;
                //drawBall(radius,color1,location1);
            };
            window.onresize = function(evt){
                ctx.canvas.width = container.clientWidth; ctx.canvas.height = container.clientHeight;
                radius = Math.floor(0.05*ctx.canvas.width)
                
            };
            //clearBall();
             
             location1.x += Math.abs( Math.sin(speedModifier*(timer/6000))) ;       
            drawBall(radius,color1,location1);
            //(ctx.canvas.width-(2*radius))*
            
            window.requestAnimationFrame(animate);
            console.log("location1.x is " + location1.x + "timer is " + timer + "canvas width is "+ ctx.canvas.width +"\n");
            

        }
        
       requestAnimationFrame(animate);
        
    </script>


What I have tried:

i have searched stack overflow and cant find an answer to the problem.
Also writing the function in matlab gave the curve output i was aiming for,but my javascript code couldnt give me the required result.
Posted
Updated 13-Jun-23 3:07am

1 solution

I am going to take a guess at your code and say that the issue lies in the line where you update the 'location1.x' value using the 'Math.sin' function returning -1 or 1, in your case 1. Currently, you are using 'Math.abs' on the returned value of 'Math.sin', which always give you a positive value.

Math.sin()[^] and Math.abs()[^]

The following line should solve the issue -

Replace this line
location1.x += Math.abs( Math.sin(speedModifier*(timer/6000))) ;

with -
location1.x = (ctx.canvas.width - 2 * radius) / 2 + (ctx.canvas.width - 2 * radius) / 2 * Math.sin(speedModifier * (timer / 6000));


I created a jsfiddle which works fine at To and Fro Ball Animation[^]
 
Share this answer
 
v3
Comments
obiora okafor 13-Jun-23 19:45pm    
Thanks a lot Andre Oosthuizen, i really appreciate your assistance.
Andre Oosthuizen 14-Jun-23 4:33am    
Pleasure, did it work for you?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900