Button to enable drawing and clear canvas

Asked

Viewed 863 times

1

// forked from makc's "Simplify this three.js drawing exmple" http://jsdo.it/makc/zXNX
var mouse = { x: 0, y: 0, down: false };

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

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

var context = canvas.getContext ('2d');
context.rect (0, 0, canvas.width, canvas.height);
context.fillStyle = 'aliceblue';
context.fill ();

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

    
    scene = new THREE.Scene();
    
    camera = new THREE.PerspectiveCamera( 75, 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);


function animate() {
    
    requestAnimationFrame( animate );
    
    mesh.rotation.y = (2 * mouse.x - document.body.offsetWidth) * 1e-3;
    
    if (mouse.down) {
        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();
* {
  margin: 0;
  padding: 0;
  border: 0;
}

#container {
    overflow: hidden;
    position: absolute;
    width: 400px;
    height: 400px;
    outline: 1px dashed grey;
    margin-left: -200px;
    margin-top: -200px;
    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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.min.js"></script>
<div id="container"></div>

I found that code on the Internet exactly how I needed to.

But now I needed to add a button that clears the drawing that is on <div>, to the <div> go back to the way it was initially. I also need to add a button to lock and unlock the painting.

Example:
When the button is unlocked, I can draw normally, but when it is locked, I cannot draw.

How can I do that?

  • Does the clean and lock button need to be inside the canvas? i.e. not be two html buttons on the page?

  • The buttons were created inside the html, with the code inside the JS file, even so it doesn’t work

1 answer

0


The "painting" itself, happens here:

if (mouse.down) { /*...*/ }

If we put a new parole, can control when the mouse draws or not:

if (mouse.down && mouse.pinta) { /*...*/ }

pinta, I added in the variable mouse that already existed:

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

I moved the entire boot context to a function called 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;
}

And I think that already works for what you wanted - see the example below.

// forked from makc's "Simplify this three.js drawing exmple" http://jsdo.it/makc/zXNX
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();
/*
* {
  margin: 0;
  padding: 0;
  border: 0;
}
*/

#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>
<script src="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>

  • Thank you so much, you helped me so much. That’s exactly what I needed.

  • Hi, @Blogger. I really need another help from you, I saw that you understood the code better and already helped me a lot, but now I needed another help, please, you could help me put a eraser, to erase the painting. Example: I click on checkbox and instead of painting, erase the painting I have already done, and do not clean the entire area, but leaving the existing buttons in the code above. Thank you very much

  • Hello Giovanni! I believe you can get help faster by asking a new question - just make sure you post your full code, as it is at the moment (rather than putting a link), and explain what you expect the code to do (thus decreases the chance of closing your question, as they did with this one). If you want, send me a warning of your new question - but I think they’ll answer before I get a chance to see her!

  • I’ll do it, thanks for the tip @Blogger

Browser other questions tagged

You are not signed in. Login or sign up in order to post.