Adding Borders to Your Text Objects in ThreeJS

Using TextGeometry in Threejs to generate custom text,

    const font = await loadFont(fontUrl)
    const geometry = new TextGeometry("文字", {
        font: font,
        size: size,
        depth: 10,
        bevelEnabled: false,
        bevelThickness: 1,
        bevelSize: 1,
        bevelOffset: 0,
        bevelSegments: 0
    })
    const material = new THREE.MeshStandardMaterial({
        color: color
    })
   

    const mesh = new THREE.Mesh(geometry, material)

would like to incorporate a border around the text like this:

desired effect

The original blue text will have a red border surrounding it.

Consider using the troika-three-text library for text rendering. It provides great functionality but may lack support for text depth.

Answer №1

You have the ability to create texture and develop material for this specific object using texture: check out the outcome on codepen.io

  1. Adjust the text geometry UV (because it is slightly odd and not within [0...1] bounds)
function flatUVbyXY(geometry) {
    if ( !(geometry.boundingBox instanceof THREE.Box3) ) {
        geometry.computeBoundingBox()
    }
    const bb = geometry.boundingBox.clone()
    const delta = new THREE.Vector3().subVectors(bb.max,bb.min)

    for (let i = 0,j = 0; i < geometry.attributes.position.array.length; i+=3, j+=2) {
        geometry.attributes.uv.array[j  ] = (geometry.attributes.position.array[i  ]-bb.min.x)/delta.x
        geometry.attributes.uv.array[j+1] = (geometry.attributes.position.array[i+1]-bb.min.y)/delta.y
    }
    geometry.attributes.uv.needsUpdate = true;
}
//flatUVbyXY(geometry)
//or
//flatUVbyXY(mesh.geometry)
  1. Make a texture with:
    2.1 Establish a scene with only text where border addition is required and an OrthographicCamera that focuses solely on the text object
    2.2 Render it and acquire the result as a texture
    2.3 Apply this texture onto a plane and render it using shaderMaterial which will incorporate the border with desired width (width specified in 3D space units)
    2.4 (optional) Implement an update function that can modify the texture with a new border width without repeating the whole process again (as certain parts do not need repeated work)
function makeFlatBorder(geometry,borderWidth=5,fontColor=0x0000ff,borderColor=0xffff00,pxYSize = 200,canvas=document.createElement('canvas')) {
    // Function implementation details continue here...
}

Furthermore, you are able to choose edges type in GLSL shader (uncomment what suits your requirement)

float dist = distance(pos*u_delta.xy,newPos*u_delta.xy);                       // rounded edges
// float dist = abs(pos.x-newPos.x)*u_delta.x + abs(pos.y-newPos.y)*u_delta.y; // sharp edges

Lastly:

// JavaScript implementation lines follow...

result: see the final output on codepen.io https://i.sstatic.net/UmuKssGE.png

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 React-Table display only the items that were not filtered out?

Is it possible to achieve a React-Table with multi-select functionality that doesn't rely on a select box but allows the user to simply click on a row? Additionally, instead of adding clicked rows to the state, how can we filter them out and re-render ...

What is the most efficient way to transfer a large volume of documents from mongoDB using http?

I'm dealing with a large mongoDB database that contains millions of documents and I need to fetch them all at once without crashing or encountering cursor errors. My goal is to send this data over http using express in nodeJS. The collection contains ...

The synergy between HTML forms and Javascript

Is there a way to input a URL in a form and have it redirect to a different URL while keeping the original parameters? For example, if I enter , can it redirect to https://www.google.com/search?q=somequery? I believe this functionality can be achieved usi ...

Issue with FullPageJS: scrollOverflow feature not functioning upon click event

I am currently working on a Fullpage.js instance that needs to be initialized with a click event and then destroyed when switching to another page, and vice versa. The scrollOverflow feature works perfectly as long as the #fullpage element is not hidden up ...

Implementing sliders for interactive functionality with an HTML table

I need to implement sorting and sliding features on an HTML table using jQuery. Sorting has already been achieved by utilizing the DataTable.js jQuery library. The challenge now is to incorporate a slider into the table, with all subject columns being scro ...

