Issue with AnimeJS Motion Path causing element to deviate from desired SVG path

I'm attempting to use an SVG element and the AnimeJS library to make the orange marker follow the course of this RC car race track.

https://i.stack.imgur.com/8FKHC.png

Despite my efforts, I am encountering strange and undesirable outcomes.

At times, I observe the marker following a path that is offset from the course and not in the correct scale. Other times, although the marker is moving, it is not visible but I can see the scrollbars on my page adjusting, indicating its presence and movement.

When inspecting the browser's developer tools, I notice rapid changes in the element's styles - translateX, translateY, and rotate.

The code given shows the marker in motion. In the JSFiddle demo, if you carefully watch and wait for 9.49 seconds for each lap to complete, you may catch a brief glimpse of an orange ball which appears disconnected from the track and not correctly scaled.

What could be causing these issues? How can this functionality be achieved successfully? I am open to exploring alternative libraries or tools to accomplish this task.

JSFiddle

HTML

<section id="race-event-overview">
    [...]
    <div class="race-track-map">
        <svg class="race-track" viewBox="0 0 560 350" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"
            stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5">
            <path class="track"
                d="M648.018 1019s-26.755-194 194-194H2618.98c220.76 0 194 194 194 194v527h-.24s10.84 139-112.49 139-112.49-139-112.49-139h-.24v-286s11.83-148-109.52-148H1413s-81-1.45-81 111c0 0-11.07 108 127... 
                
        </svg>
    </div>
</section>

SCSS:

#race-event-overview {
    position: relative;
    height: 500px;
    background: #242D33;

    .race-track-map {
        position: absolute;
        top: 75px;
        right: 0;

        svg {
            height: 350px;
            width: 560px;
        }
    }
}

JS:

var path = anime.path('.race-track .track');

anime({
    targets: '.race-track .ball',
    translateX: path('x'),
    translateY: path('y'),
    rotate: path('angle'),
    easing: 'linear',
    duration: 9490,
    loop: true
});

Answer №1

It seems like I may be a bit late to provide assistance for your needs, however:

In summary

The main issue lies in the fact that the transform origin behaves unpredictably in SVGs, and anime.js offers a straightforward solution. To resolve this problem, reposition the animated object (the circle) with attributes cx="0" and cy="0", and eliminate any transformations on the path.

Further details

A very informative article discussing SVG transforms can be found on CSS Tricks. The key takeaway is that all elements within an svg element have their transform origins at the upper left corner of the svg element.

When examining the transformations applied by anime.js to the animated element, you will notice they correspond directly to the values in the path's d attribute. These values represent distances in pixels from the origin (once again, the upper left corner of the svg element), but discrepancies arise when transformations are present. Feel free to explore Removing transforms in SVG files

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

Allow the javascript callback function to complete before proceeding

Utilizing the Google Storage API, I am saving a file in a GCP bucket within an asynchronous function. My objective is to wait until I receive an error or success callback before proceeding with the subsequent lines of code. However, I am encountering the i ...

I am looking to set an HTML file as the homepage for my Next.js project

Is there a way in next.js to render a normal .html file (index.html) when someone visits my root directory at "https://example.com/"? I have researched and edited my config file as shown below, /** @type {import('next').NextConfig} */ const next ...

Ways to add a line break within JavaScript code

I am currently developing a bot for my Discord server and working on logging messages to a text file. All the necessary information about the message is stored in a variable named logger, and I am using Node.js to append my log file. When attempting to ad ...

angular-recaptcha: Adjusting language based on the website's language update

My website offers three different languages that users can switch between. The language switch functionality is implemented on the client side using JavaScript (AngularJS). I have integrated reCAPTCHA 2 into my website and now I need to update the languag ...

Voice crashes in Discord.js after the audio has been playing for a short while

