Painting on canvas

0

I have this code below in HTML, CSS and JavaScript, and I'm using a JavaScript library called Three.js. I'm having a problem inserting into code. This code makes paintings in plans and I needed to put a checkbox in HTML so that when activated, instead of painting, it would become an eraser, so I could erase the drawing already done or a part of the drawing. It would look like the clean button on the whole screen, but instead of clearing the entire screen, I would pass the mouse where I want to delete it and it would erase that part. (I hope I was clear with my problem.)

Following HTML code:

<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.min.js"></script>
<div id="container">
<div overflow="hidden">
<input id="pinta" name="pintar" type="checkbox"/>
<label for="pintar">Bloquear</label>
<input id="limpar" type="button" value="limpar"/>
</div>
</div>

Follow the CSS code:

#container {
overflow: hidden;
position: absolute;
width: 300px;
height: 150px;
outline: 1px dashed grey;
margin-left: -150px;
margin-top: -75px;
left: 50%;
top: 50%;
}

.balloon {
position: absolute;
color: white;
background: black;
border-radius: 100px;
font-family: sans-serif;
font-size: 20px;
width: 100px;
height: 30px;
text-align: center;
padding-top: 10px;
}

.balloon .text {
overflow: hidden;
white-space: nowrap;
width: 80px;
margin-left: 10px;
/* fix chrome gap */
height: 21px;
}

.balloon .arrow {
left: 40px;
margin-top: 9px;
border-width: 10px 10px 0px;
border-color: black transparent transparent;
position: absolute;
width: 0px;
height: 0px;
border-style: solid;
}

Follow JavaScript code:

var mouse = {
    x: 0,
    y: 0,
    down: false,
    pinta: true
};

var scene, camera, renderer, raycaster = new THREE.Raycaster(),mesh;

var canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;

var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;

var context = canvas.getContext('2d');
limpar();

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(50, container.offsetWidth / 
container.offsetHeight, 1, 10000);
camera.position.y = -400;
camera.position.z = 1000;
camera.lookAt(scene.position);

mesh = new THREE.Mesh(
    new THREE.PlaneGeometry(1000, 1000),
    new THREE.MeshBasicMaterial({
        map: texture
    })
);
scene.add(mesh);

renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xffffff);
renderer.setSize(container.offsetWidth, container.offsetHeight);

container.appendChild(renderer.domElement);

var handler = function(e) {
    mouse.down = (e.buttons != 0);
    mouse.x = e.clientX;
    mouse.y = e.clientY;
}

document.body.addEventListener('mousemove', handler);
document.body.addEventListener('mousedown', handler);
document.getElementById("pinta").onchange = function() {
    pintar()
};
document.getElementById("limpar").onclick = function() {
    limpar()
};

function limpar() {
    context.rect(0, 0, canvas.width, canvas.height);
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = 'aliceblue';
    context.fill();
    texture.needsUpdate = true;
}

function pintar() {
    mouse.pinta = !document.getElementById("pinta").checked;
}

function animate() {

    requestAnimationFrame(animate);

    mesh.rotation.y = (2 * mouse.x - document.body.offsetWidth) * 1e-3;

    if (mouse.down && mouse.pinta) {
        var canvasRect = renderer.domElement.getBoundingClientRect();

        raycaster.ray.origin.set(0, 0, 0);
        camera.localToWorld(raycaster.ray.origin);
        raycaster.ray.direction.set(
            ((mouse.x - canvasRect.left) / canvasRect.width) * 2 - 1,
            ((canvasRect.top - mouse.y) / canvasRect.height) * 2 + 1,
            0.5).unproject(camera).sub(raycaster.ray.origin).normalize();

        var intersects = raycaster.intersectObject(scene, true);
        if (intersects && intersects[0]) {
            var x = intersects[0].uv.x * canvas.width;
            var y = (1 - intersects[0].uv.y) * canvas.height;

            context.beginPath();
            context.rect(x - 4, y - 4, 8, 8);
            context.fillStyle = 'black';
            context.fill();

            texture.needsUpdate = true;
        }
    }

    renderer.render(scene, camera);

}

animate();
    
asked by anonymous 30.06.2017 / 17:11

1 answer

0

An easy way to do this, taking into consideration that your program is still very simple, is to paint with the background color.

