Interactive Animation with Three.js Curved Path

I am attempting to animate a 2D curve in Three.js gradually. Because I will require more than 4 control points, I have decided against using Bezier curves and instead opted for a SplineCurve.

When I check the position of geometry.vertices of my line, I notice that they are changing over time, but the geometry.attributes.position remains constant. Is it feasible to animate the line based on the curve animation? While I was able to achieve this with Bezier Curves, I'm struggling to find a solution with SplineCurve. Any assistance would be greatly appreciated. Below is my code:

Firstly, I create the line:


var curve = new THREE.SplineCurve( [
new THREE.Vector3( -10, 0, 10 ),
new THREE.Vector3( -5, 5, 5 ),
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 5, -5, 5 ),
new THREE.Vector3( 10, 0, 10 )
] );

var points = curve.getPoints( 50 );

var geometry = new THREE.BufferGeometry().setFromPoints( points );

var material = new THREE.LineBasicMaterial( { color : 0xff0000 } );

// Create the final object to add to the scene
curveObject = new THREE.Line( geometry, material );

scene.add( curveObject );

curveObject.curve = curve;

Next, I attempt to update it:


curveObject.curve.points[0].x += 1;

curveObject.geometry.vertices = curveObject.curve.getPoints( 50 );
curveObject.geometry.verticesNeedUpdate = true;
curveObject.geometry.attributes.needsUpdate = true;

Answer №1

Here is a way you can accomplish it:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, 1, 1, 1000);
camera.position.set(8, 13, 25);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
var canvas = renderer.domElement;
document.body.appendChild(canvas);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

scene.add(new THREE.GridHelper(20, 40));

var curve = new THREE.CatmullRomCurve3([
  new THREE.Vector3(-10, 0, 10),
  new THREE.Vector3(-5, 5, 5),
  new THREE.Vector3(0, 0, 0),
  new THREE.Vector3(5, -5, 5),
  new THREE.Vector3(10, 0, 10)
]);

var points = curve.getPoints(50);

var geometry = new THREE.BufferGeometry().setFromPoints(points);

var material = new THREE.LineBasicMaterial({
  color: 0x00ffff
});

var curveObject = new THREE.Line(geometry, material);

scene.add(curveObject);

var clock = new THREE.Clock();
var time = 0;

render();

function resize(renderer) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}

function render() {
  if (resize(renderer)) {
    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    camera.updateProjectionMatrix();
  }
  renderer.render(scene, camera);

  time += clock.getDelta();

  curve.points[1].y = Math.sin(time) * 2.5;

  geometry = new THREE.BufferGeometry().setFromPoints(curve.getPoints(50));

  curveObject.geometry.dispose();
  curveObject.geometry = geometry;


  requestAnimationFrame(render);
}
html,
body {
  height: 100%;
  margin: 0;
  overflow: hidden;
}

