Top method for creating consecutive Canvas animations using Javascript

Currently, I am working on animating a canvas element (specifically PaperJs Path/Text) along a path using PaperJs. The process involves user-created frames containing paths drawn by the user, where each frame consists of multiple paths and corresponding canvas elements stored in arrays called text and paths respectively. The existing code executes for each frame but has limitations in terms of functionalities like pause, skip to next/back a frame, play frame, and variable speed. The current code snippet provided below attempts to animate these frames sequentially by limiting each frame's visibility to 2 seconds:


var offset = [];

for(let i = 0; i < paths.length; i++) {
  offset[i] = 0;
}
var time_sec = 2;   
for(let i = 0; i < paths.length; i++) {
    text[i].onFrame = function(event) {
        var speed = paths[i].length / time_sec;
        if ((event.time > frame_num * 2) && (event.time < ((frame_num * 2) + 2))) {
            text[i].fillColor = "black";          
            if (offset[i] < paths[i].length){
                text[i].position = paths[i].getPointAt(offset[i]);
                offset[i] += event.delta * speed; // speed - 150px/second
             } else {
                offset[i] = paths[i].length;
             }
        } else {
            text[i].fillColor = new paper.Color(0.5, 0);
        }
    paper.view.draw();
  }
}

I have explored adding wait times between calling animate_frame without success, as the onFrame() function from PaperJS does not execute during this waiting period. Additionally, implementing flags and while loops did not yield desired results either.

Considering my constraints with PaperJs, I am seeking alternative approaches that involve creating an animation object containing paths and canvas elements, which can be triggered by calling animation.play(). This method should also allow for waiting until a previous animation completes, enabling the sequential animation of frames. Although I am committed to using PaperJs for this project, I am open to transferring path position data to a regular JS array or exploring other packages that could align with my requirements.

Your input and ideas are highly appreciated! Thank you.

Answer №1

When it comes to handling complex animation scenarios, my recommendation would be to utilize a specialized animation library. This will simplify the process and provide more control over your animations.
One option that stands out is GSAP, which can greatly assist with tasks like play/pause functionality.

If you're interested, here's a straightforward demo showcasing how GSAP can be used to manage a Paper.js animation.

You should be able to customize this approach to fit your specific requirements.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Debug Paper.js</title>
    <script src="https://unpkg.com/acorn"></script>
    <script src="https://unpkg.com/paper"></script>
    <script src="https://unpkg.com/gsap"></script>
    <style>
        html,
        body {
            margin   : 0;
            overflow : hidden;
            height   : 100%;
        }

        canvas[resize] {
            width  : 100%;
            height : 100%;
        }

        #buttons {
            position : fixed;
            top      : 50px;
            left     : 50px;
            display  : flex;
            gap      : 15px;
        }
    </style>
</head>
<body>
<div id="buttons">
    <button id="play">play</button>
    <button id="pause">pause</button>
    <button id="reverse">reverse</button>
</div>
<canvas id="canvas" resize></canvas>
<script>
    paper.setup('canvas');

    const initialPosition = paper.view.center;

    const circle = new paper.Path.Circle({
        center: initialPosition,
        radius: 50,
        fillColor: 'orange'
    });

    function update(t) {
        circle.position = initialPosition.add([t * 100, 0]);
    }

    const obj = { value: 0 };
    var timeLine = gsap.timeline({
        onUpdate: (event) => {
            update(obj.value);
        }
    });
    timeLine.to(obj, { value: 1, duration: 1 });
    timeLine.pause();

    document.querySelector('#play').addEventListener('click', () => timeLine.play());
    document.querySelector('#pause').addEventListener('click', () => timeLine.pause());
    document.querySelector('#reverse').addEventListener('click', () => timeLine.reverse());
</script>
</body>
</html>

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 there a way to export a specific portion of a destructuring assignment?

const { a, ...rest } = { a: 1, b: 2, c: 3 }; If I want to export only the rest object in TypeScript, how can I achieve that? ...

Is there a way to automatically initiate the download of a file (such as a PDF) when a webpage loads?

Currently, my objective is to have a form on a webpage that, once filled out by a user, redirects them to a thank you page where a message of gratitude is displayed. What I aim to accomplish is for a PDF file to automatically start downloading as soon as t ...

Encountering a connection reset error (ECONNRESET) during npm installation when working behind a

