Search code examples
javascripthtmlcanvashtml5-canvas

How to make lineWidth in HTML canvas draw draw all sides of my form


So, I'm currently working on a tile program in my class, and I wanted to add borders to the tiles, my tile is composed of four triangles inside a square. Although lineWidth works really well, I'm struggling to make borders because I don't know how to manipulate moveTo and lineTo well enough, So I'm at a complete loss.

This is the entire code I'm currently working on, it works all well enough, but not having the borders around the project is really starting to trigger my OCD.

   <!DOCTYPE html>
    <!--
    LADRILHO - Aplicação gráfica interativa de manipulação simples de um ladrilho, destinado à avaliação de competências, no ano letivo de 2022-2023, do aluno n.º 99999, Nome Apelido.
    -->
    <html lang="pt">
    <head>
        <meta charset="utf-8" />
        <title>LADRILHO</title>
        <style>
            #base{background-color :#c0c0c0;}
            #base{width: 1000px; border: 6px inset; margin:0px auto; overflow: auto;}
            #tela1{display:block; margin: 20px; float: left;}
            #base2{width: 334px;margin: 20px 20px 0px 0px; float: left;}
            #etiq1{font: bold 19px arial; color:#802000;}
            #etiq2{font: bold 19px arial; color:#802000;}
            #tela2{font:bold 60px arial; color:#8d1b1b;}
            #botao{font: 19px arial; padding: 1px 8px;}
            #etiq3{width: 40px;font: bold 22px arial; background-color: #ffffff; display: inline-block; text-align: center;}
            #Cmod{width:380px; }
        </style>
        <script>
            let cGraf1;
            let cGraf2;
            let canvasPrincipal;
            let examplecanva;

            //inicialização
            
            function inic(){
                //contexto gráfico
                cGraf1 = document.getElementById("tela1");
                canvasPrincipal= cGraf1.getContext("2d");
                cGraf2 = document.getElementById("tela2");
                examplecanva = cGraf2.getContext("2d");
                //inicializar a grelha
                novoLadrilho1();
            }

            //******** input/output ********

            //output de um conteúdo num contentor HTML, dados o ID do contentor e o conteúdo (boleano, número ou string)
            
            function novoLadrilho1(){
                let modul = parseInt(document.getElementById("Cmod").value);
                document.getElementById("vMod").innerHTML= modul;
            
                canvasPrincipal.clearRect(0,0,canvasPrincipal.width,canvasPrincipal.width);
                const tamanho= cGraf1.width / modul;
                console.log(canvasPrincipal);
                
                let lineWidth;
                if (modul === 1) {
                    lineWidth = 6.3;
                } else {
                    const reductionFactor = (modul - 1) * 1.9; // Adjust the multiplication factor as needed
                    lineWidth = Math.max(0.3, 6.3 - reductionFactor);
                }
                canvasPrincipal.lineWidth = lineWidth;  
                
                for(i=0; i<modul ; i++ ){
                    for(j = 0; j < modul; j++){
                        let x = i * tamanho;
                        let y = j * tamanho;
                        ladrilho(canvasPrincipal, x, y, tamanho);
                    }
                }
                
            }
            function ladrilho(canvas, x, y, size, cor){
                
                let color = document.getElementById("vMod").value;
                let cores = listaTons(3.01,color);

                for (let i = 0; i < 4; i++) {
                    canvas.fillStyle = cores[i];
                    canvas.beginPath();
                    if (i == 0) {
                        canvas.moveTo(x + size, y + size);
                        canvas.lineTo(x + (size / 2), y + (size / 2));
                        canvas.lineTo(x, y + size);
                    }
                    if (i == 1) {
                        canvas.moveTo(x + size, y + size);
                        canvas.lineTo(x + (size / 2), y + (size / 2));
                        canvas.lineTo(x + size, y);

                    }
                    if (i == 2) {
                        canvas.moveTo(x,y);
                        canvas.lineTo(x,size+y);
                        canvas.lineTo(x + (size / 2), y + (size / 2));
                    }
                    if (i == 3) {
                        canvas.moveTo(x,y);
                        canvas.lineTo(x + size,y);
                        canvas.lineTo(x + (size / 2), y + (size / 2));
                    }

                    canvas.closePath();
                    canvas.stroke();
                    canvas.fill();
                }
            }
            
            //********* processos *********

            //lista das componentes RGB decimais de uma cor representada em código hexadecimal
            function rgbHex(ch){
                var i, cd = [];
                for(i=0; i<3; i++) cd.push(parseInt(ch[2*i+1] + ch[2*i+2], 16));
                return cd;
            }
            
            //representação em código hexadecimal de uma cor representada segundo uma lista das componentes RGB decimais
            function hexRGB(cd){
                var i, comp, ch = "#";
                for(i=0; i<3; i++){
                    comp = Math.round(cd[i]).toString(16);
                    if(cd[i] > 15) ch += comp; else ch += "0" + comp;
                }
                return ch;
            }
            
            //lista das componentes HSL de uma cor representada em lista de componentes RGB decimais
            function hslRGB(cd){
                var R, G, B, H, S, L, min, max;
                //converte os valores RGB para o intervalo 0-1 e determina o mínimo e o máximo
                R = cd[0]/255; G = cd[1]/255; B = cd[2]/255;
                min = Math.min(R,G,B); max = Math.max(R,G,B);
                //Luminosidade
                L = (min + max) / 2;
                //se for um cinza, a saturação e a matiz são zero
                if(max == min) return [0,0,L]; 
                //SATURAÇÃO
                if(L <= 0.5) S = (max-min)/(max+min); else S = (max-min)/(2-max-min);
                //MATIZ (escala 0-6)
                if(max == R) H = (G-B)/(max-min);
                if(max == G) H = 2 + (B-R)/(max-min);
                if(max == B) H = 4 + (R-G)/(max-min);
                //Resultado
                return [60*H, S, L];
            }

            //lista das componentes RGB decimais de uma cor representada em lista de componentes HSL 
            function rgbHSL(cHSL){
                //extrai as componentes
                var h=cHSL[0], s=cHSL[1], l=cHSL[2];
                //estabelece os parâmetros da fórmula
                const k = n => (n + h / 30) % 12;
                const a = s * Math.min(l, 1 - l);
                //estabelece a fórmula
                const f = n => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
                //resultado
                return [Math.round(255 * f(0)), Math.round(255 * f(8)), Math.round(255 * f(4))];
            };
            
            //gera uma lista de tons cromáticos, em código hexadecimal, por ordem crescente de luminosidade, dados o número de tons e a cor base, em código hexadecimal 
            function listaTons(nTons, corBase){
                var corHSL = hslRGB(rgbHex(corBase)); 
                var h = corHSL[0], s = corHSL[1], l = corHSL[2];
                var i, dl = 1/(nTons+2), lista = [];
                for(i=1; i<nTons+1; i++){
                    lista.push(hexRGB(rgbHSL([h, s, i*dl])));
                }
                return lista;
            }

            //Atualiza o valor da modularidade
            function uppdateMod(valor){
              document.getElementById("etiq3").innerHTML = valor;
              novoLadrilho1();
            }
                
        </script>
        </head>
        <body onload="inic()" style="background-color: #c0c0c0;">
        <div id="base">
            <canvas id="tela1" width="606px" height="606px"></canvas>
            <div id="base2"> 
                <canvas id="tela2" width="156px" height="156px"></canvas>
                <hr>
                <span id="etiq1">Cor Base: </span>
                <input id="vMod" type="color" value="#ff8000">
                <button id="botao" onclick="novoLadrilho1()">Aplicar ao Padrão</button>
                <hr>
                <span id="etiq2">Modularidade: </span>
                <span id="etiq3">12</span>
                <br>
                <input type="range" id="Cmod" width="100%" min="1" max="40" value="12" step="1" oninput="uppdateMod(value)" style="width: 100%;">
            </div>
        </div>
    </body>
    </html>

I tried manipulating the lineTo and moveTo and altought I did manage to get some lines, I didn't have them in the positions I wanted.


Solution

  • not sure, if i understand your problem cause as you said it seems to be actually working and also drawing these outlines (try to check this modifying a lineTo), i did and check the img below, your triangles are overlaping within the canvas and i guess this color thing doesnt help...

    canvas overlap

    but in order to solve it you need to deal with that, though its only a problem with the most external border, so i think you may want to get a border around the canvas?

    if its the case this single css line will help you achieve this, otherwise

    #tela1{display:block; margin: 20 10px; float: left; border: 2px solid #000;}

    let me know your thoughts!!