Exploring the dynamic world through HTML5 canvas and animated objects

Today I am exploring HTML 5 canvas and experimenting with moving 3 circles on the canvas. Based on my research, it looks like I need to continuously redraw the circles (perhaps every 60 milliseconds) and clear out the old circle before rendering the new one in its updated position.

Currently, I have a draw() function that displays 3 circles, each in a different color. The goal is to control the movement of each circle individually.

I'm seeking guidance on how to set this up initially and animate each ball effectively.

This is the progress I've made so far:

<html>
<head>
    <title>Ball Demo</title>
    <style type="text/css">
        #ball-canvas {
            border: 1px solid #666;
        }
    </style>
</head>
<body>
    <canvas id="ball-canvas" width="900" height="600"></canvas>
    <script>

        function renderCircle(context, x, y, radius, fill) {
            var strokeWidth = 2
            context.beginPath();
            context.arc(x, y, radius - (2 * strokeWidth), 0, 2 * Math.PI, false);
            context.fillStyle = fill;
            context.fill();
            context.lineWidth = strokeWidth;
            context.strokeStyle = '#666';
            context.stroke();
        }

        function draw() {
        renderCircle(context, radius, canvas.height / 2, radius, 'yellow');
        renderCircle(context, canvas.width / 2, canvas.height / 2, radius, 'blue');
        renderCircle(context, canvas.width - radius , canvas.height / 2, radius, 'red');

        }


        var canvas = document.getElementById('ball-canvas');
        var context = canvas.getContext('2d')
        var radius  = 50;


        setInterval(draw, 1000 / 60);

    </script>
</body>

Answer №1

Learn how to manipulate circles on an HTML canvas with this step-by-step guide:

Check out a live demonstration here: http://jsfiddle.net/m1erickson/JQQP9/

First, define each circle as an object:

var circle1={
    x:50,
    y:50,
    radius:25,
}

var circle2={
    x:100,
    y:100,
    radius:25,
}

Add these circles to an array:

var circles=[];

circles.push(circle1);
circles.push(circle2);

Create a function to draw all circles:

This function will clear the canvas and redraw all circles at their current x,y positions:

function draw(){
    context.clearRect(0,0,canvas.width,canvas.height);
    for(var i=0;i<circles.length;i++){
        var c=circles[i];
        context.beginPath();
        context.arc(c.x,c.y,c.radius,0,Math.PI*2);
        context.closePath();
        context.fill();
    }
}

To move the circles, update their x,y coordinates and then redraw them:

circles[0].x+=1;
circles[1].y+=1;
draw();

To add animation, consider using requestAnimationFrame for smoother movement:

var frameCount=0;

animate();

function animate(){
    if(frameCount<160){requestAnimationFrame(animate);}
    circles[0].x+=1;
    circles[1].y+=1;
    draw();
    frameCount++;
}

Answer №2

If you want to update the canvas in a smooth and efficient way, one common approach is to utilize window.requestAnimationFrame. This function allows for redrawing the canvas every time the browser checks if a screen refresh is necessary. I have made some adjustments to your draw method and initialization code below:

    function draw() {
      // Call requestAnimationFrame with itself as a callback to schedule the next frame
      requestAnimationFrame(draw);

      // Clear the canvas to prevent trails from appearing
      canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);

      // Calculate new circle positions based on current time
      var now = +new Date();
      var halfWidth = canvas.width / 2;
      var maxX = canvas.width - radius;
      var spaceBetween = canvas.width / 3;
      var x1 = (halfWidth + now) % maxX;
      var x2 = (x1 + spaceBetween) % maxX;
      var x3 = (x2 + spaceBetween) % maxX;

      var y = canvas.height / 2;
      renderCircle(context, x1, y, radius, 'yellow');
      renderCircle(context, x2, y, radius, 'blue');
      renderCircle(context, x3, y, radius, 'red');
    }

    var canvas = document.getElementById('ball-canvas');
    var context = canvas.getContext('2d')
    var radius  = 50;

    // Start the animation
    draw();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is Eval really as bad as they say... What alternative should I consider using instead?

After making an ajax request, a JSON array filled with user inputs is returned to me. The inputs have already been sanitized, and by utilizing the eval() function, I can easily generate my JavaScript object and update the page... However, there lies a dil ...

Determine the TR id when a button within a TD element is clicked using JavaScript/jQuery

Currently seeking a method to generate a unique identifier for use as a parameter in a JavaScript function. Specifically interested in extracting the id of the first td element if feasible. <tr id='it'><td id="#nameiron">Jason</td ...

Obtaining table data and HTML elements using the correct code - Selenium and Python