Then in the code where the painting occurs:

context.beginPath();
context.rect(x - 4, y - 4, 8, 8);
context.fillStyle = 'black';
context.fill();

We can if to check if we are using the rubber or the brush, and if it is the rubber, we use the color of the background to paint:

if (document.getElementById("apaga").checked) {
    context.fillStyle = 'aliceblue'; // cor do fundo
} else {
    context.fillStyle = 'black';
}
  

Take a look at the working example below:

var mouse = {
    x: 0,
    y: 0,
    down: false,
    pinta: true
};

var scene, camera, renderer, raycaster = new THREE.Raycaster(),mesh;

var canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;

var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;

var context = canvas.getContext('2d');
limpar();

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(50, container.offsetWidth / 
container.offsetHeight, 1, 10000);
camera.position.y = -400;
camera.position.z = 1000;
camera.lookAt(scene.position);

mesh = new THREE.Mesh(
    new THREE.PlaneGeometry(1000, 1000),
    new THREE.MeshBasicMaterial({
        map: texture
    })
);
scene.add(mesh);

renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xffffff);
renderer.setSize(container.offsetWidth, container.offsetHeight);

container.appendChild(renderer.domElement);

var handler = function(e) {
    mouse.down = (e.buttons != 0);
    mouse.x = e.clientX;
    mouse.y = e.clientY;
}

document.body.addEventListener('mousemove', handler);
document.body.addEventListener('mousedown', handler);
document.getElementById("pinta").onchange = function() {
    pintar()
};
document.getElementById("limpar").onclick = function() {
    limpar()
};

function limpar() {
    context.rect(0, 0, canvas.width, canvas.height);
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = 'aliceblue';
    context.fill();
    texture.needsUpdate = true;
}

function pintar() {
    mouse.pinta = !document.getElementById("pinta").checked;
}

function animate() {

    requestAnimationFrame(animate);

    mesh.rotation.y = (2 * mouse.x - document.body.offsetWidth) * 1e-3;

    if (mouse.down && mouse.pinta) {
        var canvasRect = renderer.domElement.getBoundingClientRect();

        raycaster.ray.origin.set(0, 0, 0);
        camera.localToWorld(raycaster.ray.origin);
        raycaster.ray.direction.set(
            ((mouse.x - canvasRect.left) / canvasRect.width) * 2 - 1,
            ((canvasRect.top - mouse.y) / canvasRect.height) * 2 + 1,
            0.5).unproject(camera).sub(raycaster.ray.origin).normalize();

        var intersects = raycaster.intersectObject(scene, true);
        if (intersects && intersects[0]) {
            var x = intersects[0].uv.x * canvas.width;
            var y = (1 - intersects[0].uv.y) * canvas.height;

            context.beginPath();
            context.rect(x - 4, y - 4, 8, 8);
            if (document.getElementById("apaga").checked) {
            context.fillStyle = 'aliceblue';
            } else {
            context.fillStyle = 'black';
            }
            context.fill();
            texture.needsUpdate = true;
        }
    }

    renderer.render(scene, camera);

}

animate();
#container {
overflow: hidden;
position: absolute;
width: 300px;
height: 150px;
outline: 1px dashed grey;
margin-left: -150px;
margin-top: -75px;
left: 50%;
top: 50%;
}

.balloon {
position: absolute;
color: white;
background: black;
border-radius: 100px;
font-family: sans-serif;
font-size: 20px;
width: 100px;
height: 30px;
text-align: center;
padding-top: 10px;
}

.balloon .text {
overflow: hidden;
white-space: nowrap;
width: 80px;
margin-left: 10px;
/* fix chrome gap */
height: 21px;
}

.balloon .arrow {
left: 40px;
margin-top: 9px;
border-width: 10px 10px 0px;
border-color: black transparent transparent;
position: absolute;
width: 0px;
height: 0px;
border-style: solid;
}
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.min.js"></script>
<div id="container">
<div overflow="hidden">
<input id="pinta" name="pintar" type="checkbox"/>
<label for="pintar">Bloquear</label>
<input id="apaga" name="apagar" type="checkbox"/>
<label for="apagar">Apagar</label>
<input id="limpar" type="button" value="limpar"/>
</div>
</div>
    
01.07.2017 / 23:10