JavaScript implementation for text smearing visual effect

While I have a strong understanding of Javascript, I haven't explored its advanced graphics features like canvas, webGL, and three.js. I'm interested in creating a distortion effect similar to the one on this website, but instead of applying it to an image, I want to use it with text. Essentially, I envision having plain HTML text that appears normal at first, but when a user hovers over it, the text will warp, bend, or smear in response.

After some research, I came across two Stack Overflow posts that touch on what I want to achieve. The first post is too basic for my needs, as I desire more complex transformations such as warping and bending rather than simple shifts. The second post seems promising since it involves using Three.js, but I am seeking a 2D solution and want to manipulate the actual shape of the text, not just rotate it around an axis.

I'm curious about how to implement this effect, if there's a specific name for it (as I've struggled to find examples), any recommended examples or advice. Any assistance would be greatly appreciated! Thank you!

Answer №1

There are numerous possibilities to explore.

An illustration of a basic WEBGL 2D texture rendered on a standard 2D canvas is provided here. Some boilerplate code is included for mouse, canvas, and webGL functions, which you can dissect at your own pace.

The special effect is generated in the Fragment Shader. Instead of adjusting the texture coordinates, I overlaid a 2D vector field onto the image (essentially improvising as I went along). These vectors modify the pixel lookup from the texture. The amount, controlled by moving the mouse up and down, dictates the intensity of the effect. Moving the mouse from left to right alters the Phase setting.

Moving the mouse to the top of the image decreases the effect intensity. At the bottom right corner, it reaches its maximum level.

The function webGLRender at the end configures the values for the fragment shader and renders the webGL then 2D context using drawImage for display on the canvas. The Fragment shader is positioned above this section.

Since the webGL image is rendered via ctx.draw2D, resizing is easy and makes the webGL render resolution independent. If there are performance issues (particularly with high-resolution images), consider reducing the input image size.

Note that WebGL cannot render images from different domains (tainted) unlike 2D canvas. WebGL requires access to pixel data for drawing textures, so tainted images will trigger security errors. In this case, a 2D canvas was used instead of an image because a suitable untainted image could not be located.

// Boilerplate code
const U = undefined;const RESIZE_DEBOUNCE_TIME = 100;
// Additional JavaScript code here...

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

trouble encountered when attempting to integrate typeahead functionality in AngularJS using jQuery

Greetings! I am brand new to using AngularJS and currently exploring the implementation of typeahead functionality. I decided to utilize an existing library by including the following script: <script src="lib/xyz/typeahead.bundle.js"></script> ...

checkbox toggling event triggering twice

I have been working on an application that allows users to register for university courses. They can select their registration type, course type, batch, and subjects. The subjects are displayed in a table based on the selected course type and batch. Users ...

Angular-template static functions refer to functions that do not require an

Our project utilizes the linting-config provided by AirBnB. There is a rule that stipulates class methods must utilize this or be declared as static. While this rule theoretically makes sense, it seems to present challenges within an angular context. Consi ...

Stopping the spread of popup alerts: A comprehensive guide

I'm having trouble explaining this in English;-) Whenever I select an option, an alert pops up for each choice and I don't know how to stop it. Step 1: Choose the "aaaa" option, for example 1111 alert ... Step 2: Choose the "bbbb" option, for ...

Switch between class and slider photos

I am currently having an issue toggling the class. Here is the code I am working with: http://jsfiddle.net/h1x52v5b/2/ The problem arises when trying to remove a class from the first child of Ul. I initially set it up like this: var len=titles.length, ...

A demonstration of VueJS Nested Builder functionality

I am currently exploring VueJS and working on a project to create a simple page builder application that allows users to add sections and subsections. I am seeking guidance on how to properly set up the Vue data property for this functionality. Any advice ...

Steps for converting a window to a PDF file rather than an XPS file

Whenever I attempt to print the contents of my HTML page using window.print(), it always creates an XPS file. However, what I really need is for it to generate a PDF file instead. Any assistance would be greatly appreciated. Thank you! ...

Is there a way to manipulate the checkbox using the filter?

I'm struggling to create a controllable checkbox that will be checked if the post id matches an id from another array. I want the checkbox to add the post id to a bookmark array when clicked, and I need it to be controllable. The Redux store provides ...

The message sent by the node containing a large body (1.3 mb) encountered an error: 413 Request Entity Too Large

Using Fiddler, I am creating a POST message with a header. Content-Type: application/text-enriched app.post('/books',function(req,res){ var writeStream = fs.createWriteStream('C://Books.txt' ,{ flags : 'w' }); ...

Retrieve data from an external website containing an HTML table without a table ID using Java Script and transform it into JSON

I have developed a script that can convert HTML table data into a JSON Object. To accomplish this task, I utilized the jquery plugin created by lightswitch05. With this code, I am able to extract data from an HTML table on the same web page using: var t ...

How to dynamically reset an ng-form in Angular

After reviewing the following resources: Reset Form in AngularJS and Angular clear subform data and reset validation, I am attempting to develop a flexible form reset/clear function that would resemble the code snippet below: $scope.clearSection = functio ...

Converting a JavaScript array of strings into a regular expression literal

Here is a live example you can check out: http://jsfiddle.net/R7KuK/ In an attempt to create an array of full regular expressions with regex delimiters and set flags, I've noticed that the RegExp object is interpreting given strings as strings rather ...

Having trouble with Discord.js version 12 and the messageReactionAdd event not triggering properly?

client.on('messageReactionAdd', (reaction, user) => { console.log('If you see this I actually work...'); }); I am having some trouble with my code. Despite setting up a simple console log, it seems like the code is not running prope ...

Managing events with classes

I have multiple divs with the same class. When one of these divs is clicked, I want to change the display of the other divs to 'block'. Currently, I am using inline JavaScript for this functionality, but I would like to achieve it without inline ...

When the jQuery AJAX call is successful, the function is returned as data

Here is my implementation using codeigniter flashdata with a jQuery AJAX call: <script type="application/javascript"> var res_no = '<?php echo $this->session->flashdata('res_no'); ?>'; var res_new = '<?php ec ...

What exactly does the .proxy() method do in jQuery?

Can you explain the purpose of the jQuery.proxy function in jQuery and describe the scenarios where it is most beneficial? I came across this link, but I'm struggling to grasp its concept fully. ...

Displaying various charts in a single view without the need for scrolling in HTML

How can I display the first chart larger and all subsequent charts together in one window without requiring scrolling? This will eventually be viewed on a larger screen where everything will fit perfectly. Any recommendations on how to achieve this? Here ...

JavaScript is having trouble with the custom attribute (data-) in HTML and it is not functioning

I created a select bar with multiple options to help me sort items, and I also wanted to add a feature where clicking the option again switches between ascending and descending order. Here is the HTML code snippet: <select name="theme" id="sortSelec ...

Opacity effect on input text when it exceeds the input boundaries

I'm having an issue: I need to create inputs with different states, including when the text is longer than the input itself. In this case, the extra text should fade out with a gradient transparency effect: https://i.sstatic.net/r5qQu.jpg Here is my ...

Exploring Next.js with getStaticPaths for multi-language support

In my current Next.js project, I am working on implementing multiple locales for dynamic pages using i18n. Within my next.config.js file, the following configuration is set: module.exports = { i18n: { locales: ["en-US", "da-DK", "se-SE", "no-NO", "n ...