Home > other >  Scaling function of line thickness in JavaScript
Scaling function of line thickness in JavaScript

Time:10-19

I am looking for a scaling function in JavaScript. In my canvas there are moving points which connects with each other through a line in the form of a triangle (Please look at the code snippet below for better understanding.)

What I am looking for is, whenever two moving points are getting closer, their corresponding line should be thicker.
Two connected points far away = thin line,
two connected points close = thick line

I would prefer using pure JavaScript then using libraries or anything like, that I wouldn't probably understand.

There are quite few comments for documentation. It should help explain my code better

body {
    background-color: #000000;
}

canvas {
    padding: 0;
    margin: auto;
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #111416; 
    /*background-color: white; */
    border: 10px solid #37c7f7;
    border-style: double;
    box-shadow: 0 0 20px 5px #37c7f7;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <link rel="stylesheet" href="canvas.css">
    <canvas id="myCanvas" width="700" height="700"></canvas>

    <script>
    
    // Get id from the canvas element
    var canvas = document.getElementById("myCanvas");

    // Provide 2D rendering context for the drawing surface of canvas
    var context = canvas.getContext("2d");

    // Get width and height of the canvas element
    var canvW = document.getElementById("myCanvas").width;
    var canvH = document.getElementById("myCanvas").height;
    
    // Create a random range of numbers
    const randomRange = (min, max) => {
        return Math.random () * (max - min)   min;
    }
   
    // Create empty array called
    const agents = [];

    // Class = Create multiple objects with the same properties 
    class Point {
        // Build the new object and pass parameters
        constructor(x, y){
            
            // Define properties
            // "this" refers to the scope of the class
            // class point contains propertie x and y
            this.x = x; 
            this.y = y;
        }

        // "v" stands for vector
        //Connecting the moving points into a triangle
        getDistance(v){
            const dx = this.x - v.x;
            const dy = this.y - v.y;
            // Phytagorean Theorem
            return Math.sqrt(dx*dx   dy*dy);
        }

    }

    // Separate point from canvas
    // Make dot a new entity
    // Create another class

    class Agent {
        constructor(x, y){
            // First property is position using x and y parameters
            this.pos = new Point(x, y);

            // Define velocity of point.
            this.vel = new Point(randomRange(-0.75, 0.75), randomRange(-0.75, 0.75));

            // Create points with random radius
            this.radius = randomRange(4, 12);
        }

        // Generated points are bouncing off from the edge of the canvas 
        bounce(canvW, canvH) {
            if (this.pos.x <= 0 || this.pos.x >= canvW) this.vel.x *= -1;
            if (this.pos.y <= 0 || this.pos.y >= canvH) this.vel.y *= -1;
        }

        update() {
            this.pos.x  = this.vel.x;
            this.pos.y  = this.vel.y;
        }

        // Create new method called draw
        // Pass paramter as reference to the context

        draw (context) {
            // Draw the points
            context.save();
            context.translate(this.pos.x, this.pos.y);
            context.beginPath();
            context.arc(0, 0, this.radius, 0, Math.PI * 2);
            context.lineWidth = 2;
            context.fillStyle = "#37c7f7";
            context.fill();
            context.stroke();
            context.restore();

            for (let i = 0; i < agents.length; i  ){
                const agent = agents[i];

                for(let j = i  1; j < agents.length; j  ){
                const other = agents[j];
                
                //Get distance between the moving points
                const dist = agent.pos.getDistance(other.pos);
                
                // If distance greater than the number, do not connect the lines
                if (dist > 200) continue;
                
                // Connecting the moving points with lines
                context.beginPath();
                context.moveTo(agent.pos.x, agent.pos.y);
                context.lineTo(other.pos.x, other.pos.y);
                context.stroke();
                context.strokeStyle = "#37c7f7";
                }
        }

        }
    }

    // Create random number of points using a for loop

    for (let i =0; i<40; i  ){
        const x = randomRange(0, canvW);
        const y = randomRange(0, canvH);

        // push adds new items to the end of an array
        // push changes the length of an array
        // push returns the new length
        agents.push(new Agent (x, y));

    }

    // Drawing and updating the animation process
    const animate = () => {

        context.save();
        context.fillStyle = "#111416";
        context.fillRect(0, 0, canvW, canvH);
        context.restore();

        agents.forEach(agent => {
            agent.draw(context);
            agent.update();
            agent.bounce(canvW, canvH);
        });
    
      requestAnimationFrame(animate);
    }

    animate();
    
    </script>

</body>
</html>

CodePudding user response:

One way you can approach this is by using the dist between the agents to determine the lineWidth. Here I made sure the width would atleast be 1 and played with the 100 variable.

...

if (dist > 200) continue;
...
context.stroke();
context.lineWidth = dist / 100   1;
context.strokeStyle = "#37c7f7";

CodePudding user response:

This can be done by normalizing distance between two connected points to some fixed range, in this case 0..radius looks fine:

body {
    background-color: #000000;
}

canvas {
    padding: 0;
    margin: auto;
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #111416; 
    /*background-color: white; */
    border: 10px solid #37c7f7;
    border-style: double;
    box-shadow: 0 0 20px 5px #37c7f7;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <link rel="stylesheet" href="canvas.css">
    <canvas id="myCanvas" width="700" height="700"></canvas>

    <script>
    
    // Get id from the canvas element
    var canvas = document.getElementById("myCanvas");

    // Provide 2D rendering context for the drawing surface of canvas
    var context = canvas.getContext("2d");

    // Get width and height of the canvas element
    var canvW = document.getElementById("myCanvas").width;
    var canvH = document.getElementById("myCanvas").height;
    
    // Create a random range of numbers
    const randomRange = (min, max) => {
        return Math.random () * (max - min)   min;
    }
   
    // Create empty array called
    const agents = [];

    // Class = Create multiple objects with the same properties 
    class Point {
        // Build the new object and pass parameters
        constructor(x, y){
            
            // Define properties
            // "this" refers to the scope of the class
            // class point contains propertie x and y
            this.x = x; 
            this.y = y;
        }

        // "v" stands for vector
        //Connecting the moving points into a triangle
        getDistance(v){
            const dx = this.x - v.x;
            const dy = this.y - v.y;
            // Phytagorean Theorem
            return Math.sqrt(dx*dx   dy*dy);
        }

    }

    // Separate point from canvas
    // Make dot a new entity
    // Create another class

    class Agent {
        constructor(x, y){
            // First property is position using x and y parameters
            this.pos = new Point(x, y);

            // Define velocity of point.
            this.vel = new Point(randomRange(-0.75, 0.75), randomRange(-0.75, 0.75));

            // Create points with random radius
            this.radius = randomRange(4, 12);
        }

        // Generated points are bouncing off from the edge of the canvas 
        bounce(canvW, canvH) {
            if (this.pos.x <= 0 || this.pos.x >= canvW) this.vel.x *= -1;
            if (this.pos.y <= 0 || this.pos.y >= canvH) this.vel.y *= -1;
        }

        update() {
            this.pos.x  = this.vel.x;
            this.pos.y  = this.vel.y;
        }

        // Create new method called draw
        // Pass paramter as reference to the context

        draw (context) {
            // Draw the points
            context.save();
            context.translate(this.pos.x, this.pos.y);
            context.beginPath();
            context.arc(0, 0, this.radius, 0, Math.PI * 2);
            context.lineWidth = 2;
            context.fillStyle = "#37c7f7";
            context.fill();
            context.stroke();
            context.restore();

            for (let i = 0; i < agents.length; i  ){
                const agent = agents[i];

                for(let j = i  1; j < agents.length; j  ){
                const other = agents[j];
                
                //Get distance between the moving points
                const dist = agent.pos.getDistance(other.pos);
                
                // If distance greater than the number, do not connect the lines
                if (dist > 200) continue;
                
                const r = this.radius;
                
                // Connecting the moving points with lines
                context.beginPath();
                context.moveTo(agent.pos.x, agent.pos.y);
                context.lineTo(other.pos.x, other.pos.y);
                context.strokeStyle = "#37c7f7";
                context.lineWidth = r * (1 - (dist - r) / (200 - r));
                context.stroke();
                }
        }

        }
    }

    // Create random number of points using a for loop

    for (let i =0; i<40; i  ){
        const x = randomRange(0, canvW);
        const y = randomRange(0, canvH);

        // push adds new items to the end of an array
        // push changes the length of an array
        // push returns the new length
        agents.push(new Agent (x, y));

    }

    // Drawing and updating the animation process
    const animate = () => {

        context.save();
        context.fillStyle = "#111416";
        context.fillRect(0, 0, canvW, canvH);
        context.restore();

        agents.forEach(agent => {
            agent.draw(context);
            agent.update();
            agent.bounce(canvW, canvH);
        });
    
      requestAnimationFrame(animate);
    }

    animate();
    
    </script>

</body>
</html>

  • Related