首页 > 解决方案 > 如何解决canvas JS lineWidth问题?

问题描述

我试图在使用画布 moveTo() - lineTo() 时正确更改线宽,如果我只是将笔画的宽度保留为 1px,它会正常工作,但除此之外的任何东西都会给我带来混乱的线条。

这是我正在使用的代码。 https://github.com/nitroflox/git_practice/blob/main/main.js

HTML:https ://github.com/nitroflox/git_practice/blob/main/drawingPallet.html

编辑

const canvas = document.getElementById("pallet");
const ctx = canvas.getContext("2d");
const width = canvas.width = 800;
const height = canvas.height = 640;

var mouse = {};
var mousePressed = false;

var squarePen = {
    x: 0,
    y: 0,
    w: 30,
    h: 30,
    use: true
};
var circlePen = {
    x: 0,
    y: 0,
    r: 15,
    use: false
};
var pen = {
    x: 0,
    px: 0,
    y: 0,
    py: 0,
    w: 1,
    h: 1,
    use: false
};
var eraser = {
    x: 0,
    y: 0,
    w: 30,
    h: 30,
    use: false
};


var redSlider = document.getElementById("r");
var redValue = document.getElementById("red");
var greenSlider = document.getElementById("g");
var greenValue = document.getElementById("green");
var blueSlider = document.getElementById("b");
var blueValue = document.getElementById("blue");
redValue.value = redSlider.value;
greenValue.value = greenSlider.value;
blueValue.value = blueSlider.value;

var square = document.getElementById("square");
square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;

redSlider.addEventListener("change", (e)=>{
    redValue.value = redSlider.value;
    square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;
});
redValue.addEventListener("keyup", (e)=>{
    redSlider.value = redValue.value;
    square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;
});

greenSlider.addEventListener("change", (e)=>{
    greenValue.value = greenSlider.value;
    square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;
});
greenValue.addEventListener("keyup", (e)=>{
    greenSlider.value = greenValue.value;
    square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;
});

blueSlider.addEventListener("change", (e)=>{
    blueValue.value = blueSlider.value;
    square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;
});
blueValue.addEventListener("keyup", (e)=>{
    blueSlider.value = blueValue.value;
    square.style.backgroundColor = `rgb(${redValue.value},${greenValue.value},${blueValue.value})`;
});

canvas.addEventListener("mousemove", (e)=>{
    mouse.x = e.clientX - 303;
    mouse.y = e.clientY - 6;
    if(squarePen.use) setSquarePos();
    if(circlePen.use) setCirclePos();
    if(eraser.use) setEraserPos();
    if(pen.use) setPenPos();
});

canvas.addEventListener("mousedown", (e)=>{
    if(pen.use) setPrevPenPos();
    mousePressed = true;
});

canvas.addEventListener("mouseup", (e)=>{
    if(pen.use) setPenPos();
    mousePressed = false;
});

var sizeSlider = document.getElementById("size");
var sizeValue = document.getElementById("pen-size");
sizeValue.value = sizeSlider.value;
setCircleSize();
setSquareSize();
setEraserSize();
setPenSize();
sizeSlider.addEventListener("change", (e)=>{
    sizeValue.value = sizeSlider.value;
    if(circlePen.use) setCircleSize();
    if(squarePen.use) setSquareSize();
    if(eraser.use) setEraserSize();
    if(pen.use) setPenSize();
});
sizeValue.addEventListener("keyup", (e)=>{
    if(sizeValue.value <= sizeSlider.min) sizeValue.value = 1;
    if(sizeValue.value >= sizeSlider.max) sizeValue.value = 200;
    sizeSlider.value = sizeValue.value;
    if(circlePen.use) setCircleSize();
    if(squarePen.use) setSquareSize();
    if(eraser.use) setEraserSize();
    if(pen.use) setPenSize();
})

function changeFill(){
    ctx.fillStyle = square.style.backgroundColor;    
    ctx.strokeStyle = square.style.backgroundColor;
    if(eraser.use){
        ctx.strokeStyle = "white";
        ctx.fillStyle = "white"; // change to remove from canvas
    }
}

function clearCanvas(){
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, 800, 640);
    ctx.fillStyle = square.style.backgroundColor;
}

function useSquare(){
    circlePen.use = false;
    eraser.use = false;
    pen.use = false;
    squarePen.use = true;
    setSquareSize();
}

function useCircle(){
    squarePen.use = false;
    eraser.use = false;
    pen.use = false;
    circlePen.use = true;
    setCircleSize();
}

function usePen(){
    squarePen.use = false;
    circlePen.use = false;
    eraser.use = false;
    pen.use = true;
    setPenSize();
}

function useEraser(){
    squarePen.use = false;
    circlePen.use = false;
    pen.use = false;
    eraser.use = true;
    setEraserSize();
}

function setSquarePos(){
    squarePen.x = mouse.x - squarePen.w / 2;
    squarePen.y = mouse.y - squarePen.h / 2;
}