I've been attempting to extract the ticker symbol, stock name, price, sector, and market cap columns from this website. I'm facing challenges in identifying the correct HTML elements using the appropriate code. Although I've used Selector Ga ...

Having trouble retrieving the data property from the parent component within the child component slot

I am facing an issue with my Vue components. I have a rad-list component and a rad-card component. In the rad-list component, I have placed a slot element where I intend to place instances of rad-card. The rad-card component needs to receive objects from t ...

Are you experiencing issues with modal contents extending beyond the modal on smaller screens?

I recently installed a modal plugin called blockUI for my image uploading needs. Although I have styled and positioned everything accordingly, I am facing an issue: Whenever I resize the browser screen, switch to my iPhone, or use another screen, some con ...

Tips for properly formatting the sort_by parameter in Cloudinary to avoid errors

Greetings to the helpful stack overflow community, I have encountered an issue with fetching images from cloudinary via a post request. Everything works fine until I include the sort_by parameter in the URL. This results in an error related to the format ...

Tips for validating a text field in React Material UI depending on the input from another text field

Currently, I am working with Material UI TextField and encountered an issue where I need to create a code that establishes a dependency between two textfields. For example, if I enter the number 4 in textfield one, then the number in textfield two should ...

The function history.popstate seems to be malfunctioning, as it is triggered by both the forward and backward navigation buttons in

When I press the back button, I am attempting to retrieve the previous state. Upon inspecting, I noticed that the popstate function is also triggered by the forward button. However, it does not revert to the previous state even though the popstate function ...

Substitute this.bindMethod for function component

I have a class component that is structured like this: interface MyProps { addingCoord: any resetCoords: any } interface MyState { x: any y: any } class DrawerOld extends React.Component<MyProps, MyState> { width: number height: number ...

Using the <li dir="..."> tag can cause list indicators to break

Is there a method to utilize dir tags for <li> elements without disrupting the list indicators? Logically, they should all align on the same side and RTL <li> elements in an otherwise LTR document should either be left-aligned if it's only ...

What are the capabilities of Ajax when it comes to utilizing select controls in J

Is there a way to trigger an ajax call when a select control value is clicked? The onChange event doesn't seem to work for me in this case :( This is what I have tried so far: JAVASCRIPT: <script> function swapContent(cv) { $("#myDiv"). ...

Executing asynchronous promises within an asynchronous promise using the .join() method

I am currently utilizing node/express, MySQL, and Bluebird for my project. When handling client requests, I am performing async database operations. After the initial database operation callback, I need to carry out some calculations before executing two ...

The phonegap page redirection is failing, as the 'location' property of the object does not function correctly

I'm attempting to implement a straightforward page redirection in PhoneGap using JavaScript. Within an iframe, I have the following code: window.parent.location("event_select.html"); Unfortunately, this approach is unsuccessful and results in the fo ...

Once the data is retrieved and the old image is deleted, attempting to upload the new image still results in the old image being displayed in the Next.js application with React Query

async function fetchTour() { const response = await api.get(`/tour/${router.query.slug}`); return response.data; } const { data: tourData, isLoading, isFetching, isTourError: isError, } = useQuery(['fetchTour', router.que ...

What are the steps to implement background synchronization in place of making fetch requests upon UI changes?

Consider this scenario: A straightforward web application with a comments feature. In my view, when a user submits a comment, the following steps would typically unfold: Show UI loader; Update the front-end state; Send a fetch request to the API to post ...

Having trouble with the functionality of my JavaScript slider

After attempting to incorporate a slider into my website, I encountered an issue where the slider was not functioning as expected. The slider I tried to implement can be found here: https://codepen.io/amitasaurus/pen/OMbmPO The index of the site can be a ...

Unable to save data in local storage

I'm enhancing an existing chrome extension while ensuring a consistent style. I am looking to implement a new feature, and I have written a script that saves the user's selection from the popup and sets a new popup based on that choice going forw ...

Arranging divs with HTML and CSS

I am currently facing issues with the positioning of 3 scripts in my HTML file. The vertical gauge is overlapping the second circular gauge, despite trying different positioning options to no avail. How can I adjust the layout so that the vertical gauge a ...

Incorrect JavaScript switch case usage

Once again, I find myself with a question regarding JavaScript. This one seems to be an easy fix, but for some reason, I just can't seem to figure out what went wrong: I have a textbox and a button. When the button is clicked, the value should be pas ...

The resulting line will consist of the discovered string

Let's say there's an interesting HTML document presented below with associated line numbers: 30 - <div id="myDiv"> 31 - <span class="mySpan">Some Text</span> In this scenario, PHP is being utilized for a specific purpose: $ ...