Resizing the Canvas in Three.js with GLSL

I'm currently facing challenges with maintaining the proportions when resizing the window to smaller sizes on mobile devices as shown in this CodePen. The lines and interaction become difficult to see on mobile screens. Is there a solution to address this issue? One approach could be to double the scale on resize based on the window size, but I'm unsure how to implement this effectively.

The relevant section of the JavaScript code:

onWindowResize();
window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize(event) {
container.style.height = window.innerHeight+"px";
container.style.width = window.innerWidth+"px";

canvasWidth = container.offsetWidth;
canvasHeight = container.offsetHeight;
//send new size value to the shader and resize the window
uniforms.resolution.value.x = canvasWidth;
uniforms.resolution.value.y = canvasHeight;

//var res = canvasWidth / cols;
//rows = canvasHeight / res;
uniforms.colsrows.value.x = cols;
uniforms.colsrows.value.y = rows;//rows;

renderer.setSize(canvasWidth, canvasHeight);
}

Access the pen here:

// Initialize variables for the container, the WebGL 3D scene, uniforms to bind into the shader, and timer

var container;
var camera, scene, renderer;
var uniforms;
var startTime;


var cols = 50.;
var rows  = 50.0;

init(); // Initialize the scene
animate(); // Update the scene

function init() {
// Get the container
container = document.getElementById('container');

// Create THREE.JS scene and timer
startTime = Date.now();
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();

// Create a simple plane
var geometry = new THREE.PlaneBufferGeometry(16, 9);

// Create uniform table that provides all our GLSL bindings
uniforms = {
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
colsrows: {type: "v2", value: new THREE.Vector2()},
mouse: {type: "v2", value: new THREE.Vector2()}
};

// Create a shader material in THREE.JS
var material = new THREE.ShaderMaterial( {
// Set shaders and uniforms into the material
uniforms: uniforms,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
} );

// Create a mesh and add it to the scene
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// Create a renderer and add it to the DOM
renderer = new THREE.WebGLRenderer();
container.appendChild(renderer.domElement);

// Check for window resize to obtain proper resolution values to bind
onWindowResize();
window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize(event) {
container.style.height = window.innerHeight+"px";
container.style.width = window.innerWidth+"px";

canvasWidth = container.offsetWidth;
canvasHeight = container.offsetHeight;
// Send new size value to the shader and resize the window
uniforms.resolution.value.x = canvasWidth;
uniforms.resolution.value.y = canvasHeight;

//var res = canvasWidth / cols;
//rows = canvasHeight / res;
uniforms.colsrows.value.x = cols;
uniforms.colsrows.value.y = rows;//rows;

renderer.setSize(canvasWidth, canvasHeight);
}

function animate() {
render();
requestAnimationFrame(animate);
}

function render() {
var currentTime = Date.now();
var elaspedSeconds =  (currentTime - startTime) / 1000.0;
var maxTime = 4.0;
var normTime = (elaspedSeconds % maxTime) / maxTime;
uniforms.time.value = elaspedSeconds * 1.0;

renderer.render(scene, camera);
}


function move(ev){
 mx = ev.clientX
  my = ev.clientY;
// console.log(mx+" , "+my);

uniforms.mouse.value.x = mx;
uniforms.mouse.value.y = my;
}

document.addEventListener('mousemove', move)
html, body {
  margin: 0;
  height: 100%;
  background : #1a1a1a;
}

canvas {
  display: block;
  cursor: none;
}

#container{
background : black;
color : white;
  margin: auto;
width : 500px;
height : 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<div id="container"></div>

<!-- GLSL SCRIPT -->
<!-- vertex shader -->
<script id="vertexShader" type="x-shader/x-vertex">
// Vertex shader code here
</script>

<!-- fragment shader -->
<script id="fragmentShader" type="x-shader/x-fragment">
// Fragment shader code here
</script>

Answer №1

The thickness of the strokes is calculated within the drawLine function and depends on the inputs of the smoothstep method:

float drawLine(vec2 uv, vec2 p1, vec2 p2, float r)
{
   // [...]

   return 1.0 - smoothstep(0.0, 0.01, d - r);
}

To create thicker lines, adjust the value of the edge1 parameter (e.g. set it to 0.1):

float drawLine(vec2 uv, vec2 p1, vec2 p2, float r)
{
    // [...]

    return 1.0 - smoothstep(0.0, 0.1, d - r);
}

You have the option to introduce a new uniform variable for the line thickness:

uniform float thickness;

float drawLine(vec2 uv, vec2 p1, vec2 p2, float r)
{
    // [...]

    return 1.0 - smoothstep(0.0, thickness, d - r);
}
uniforms = {
    // [...]

    thickness: { type: "f", value: 0.1 },
};

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

Asynchronous task during stream processing

Can anyone assist me? I am looking to read a file as a stream and when processing the initial chunk, I need to create a database table in an async manner. To achieve this, I want to develop a duplex/transformer stream that would be responsible for creatin ...

Implementing the jquery mobile data-native-menu feature in a select element dynamically generated from jeditable

Greetings! I have encountered an issue where the data-native-menu="false" instruction works correctly when directly placed in a select element, but doesn't work when added to a select generated by JavaScript (using the Jeditable plugin). You can view ...

Coloring vertices in a Three.js geometry: A guide to assigning vibrant hues

This inquiry was previously addressed in this thread: Threejs: assign different colors to each vertex in a geometry. However, since that discussion is dated, the solutions provided may not be applicable to current versions of three.js. The latest versions ...

Getting a null value for active user after completing the sign-in process

I am using local storage to store username and password. However, I am encountering an issue where the active user is returning null after a certain line of code, and I am unsure why. console.log("I am the Active user: " + activeUser); const me ...

Tips for creating a stylish scrollbar in a React Material-Table interface

Currently, I am utilizing the react material-table and looking to implement a more visually appealing scroll-bar instead of the default Pagination option. Although I have experimented with the react-custom-scroll package, it has not produced the desired ...

Using React with Axios to trigger several requests with a single action

Let's say a user selects a team from a dropdown menu, triggering a request to an API endpoint. const selectHomeTeamStat = evt => { const { value } = evt.target; getStats(leagueId, value, 'home'); }; In this hypothetical scen ...

Retrieve data from ajax call in segments before it finishes

When my browser sends an ajax/json request to the server, it calls several services to gather data of different lengths before displaying it in the browser. Instead of waiting for all the data to be retrieved at once, I would prefer to receive the data (j ...

Step-by-step guide to inserting an image into a Table Cell

I want to include my PDF image at the conclusion of the text in my table cell When it comes to my Table, I'm hoping that the image can be combined with the text seamlessly after it finishes <TableCell component="th" scope="row" className = {class ...

Creating a unique triangle in three.js

I am currently working on creating a custom triangle in Three.js. The current code is rendering the wireframe of the triangle, but nothing else. When I turn off the wireframe, it becomes invisible. How can I modify this to render a colored triangle? v ...

What causes my browser fingerprint to consistently remain unchanged?

declare var Fingerprint2: any; @Component({ selector: 'my-app', template: `Hello`, }) export class App { constructor() { new Fingerprint2().get(function(result, components){ console.log(result); // Device fingerprint as a hash va ...

angularjs controller cross-validation for forms

I am faced with a dilemma involving two controllers: btnController and formController. Specifically, I need to submit a Form from another controller action while ensuring that the function in the controller is only called when the Form Validation is Valid. ...

Trying to configure and use two joysticks at the same time using touch events

I have been grappling with this problem for the past two days. My current project involves using an HTML5/JS game engine called ImpactJS, and I came across a helpful plugin designed to create joystick touch zones for mobile devices. The basic concept is th ...

Upon a successful AJAX post request, the page fails to display

I'm encountering an issue connecting my front-end JavaScript to my back-end Node/Express. Although the requests from my client-side js to the server return successful, the page I am requesting fails to render. On the server side, here is my code: ap ...

Guide: "Executing an AJAX button click using a Greasemonkey script"

(find below a solution) I created a Greasemonkey script that automatically clicks on a specific link within a target website. Initially, my script looked like this: var MyVar = $("a:contains('Save')"); if (MyVar && MyVar.length) win ...

I'm currently working on developing a chat system, but I'm facing an issue where I am unable to send multiple messages consecutively. It seems like there is a problem with the form

My chat application is not allowing me to post multiple messages. Here is the code snippet responsible for sending messages: window.typing = false; var posted = 0; var canPost = 1; var donotrefresh = 0; document.forms['send'].addEventListener(& ...

Interacting Shadows with BufferGeometry in react-three-fiber

I've been working on my custom bufferGeometry in react-three-fiber, but I can't seem to get any shadows to show up. All the vertices, normals, and UVs are set correctly in my bufferGeometry, and I even tried adding indices to faces, but that just ...

The native javascript modal fails to appear

I'm attempting to implement the functionality from this Codepen demo into my project. I've copied over the HTML, CSS, and JavaScript code: <!DOCTYPE HTML> <html> <head> <script> var dialog = docume ...

Exploring the map function in Angular and native JavaScript

Still getting the hang of angular, so there might be something I'm overlooking. I have a model containing a collection of objects with their own properties, and my goal is to generate a csv value based on the Text property of each object. I've ex ...

How to Perform a Method Call or Array Iteration in JSX within HTML

Encountering a new issue that I haven't faced before, this is my first time working on something like this and finding a solution is proving to be tricky. Currently, I'm using SendGrid to send an HTML email through a POST request in express on N ...

Exploring AngularJS through interactive sessions

I am working on implementing a basic login system using express and angularjs. The angular js application is running on a different server (grunt server localhost:9000), while the express app is running on a separate port. In my express app, I have configu ...