function setCirclePos(){
    circlePen.x = mouse.x;
    circlePen.y = mouse.y;
}

function setPenPos(){
    pen.x = mouse.x - pen.w / 2;
    pen.y = mouse.y - pen.h / 2;
}
function setPrevPenPos(){
    pen.px = pen.x;
    pen.py = pen.y;
}

function setEraserPos(){
    eraser.x = mouse.x - eraser.w / 2;
    eraser.y = mouse.y - eraser.h / 2;
}

function setSquareSize(){
    squarePen.w = sizeSlider.value;
    squarePen.h = sizeSlider.value;
}

function setCircleSize(){
    if(sizeSlider.value <= 2) circlePen.r = 2;
    else circlePen.r = sizeSlider.value / 2;
}

function setPenSize(){
    pen.w = sizeSlider.value;
    pen.h = sizeSlider.value;
    ctx.lineWidth = sizeSlider.value;
}

function setEraserSize(){
    eraser.w = sizeSlider.value;
    eraser.h = sizeSlider.value;
}

function draw(){
    if(mousePressed){
        ctx.beginPath();
        if(squarePen.use)
            ctx.rect(squarePen.x, squarePen.y, squarePen.w, squarePen.h);
        if(circlePen.use)
            ctx.arc(circlePen.x, circlePen.y, circlePen.r, 0, Math.PI * 2, false);
        if(eraser.use)
            ctx.rect(eraser.x, eraser.y, eraser.w, eraser.h);
        ctx.fill();
        ctx.closePath();

        if(pen.use){
            ctx.beginPath();
            ctx.moveTo(pen.x, pen.y);
            ctx.lineTo(pen.px, pen.py);
            setPrevPenPos();
            ctx.stroke();
            ctx.closePath();
        }
    }
}

function update(){
    changeFill();
    draw();
    window.requestAnimationFrame(update);
}

window.requestAnimationFrame(update);
*{ margin: 0; padding: 0;}

#main{
    /* border: thin solid red; */
    border-collapse: separate;
    border-spacing: 15px 5px;
    margin: 0;
    padding: 0;
}

#main td{
    /* background-color: lime; */
    /* border: thin solid black; */
    margin: 0;
    padding: 0;
}

#pallet{
    border: 2px solid black;
    background-color: rgb(255, 255, 255);
    display: block;
}

#color{
    border: thin solid black;
    background-color: lightcoral;
    width: 270px;
    height: 200px;
}

#color table{
    border-collapse: collapse;
}
    #square{
        width: 70px;
        height: 70px;
        border: thin solid black;
        margin: 7px auto;
    }
    .slider{
        -webkit-appearance: none;
        height: 4px;
        width:200px;
        margin:15px 5px;
        background:#d3d3d3;
    }
    #r::-webkit-slider-thumb{
        -webkit-appearance: none;
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: red;
    }
    #r::-moz-range-thumb{
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: red;
    }
    #g::-webkit-slider-thumb{
        -webkit-appearance: none;
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: green;
    }
    #g::-moz-range-thumb{
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: green;
    }
    #b::-webkit-slider-thumb{
        -webkit-appearance: none;
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: blue;
    }
    #b::-moz-range-thumb{
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: blue;
    }
    .color-value{
        width:40px;
    }

#tool{
    border: thin solid black;
    /* background-color: lightblue; */
    width: 270px;
    height: 435px;
}
    .tool-btn{
        width: 60px;
    }
    <table id="main">
        <tr>
            <td>
                <div id="color">
                    <table>
                        <tr>
                            <td>
                                <input type="range" min="0" max="255" class="slider" id="r" />
                            </td>
                            <td>
                                <input type="text" class="color-value" id="red" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <input type="range" min="0" max="255" class="slider" id="g" />
                            </td>
                            <td>
                                <input type="text" class="color-value" id="green" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <input type="range" min="0" max="255" class="slider" id="b" />
                            </td>
                            <td>
                                <input type="text" class="color-value" id="blue" />
                            </td>
                        </tr>
                        <tr>
                            <td colspan="2">
                                <div id="square"></div>
                            </td>
                        </tr>
                    </table>
                </div>
            </td>
            <td rowspan="2">
                <canvas id="pallet"></canvas>
            </td>
        </tr>
        <tr>
            <td>
                <div id="tool">
                    <button class="tool-btn" onclick="clearCanvas()">Clear</button><br/><br/>
                    <button class="tool-btn" onclick="usePen()">Pen</button><br /><br />
                    <button class="tool-btn" onclick="useSquare()">Square</button> 
                    <button class="tool-btn" onclick="useCircle()">Circle</button> 
                    <button class="tool-btn" onclick="useEraser()">Eraser</button><br/>
                    <input type="range" min="1" max="200" class="slider" id="size" value="5" />
                    <p>pen size: <input type="text" class="color-value" id="pen-size" /> px</p>
                </div>
            </td>
        </tr>
    </table>
    <script src="js/main.js"></script>

标签: javascripthtmlcanvas

解决方案


推荐阅读