Every time I try to play a song, the bot crashes and gives an "aborted" error message after about a minute. music = { "resource": createAudioResource(ytdl(parameters[0], {filter: "audioonly"}), {inputType: StreamType.Arbit ...

The function Mediarecorder.start() is experiencing issues on Firefox for Android and is not functioning

Recently, I've been facing a peculiar issue while developing a web application. The purpose of this app is to capture about 10 seconds of video intermittently from the device webcam and then upload it to a server. For this functionality, I utilized th ...

What is the best way to compare two arrays of objects and then append a new key to the objects in the second array?

Consider the following arrays where you are tasked with comparing them and returning a filtered version of array two containing elements found in array one: const array1 = [ { name: "Jack", age: 54, title: "IT Engineer" }, { na ...

"Converting a database table record into a JavaScript array: Step-by-step guide

I'm currently expanding my knowledge of PHP by working on a small project. Within my database, I have a table called city_name which consists of columns for id, name, longitude, and latitude. Typically, this table contains around 10-15 rows. When a us ...

What are some ways to utilize CSS variables for enhancing component styles within Svelte?

Presented here is a straightforward component called Text.svelte. It utilizes a CSS variable to prevent unnecessary duplication: <div> <span class="t1">t1</span> <span class="t2">t2</span> </div> ...

Selecting an option from dropdown1 to retrieve a specific value from a JSON file

I currently have 2 dropdown lists to fill with data from a JSON file: $scope.categories = [ {name:"Blouse", sizes:["36","38","40","42","44","46","48","50"]}, {name:"Shirt", sizes:["36","38","40","42","44","46","48","50"]}, {name:"Pants", size ...

Press the AngularJS button using just JavaScript and the element

I've been developing a browser extension that automatically clicks buttons on web pages, but I've run into an issue with sites using AngularJS. The code functions properly on most websites except for those built with AngularJS. Below is the snip ...

Property '{}' is not defined in type - Angular version 9.1.1

Currently, I am working with Angular CLI version 9.1.1 and I am attempting to update certain data without updating all of it. form: UserInfo = {adresse : {}}; UserInfo.interface export interface UserInfo { id_user: string; username: string; em ...

The process of altering the color of a table row in JavaScript can be done after dismissing a pop-up that was triggered by a button within the same row

I am tasked with changing the color of a specific table row based on user interaction. The table consists of multiple rows, each containing a button or image. When the user clicks on one of these buttons or images, a popup appears. Upon successful data sub ...

Unable to generate a navigation panel using HTML/CSS and jQuery

I recently completed the basic courses in HTML/CSS, JavaScript, jQuery, and PHP on Codecademy. I'm currently working on creating a website using HTML/CSS and jQuery in Codecademy's codebits. However, I'm facing some issues with my navigation ...

Combine two events in jQuery using the AND operator

Can I create a condition where two events are bound by an AND logic operator, requiring both to be active in order for a function to be called? Let's say you have something like this: foobar.bind("foo AND bar", barfunc); function barfunc(e) { al ...

I want to use Angular and TypeScript to play a base64 encoded MP3 file

I am attempting to play a base64 encoded mp3 file in an Angular application. I have a byteArray that I convert to base64, and it seems like the byte array is not corrupted because when I convert it and paste the base64 string on StackBlitz https://stackbli ...

What is the best way to stack several items vertically beside an image?

As a beginner in the world of web development, I recently embarked on my first project. However, I am facing an issue where I cannot align multiple elements under each other next to an image. One element floats at the top beside the image, while the other ...

Exploring how to replicate background-size: cover with a center position using HTML5's <video> tag

Looking to replicate the effect of background-size: cover on a <video> element. I was able to achieve this with the code below: <video id="videobackground" autoplay="true" loop="true"> <source src="BackgroundFinal2.mp4" type="video/mp4" ...

Tips for utilizing JSON.parse

Within my ajax request, I am encountering the following code: 403: function(jqXHR) { var error = jqXHR.responseText; console.log(error); } When this error occurs, a message is displayed in the console: Htt ...

Styling Page Titles with CSS Content

I'm having trouble including the page title in the footer of all printed pages. I've tried using the following code snippet: @page { @bottom-right { content: attr(title); } } However, this method doesn't seem to be working for me. ...