# How to create a simple dynamically expanding rectangle geometry

Hi,

I want to create a simple rectangle geometry that can dynamically expand. To be exact:

• The geometry must expand its height over time (e.g. while the user presses a certain key)
• The geometry needs to have rounded corners with a fixed radius
• The final mesh needs to have an n-pixel wide border (like the black line in the example below)
• 2D only

As I’m still a beginner ( ), I was searching the web and this forum for possible solutions but I’m still uncertain which approach is the correct one. I made a small prototype using `THREE.Shape` (see below) but with that approach, I’ve no guess how I can expand this shape in its height over time without completely recreating it over and over again (which sounds performance-wise not like a good idea or?). Initially, I was using simple plane geometries and used the mesh `scale` function to expand it but with this variant, I didn’t know how to create the round corners. Somewhere I was reading about using morph targets for such kind of animations but I didn’t test it yet. The name `morph target` implies to me somehow that I need to know the target height in advance but as it expands over time I don’t know the “final” height.

Any input or examples would be very helpful!

``````function roundedRect(x, y, width, height, radius) {
const shape = new THREE.Shape();
shape.lineTo(x, y + height - radius);
shape.lineTo(x + width - radius, y + height);
x + width,
y + height,
x + width,
);
shape.lineTo(x + width, y + radius);
return shape;
}
``````

You can create a self defined indexed BufferGeometry and then position the vertices as time dependent as you like.

https://threejs.org/docs/index.html#api/en/core/BufferGeometry

From these examples you might be able to use parts.

https://hofk.de/main/discourse.threejs/2017/index2017.html

https://hofk.de/main/discourse.threejs/2017/Round-edged%20box%203/Round-edged%20box%203.html

https://hofk.de/main/discourse.threejs/2017/Round-edged%20box%202/Round-edged%20box%202.html

https://hofk.de/main/discourse.threejs/2019/ShapeWithOutline/ShapeWithOutline.html

https://hofk.de/main/threejs/sandboxthreeg/MagicBoxTHREEg.html example No. 7, 15 are dynamic

A code snippet from my program where the verices are updated.
Beforehand you calculate the coordinates as desired.

``````g.faceIndices = new Uint32Array( faceCount * 3 );
g.vertices = new Float32Array( vertexCount * 3 );

g.setIndex( new THREE.BufferAttribute( g.faceIndices, 1 ) );
g.setAttribute( 'position', new THREE.BufferAttribute( g.vertices, 3 ).setDynamic( true ) );
``````

``````	function xyzSet( x, y, z ) {

posIdx = vIdx * 3; // (vIdx vertex index)

g.vertices[ posIdx ]  = x;		// set vertex position
g.vertices[ posIdx + 1 ]  = y;
g.vertices[ posIdx + 2 ]  = z;

}

g.attributes.position.needsUpdate = true;
g.attributes.normal.needsUpdate = true;
``````

Wow, thanks a lot for all the links and the example I’ll give the indexed BufferGeometry a try and let you know if I had success or got stuck at some point

Ok, one more question regarding the BufferGeometry:

Basically I’ve to create a geometry that looks like the following or? Is there a simple method to generate this circle geometries? I don’t want to implement that on my own… Seems like it’s possible to merge a plane geometry with a circle geometry but in that case, I’d lose the vertex indexes (red dots) which I need for my transformation or?

(sorry for the bad quality )

A mixture of techniques in such a simple example does not seem reasonable.

The calculation of the points is quite elementary.
circle see e.g. https://www.mathopenref.com/coordparamcircle.html

In a loop with the number of passes corresponding to the desired fineness of the arcs, the points of the quarter circles are calculated. With a function where the start angle is used as a parameter.

If you use appropriate variables, you can easily realize the change of shape.

For the thick border you may be able to use this method (@Mugen87) ?

See https://hofk.de/main/discourse.threejs/2020/index2020.html
nearly at the bottom.

The principle from this topic is applicable in this case: Cheap round-edged box (vertex shader)
And it’s even simpler, as there’s no need to compute normals in shaders.

A little update from my side. I’ve managed to create a custom geometry that I can resize dynamically in its width/height but keeps a constant corner radius. Basically, I just translate the corners and scale the rectangles.

Implementing the resize logic took me a while and code-wise it’s more than 400+ lines (complete geometry with resize logic). Even if you could do in the half amount of code, it still feels like a huge overhead to maintain. Let’s see how it feels like to use a simple plane geometry instead and apply a vertex shader as recommended by @prisoner849