1

Im started to develop my project, where fabric js canvas used as a texture on my 3d object, loaded by three js library. Unfortunately I don`t have a full working snippet now, maybe you can show me solution or right way to solve my problem

The problem is the controls drawing on the lower canvas and its transfer on my 3d object, i want to render it on the upper canvas. Is it possible? The second problem is the brush at first rendered on the upper canvas and after event 'mouse: up' its rendered on the lower canvas. How to render brush line by event 'mouse; move' on the lower canvas at the moment drawing?

p.s. sorry for my english, its really hard to say for me. Hope, you understand my mind

Here you can see my first issue: https://1drv.ms/u/s!AqtIFlFVWz4MhNtBc3g1DQElfA6_7Q?e=y7ly37

Thank you for you response!

vinkovsky
  • 310
  • 4
  • 16

2 Answers2

2

Woow! this is a very good code example! And it works pretty smooth too. It shows the problem a lot better.

I found a solution for the first problem (that is kind of a three.js problem) in the fabric js demo: http://fabricjs.com/controls-customization. I'm not good with fabric so there might be a more elegant solution than this. You can hide the controls, render to three.js and then show them again. You also have to force the canvas to render, it won't work otherwise.

function animate() {
    requestAnimationFrame(animate);

    //find the selected object on the fabric canvas
    let selected = canvas.getActiveObject();

    //hide controles and render on the fabric canvas;
    if (selected){
        selected.hasControls = false;
        selected.hasBorders = false;
        canvas.renderAll();
    }

    //update texture and render
    texture.needsUpdate = true;
    renderer.render(scene, camera);

    //show controls and render on the fabric canvas
    if (selected){
        selected.hasControls = true;
        selected.hasBorders = true;
        canvas.renderAll();
    }    
}

The second problem is a bit harder to understand. I'm not sure what the 'lower canvas' is and if that is a part of fabric that i don't understand. This is the closest i can get. I almost made it work on the three.js renderer. If i understood the idea correctly...

You need to have a variable to know if you are pressing the mouse or not. Only if you are pressing the mouse AND moving the mouse, it draws a circle.

To do the same with fabric 'mouse:move' you will at least have to disable that selectionbox on the fabric canvas. But i do not know how that works in fabric.

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var mouseDown = false;///////////////////////////// global boolean
var onClickPosition = new THREE.Vector2();



container.addEventListener("mousedown", function(){
    mouseDown = true;
    canvas.selection = false;
    onMouseEvt(); //draw circle
}, false);

container.addEventListener("mouseup", function(){
    mouseDown = false
    canvas.selection = true;
}, false);

container.addEventListener("mousemove", function(e){
    if (mouseDown){
    onMouseEvt(); //draw circle
    }
}, false);


///This code does not work, it goes into selection mode..
canvas.on('mouse:down', function(){
    mouseDown = true;
    addCircle(); 
}, false);

canvas.on('mouse:up', function(){
    mouseDown = false;
}, false);

canvas.on('mouse:move', function(){
    if ( mouseDown ){
        addCircle(); 
    }
}, false);
Ethan Hermsey
  • 930
  • 4
  • 11
  • O yeah, I've you are open to other options than fabric, maybe p5.js is something interesting? It does not support these awesome controls though. But if you aim for more 'drawing' then moving/rotating squares, that could work easier. – Ethan Hermsey Nov 24 '19 at 02:03
  • Hello @Ivan! First, much thanks for your examples! The first case works perfectly. For second: Fabric object creates two canvases with to classes - upper-canvas and lower-canvas. You can see it in the dom elements. I`m trying to develop brush that draws on lower canvas and this is what I got: https://codepen.io/vinar22/pen/VwZpaVd?editors=1111 However, I think its not good realisation – vinkovsky Nov 24 '19 at 06:29
  • Also i saw this question: https://stackoverflow.com/questions/51370679/fabrics-how-to-render-free-drawing-content-before-mouse-up?rq=1 Maybe its useful, but i have no idea how to integrate it in my code – vinkovsky Nov 24 '19 at 06:35
  • That seems to work fine.. Does it not do what you want it to do? I'm sorry i can't help you with that problem, i'm not good enough with fabric. Maybe try another post in the fabricjs stackoverflow, with only that second problem. I still don't understand what the functions of those upper/lower canvasses are :p i can see them but i dont know why there are two.. I do like the project, good luck with building it :) – Ethan Hermsey Nov 24 '19 at 14:28
  • Thank you Ivan! I marked your post as answer. Good luck you too! – vinkovsky Nov 24 '19 at 16:19
1

This is a hard question and it's not really a three.js thing, it has more to do with fabric.js and drawing to a canvas. The three.js part of texturing the object seems to work fine.

If I understand correctly you have an overlaying canvas on which you want to render the controls, but they are also rendered to the actual texture canvas? If in case you are actually rendering the controls on the texture; don't do that :p

It should be possible to make it work the way you want to. It would be helpful to post a small code example on https://jsfiddle.net/ or something.

Ethan Hermsey
  • 930
  • 4
  • 11
  • 1
    Hello @Ivan Hermse! Thank you for your reply. You can see on this example https://codepen.io/vinar22/pen/RwbpJeB – vinkovsky Nov 23 '19 at 15:20