issue with AngularJS custom blur functionality not functioning as expected

I have been attempting to set up notifications similar to this example: http://plnkr.co/edit/GbFioFDNb2OC4ZjARQTp?p=preview However, I have been unable to integrate it into my script successfully. When I click outside the notification box, nothing happen ...

Avoiding node_modules in Webpack 2 with babel-loader

After updating to Webpack 2, I've run into an issue with the "exclude" property in my "rules". It seems I can no longer pass "exclude" into "options". What is the correct approach to handling this now? Previously: { test: /\.js$/, loader: ...

Locate and extract the JSON object using the specified key-value pair

Trying to extract a specific object from a complex json file, noting the key, and then returning a new json poses a challenge. I am using expressjs as the backend for this task. Sample.json '[{"ServID":"Rai 1","Parametri" ...

What is the reason for not receiving a JSON object in the response from my personal node.js/express server?

-- Exploring a New Challenge -- I am currently working on creating an e-form signup for a client as part of our business marketing strategy service. The form design is complete and looks excellent. Now, I need to connect it to the existing API that our bu ...

Filtering an array of map/key pairs can be done by using various methods to

I am searching for individuals above the age of 21. const people = [ {0: {name: 'john', age: 30}}, {1: {name: 'jay', age: 33}}, {2: {name: 'cris', age: 18}} ]; The code snippet provided below did not produce an ...

Display solely the initial row in the tbody segment of a table. Is there a method to obscure subsequent 1st rows?

The initial row of each tbody acts as the row header, containing the column names. Subsequent rows in each tbody are unnecessary and should be hidden. Classes utilized: toprowHeader = first row containing column names recordsRow = holds additional recor ...

Struggling with synchronicity in javascript(node.js) and seeking assistance

I am faced with a challenge in my express.js app where I need to execute a script on the server, followed by running a couple of functions to derive some values. The process should be sequential, but I am running into issues as JavaScript seems to move on ...

Accept only numerical values, addition and subtraction symbols, commas, the F5 key, and various other characters

I want to restrict key strokes to only numbers (including those on the numpad), minus (-) and plus (+) signs, and commas (,). Currently, it types twice when I input a number (e.g. 2 is displayed as 22) and replaces the current value with the new number. F ...

HTML5 Canvas with Transparent Color Feature

I have created a basic Pong game using Javascript and the Canvas element. To allow the background image of the div tag to show through the canvas, I set the background color of the canvas to be transparent. However, I encountered an issue where the ball ...

Modifying the color scheme of elements in a circular pattern with an array

I am faced with a unique challenge that is proving to be quite troublesome for me, as I struggle to figure out the solution. Currently, I have 5 items at hand: 4 divs each with a width and height of 50px, and the body element. My goal is to create a func ...

The top scrolling behavior on click applies exclusively to the first set of Bootstrap 5 tabs

I am experiencing an issue with my HTML webpage that contains multiple BS5 Nav Tabs. The first tab is not functioning properly, while all the other tabs are working smoothly. When I click on the first BS5 Nav Tab, the page scrolls to the top with the addre ...

What kind of error should be expected in a Next.js API route handler?

Recently, I encountered an issue with my API route handler: import { NextRequest, NextResponse } from "next/server"; import dbConnect from "@/lib/dbConnect"; import User from "@/models/User"; interface ErrorMessage { mess ...

Implementing pagination in Firestore using React-Redux

I'm currently working on implementing pagination with Firebase and React Redux Toolkit. I've grasped the logic behind it, but I'm facing challenges when integrating it with Redux. Initially, my approach was to store the last document in the ...

How can I transform my jQuery code into a React Component?

When it comes to updating the CSS of an element in React, I initially turned to jQuery but later discovered that is not recommended. So now I am seeking guidance on how to achieve this task properly without using jQuery. If necessary, I can provide additi ...

import shaders from next.js

In my web app built with next.js, I am utilizing WebGL to render a 2D scene. Currently, I have my fragment and vertex shaders hardcoded as strings in my JavaScript: var fragmentShaderSource = [ ` #ifdef GL_ES`, `precision highp float;`, ` #en ...