While attempting to install packages using npm, I encountered an error message as shown below: [![Error Message][1]][1] After researching, I discovered that the issue was related to a connectivity problem with https://registry.npmjs.org/ Despite my atte ...

Transformation of CSS classes in React with Webpack

Have you ever noticed that when you inspect the Airbnb website, the classnames appear to be morphed into single alphanumeric names? What is the name of this technique and is it applied at the code level or build level? https://i.sstatic.net/qSiaj.jpg ...

Managing automatic page redirects in Ajax requests

For the past two days, I have been encountering a challenging issue with my Laravel application that is hosted on Heroku server. The app allows file uploads through an ajax request, displaying upload progress on the page and returning JSON response upon co ...

How can jQuery be used to determine if the number of checked checkboxes is a multiple of three?

Within the ul, I have li tags with checkboxes and I want to create a function that checks, when the submit button is pressed, if the number of checked checkboxes is not a multiple of 3. If it isn't, an alert should be displayed. How can I accomplish t ...

What causes the input field to lose focus in React after typing a character?

Currently utilizing React Mui for components and encountering no errors in either the Chrome inspector or terminal. How can this be resolved? No error notifications are being displayed by eslint or Chrome Inspector. The form submission functions correctl ...

How can a JavaScript function communicate with a code behind method?

Currently, I am trying to implement a JavaScript function for an HTML img click event on an aspx page. Additionally, there is a server method in the code behind page that I need to call from the JavaScript function without any parameters whenever the user ...

Activate the textbox without utilizing `.focus()` method

I am encountering an issue with a small iframe on my page. The content within the iframe is larger than the window itself, requiring users to scroll around to view it in its entirety. Within this iframe, there is a button that, when clicked, triggers an an ...

Is it possible to have a div set to close upon loading the page?

Is there a way to have the toggle function set up so that when the page loads, the div being toggled starts out closed? I don't want them to be visible until clicked on. Best regards, Joey <script type="text/javascript> $(document ...

Utilize React-markdown to interpret subscript text in markdown format

I tried to create subscript text in an .md file using the following syntax: x_i x~i~ Unfortunately, react-markdown did not interpret this as subscript. After some research, I discovered the package remark-sub-super and implemented it with the plugin ...

Pick the item when the checkbox is selected

I am currently attempting to toggle the visibility of a select element based on whether a checkbox is checked or not, but it doesn't seem to be working as expected. My desired functionality is for the select element to be hidden upon page load and th ...

Searching for and replacing text that spans across multiple nodes in HTML can be accomplished using C# programming language

Here is the HTML code to consider. The term 'response' was modified to 'reason', by removing 'sp' (<del> tag) and adding 'as' (<ins> tag), while also removing 'se' (<del> tag). <div &g ...

Unhook, add at the beginning, and set requirements jQuery

There are two clickable div elements that can switch classes when clicked. If the first one contains "1", it will be given a class of "active". If the second one contains "2", it will have the class "active" while removing the class from the first one. &l ...

Error event triggered by Ajax call despite receiving 200 ok response

$.ajax({ url: 'http://intern-dev01:50231/api/language', type: 'GET', dataType: 'json', success: function() { console.log('Success! The call is functioning.'); }, ...

JQuery's .each method is executed prior to making an Ajax request

I am currently working on a JavaScript (jQuery) function that loops through input elements in a form, builds an array to convert into a JSON string, and then sends it to an AJAX endpoint. However, I am facing an issue where the loop runs after the AJAX cal ...

State in Vuex is failing to update effectively when actions are being utilized

I'm trying to wrap my head around VueX, but I'm having trouble getting Axios to work with it. In my store.js file, I have the following setup: state: { cards: [], currentPage: 1, lastPage: 2, }, actions: { loadGradients(page ...

Scrollbar becomes inactive following the loading of AJAX content

Having an issue with loading a div using Ajax. The div loads, however the scrollbar within it stops working afterwards. In Main.html, I load content from other HTML files like so: <div id="content1" > </div> The content is loaded as follows: ...

Making a call to Ajax while specifying the contentType as 'application/json'

After some troubleshooting, I discovered that removing the content-Type works fine. However, the jsonitem received on the PHP side is showing syntax errors. From my research, it seems like specifying the content type when sending Json objects is crucial. ...

Please explain this ES6 syntax to me: Using a colon after a function call

While exploring the documentation for a flux store in React, I came across an example that caught my attention. import {ReduceStore} from 'flux/utils'; class CounterStore extends ReduceStore<number> { getInitialState(): number { ret ...