canvas {
  width: 100%;
  height: 100%;
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

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

TRPC fails to respond to the passed configuration or variables (e.g., when enabled is set to false)

Recently started using trpc and I'm trying to grasp how to utilize useQuery (which I've previously worked with in react-query): const IndexPage = () => { const { isLoading, data, isIdle } = trpc.useQuery([ "subscriber.add", { email: ...

"Make sure to always check for the 'hook' before running any tests - if there's an issue, be sure

before(function (func: (...args: any[]) => any) { app = express(); // setting up the environment sandbox = sinon.createSandbox(); // stubbing sandbox.stub(app, "post").callsFake(() => { return Promise.resolve("send a post"); }); ...

MongoDB has encountered an error while attempting to combine two disparate conditions

I need to run a MongoDB query using JavaScript. Specifically, I am looking to retrieve documents based on two different criteria. The first condition is as follows: $or: [ { "users.username": user.username }, { buyer: ...

Using Leaflet JS to add custom external controls to your map

Is there a way to implement external controls for zooming in on an image? I've searched through the documentation, but haven't been able to find a clear solution. HTML: <div id="image-map"></div> <button id="plus">+</butto ...

Adding a <tr> tag to an HTML table using JQuery and AJAX in the context of Django framework step by step

I am currently navigating the world of Javascript, Jquery, and Ajax requests and I'm encountering a challenge with how my scripts are executing. My homepage contains a lengthy list of items (over 1200) that need to be displayed. Previously, I loaded ...

Display my additional HTML content on the current page

Is it possible for my addon to open a predefined html page in the current window when it is started? And if so, how can this be achieved? Currently, I am able to open my addon page in a new window using the following command: bridge.boot = function() { ...

My program contains redundant sections that are being repeated multiple times, and I am unsure of how to remedy this issue

This particular payment gateway relies on a paid market for processing transactions. Unfortunately, there seems to be an issue where multiple error messages are being triggered during the payment verification process. The errors include: ❌ | An error h ...

Locate all instances of words that begin with a certain character and are immediately followed by numbers within

I am searching for words that start with "mc" and are followed by digits only. let myString = "hi mc1001 hello mc1002 mc1003 mc1004 mc mca"; Expected output = [mc1001, mc1002, mc1003, mc1004] This is how I tackled it: const myRegEx = /(?:^|\s)mc(. ...

Executing SQL queries in JavaScript using PHP functions

Is it allowed, or is it a good practice? It worked for me, but what issues might I face in the future? Just to clarify, I am new to PHP scripting. // button <button type="button" class="btn btn-primary" id="Submit-button" >Save changes</button> ...

Achieving successful implementation of SSAO shader on SkinnedMesh models

Trying to implement the SSAO post-processing shader with the most recent version (r77) of three.js has been a challenge for me. I have been utilizing the EffectComposer, with the code completely replicated from the example page provided here: The specific ...

Develop a custom dropdown menu using JavaScript

I've been working on creating a dropdown menu that appears after selecting an option from another dropdown menu. Here's the HTML code I'm using: <br> <select id ="select-container" onchange="addSelect('select-container') ...

What is the best way to achieve a Clamp-To-Border effect on a Texture loaded onto an Image in the THREE.js?

My scene includes a plane with an image loaded onto the texture. I've found that there is no Clamp-To-Border option for textures, only Clamp-To-Edge, Repeat Wrapping, and Mirrored Wrapping. Below is an image displaying the default ClampToEdge effect. ...

jQuery if statement appears to be malfunctioning

When the condition operates alone, everything works fine. However, when I introduce an 'and' operation, it does not function correctly. If only one of them is true, the code works. It also successfully takes input values. <!DOCTYPE HTML Code ...

Strip away the HTML tags and remove any text formatting

How can I effectively remove HTML tags and replace newlines with spaces within text? The current pattern I am using is not ideal as it adds extra space between words. Any suggestions on how to improve this pattern? replace(/(&nbsp;|<([^>]+)> ...

What is the best way to import two components with the same name from different libraries?

How can I import the Tooltip component from two different libraries without encountering naming conflicts? For example: import { Tooltip as LeafletTooltip } from "react-leaflet"; import { Tooltip as RechartsTooltip } from "recharts"; By renaming the impo ...

Ways to expand the constructor function of the THREE.Mesh class

Exploring Three.js, I'm working on creating a basic model of the solar system. My current task involves building constructor functions for planets and moons. However, I keep encountering an error message: The function setShadow() is not recognized. ...

What is causing the error to occur during the installation of the NestJS Client?

Encountered an error while attempting to install the nestjs client, and I'm completely puzzled by this issue. PS C:\Users\meuser> npm i -g @nestjs/cli npm ERR! code ETARGET npm ERR! notarget No matching version found for @angular- ...

Redirect to a new URL using $routeProvider's resolve feature

Currently, I am in the process of developing an application that includes the following endpoint: .when('/service/:id?', { templateUrl: 'views/service.html', controller: 'ServiceCtrl', resolve: { service: fu ...

Building a navigation system with previous and next buttons by implementing JavaScript

I am currently working with AngularJS and I have data that is being received in the form of an array containing two objects. As a newcomer, I am still trying to figure this out. data[ { "something":"something1", "something":"something1", "something":"some ...

In my experience, I have encountered issues with certain routes not functioning properly within Express

I am currently working on developing a tic-tac-toe game and looking to store user data in a database. However, I am facing an issue with the router I intended to use for this purpose as it is returning an 'Internal server error message (500)'. B ...