Create an animation on canvas of a shape moving along a square path using a sine wave

Currently, I am attempting to create a basic animation in which a shape moves along a square path determined by a specified 'radius'. Right now, I am utilizing a sine wave to control the position over time, resulting in the shape moving along a circular path. Is there a mathematical approach to adjusting the sine wave to achieve a square animation? While aware of alternative methods of accomplishing this task, I am keen on delving into the math behind it.

Here is an example fiddle:

t = new Date().getTime()

r = 25

x = (r * Math.cos t * 0.005) 
y = (r * Math.sin t * 0.005)

http://jsfiddle.net/Z5hrM/1/

Answer №1

There is more to geometry than just circles and squares! The equations for x and y can be enhanced with an exponent D:

 x = (r^D * cos(theta))^(1/D) and y = (r^D * sin(theta))^(1/D)

For D = 1, you get the standard circle equations. For D = 0.5, a diamond shape is formed; values of D less than 0.5 create pointed stars. As D increases above 1, blocky shapes emerge, eventually morphing into a square as D approaches infinity. Experiment with this code snippet by adjusting the value of D during the animation.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>animation problem</title>
<script type='text/javascript'>
    function demo(){
        var w = 400;
        var ctx = document.getElementById("canvas").getContext("2d");
        ctx.canvas.width = w;
        ctx.canvas.height = w;
        var r = w/4;
        var theta = 0;

        setInterval(function(){
            ctx.canvas.width += 0;    //  clear the canvas
            ctx.translate(w/2, w/2);  //  center it on (0,0)
            var D = +document.getElementById("exponent").value;

            var xSign = Math.cos(theta) < 0 ? -1 : 1;  // Handle all quadrants this way
            var ySign = Math.sin(theta) < 0 ? -1 : 1;
            var x = xSign*Math.pow( Math.pow(r, D)*Math.abs(Math.cos(theta)), 1/D );
            var y = ySign*Math.pow( Math.pow(r, D)*Math.abs(Math.sin(theta)), 1/D );
            ctx.fillStyle = "blue";
            ctx.arc( x, y, 20, 0, 6.2832, false );
            ctx.fill();

            theta += Math.PI/100;
        }, 20);
    }
</script>
</head>
<body onload='demo()'>
    <input id='exponent' type=text value='1'\>
    <br />
    <canvas id='canvas'></canvas>
</body>
</html>

Answer №2

CodePen Example

To transform the path into a square shape, minimal adjustments are required. Since the cosine corresponds to the x coordinate and the sine corresponds to the y coordinate, it is evident that one of these values must be rounded to a whole number for a square path.

Therefore, Math.cos t and Math.sin t should be controlled using a variable and a condition like below:

xcos = Math.cos t * 0.005
ysin = Math.sin t * 0.005

if Math.abs(xcos) > Math.abs(ysin)
 xcos = Math.round(xcos)                                       
else
 ysin = Math.round(ysin)     

x = @cx + (radius * xcos)
y = @cy + (radius * ysin)

Answer №3

Ensure that your variable r is defined as a two-dimensional vector (x,y) to manage position and increment along the x and y axes. Simply changing x = (0 * Math.cos t * 0.005) will only move the circle up or down, but for shape behavior control, manipulate the vector (x and y positions) over time and utilize remainder (%) to wrap around x and y positions.

Best regards.

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

How can I create a clickable <div> element containing multiple links and trigger only one action?

Within my code, there is a <div> element that has been made clickable. Upon clicking this <div>, the height and text expand using the jQuery function $(div).animate();. While this functionality works as intended, I am encountering a slight issu ...

React Select value remains unchanged after state modification

I'm facing an issue with a select component that should reset to the "Neutral" state after the user clicks the next button. However, it keeps displaying whatever option the user previously selected. The components are structured as shown below. When t ...

Angular5 causing all divs to have click events at once instead of individually triggered

I am a beginner when it comes to working with Angular and I have encountered an issue. I created a click event on a FAQ page in Angular 5, but the problem is that when I click on one FAQ, they all open up instead of just the targeted one. Here is my TypeS ...

Modify the HTML select tag to toggle from a selected checkbox

What should I do when a certain option is checked in the checkbox, and that label needs to be shown in the select tag? https://i.stack.imgur.com/ZxRNF.png Checkbox input <input type="checkbox" class="toggle-product pull-right" @if(!isset($restrictedPr ...

Issues with retrieving data from Firestore and storing it into an array in a React

Struggling to fetch data from my firestore and display it on the webpage. Despite trying all possible solutions and searching extensively, I am unable to get it working. When using the code below, nothing appears on the website. However, if I switch to th ...

Obtaining page information from a frame script in e10s-enabled Firefox: A guide

One of the challenges I'm facing is with my Firefox extension, where a function loads page information using the following code: var title = content.document.title; var url = content.document.location.href; However, with the implementation of multi- ...

How to reset a form in AngularJS using either HTML or a built-in directive

Within a standard modal popup in Bootstrap, I have implemented a form consisting of input fields, a submit button, a cancel button, and a close-icon. When selecting the name from an Object data-list using ng-repeat, the popup containing the form will displ ...

The useRoutes function is returning null despite the correct pathname being provided

Check out my React code snippet! I've got the Component nestled within a micro-frontend application, which is then brought into the main app using module federation. // embedded in my microfrontend. const path = '/another-component-path'; f ...

"Automatically insert a new row into the table if the cell loses focus and is not left

Can someone assist me with adding a table row dynamically when a cell is filled and the input focus is lost? My JavaScript skills are not strong. Here is a link to the form: JSFIDDLE <table class="table table-timesheet" ng-controller="TimesheetCtrl"> ...

Using Javascript to dynamically add variables to a form submission process

Looking to enhance my javascript skills, I've created a script that locates an existing id and exchanges it with a form. Inside this form, I'm aiming to incorporate javascript variables into the submit url. Unsure if this is feasible or if I&apo ...

Ways to retrieve the identifier of the uploaded document in GridFs for linking with another model

After creating a GridFS and uploading an image using the code snippet below: app.post("/upload", upload.single("photo"), function(req, res) { res.redirect("/images"); }) I also have a separate model for users: var userSchema = new mongoose.Schema({ ...

Using Bootstrap multiselect, you can easily control the display of a second menu based on the selection in the first menu

On my website, I am working with two menus. When I select Abon from the first menu, it should display all li elements under the Abon optgroup (Abon-1, Abon-2). If I uncheck block in the second menu, those elements should disappear. The code consists of Sel ...

Implementing Auto-complete Functionality with Tagify in C# ASP.Net using jQuery

I'm currently utilizing Tagify, a tool that utilizes jQuery Autocomplete, references : <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquer ...

How to Retrieve Superclass Fields in Angular 5 Component

I have a superclass that provides common functionality for components. export class AbstractComponent implements OnInit { public user: User; constructor(public http: HttpClient) { } ngOnInit(): void { this.http.get<User>(& ...

Assistance needed for disabled JavaScript

I'm currently working on a small application where I need to display some text wrapped in 3 divs. The goal is to only show one div at a time and provide users with prev and next buttons to switch between them. However, when JavaScript is disabled, I w ...

Is it possible to arrange two items in one column and the rest as columns in MaterialUI Grid?

I need help arranging my arrows in a MaterialUI grid where one points up and the other points down. How can I achieve this layout? Attached below is an image of my current setup and the desired outcome. Here is my code: <Paper className={classes.paper ...

Incorporating Recoil with React, a substantial array is experiencing lags due to numerous re-renders

I currently have an array of around 400 objects within my application. The hierarchy of components in my tree is structured as follows: App -> Page (using useRecoilState(ListAtom) for consumption) -> List -> Item (utilizing useSetRec ...

Ensure that the function .each() waits for the element to be converted to a DataURL

Utilizing html2canvas for the conversion of HTML elements into canvas images, I iterate through the HTML using .each to pass elements to html2canvas. Once an element is converted into a DataURL, it is added to an array called content. $('.itinerary- ...

Searching by multiple parameters in Angular.js

I have a script that scans through a field and highlights the words related to the search input. I want this script to not only filter by title, but also by name. How can I adjust the code to filter both the title and name when searching? <li ng-repeat ...

Vue Bootstrap Checkbox and <b-table> with <b-form-checkbox> components combine to provide a powerful and flexible user

I am currently implementing b-form-checkbox with b-table to fetch the selected module Ids. <b-table id="module-table" :items="list.modules" :fields="fields" :busy="isBusy"> <template slo ...