Draw New Path beneath Overlay Image - javascript

When I draw a new path in fabric.js isDrawingMode: true (right side of the screenshot) I want it to appear beneath my overlay image, that is a transparent png.
var canvas = this.__canvas = new fabric.Canvas('c', {
isDrawingMode: true,
preserveObjectStacking: true
});
var img = fabric.Image.fromURL(imgUrl, function(oImg) {
oImg.scaleToWidth(canvas.getWidth());
oImg.id="OverlayImage";
canvas.setOverlayImage(oImg, canvas.renderAll.bind(canvas));
});
It works as soon as I finish the path, though.
I experimented with multiply filter, and stacking order on mouse move event, but got nowhere.
Any idea how to solve this!
https://codepen.io/localhorst/pen/zYvKWqo

a 100% fabric solution would imply not to use the fabric brush/freeDrawingMod.
you could create your draw path and add it to the canvas as a fabric object by tracking mousedown and mousemove, updating your fabric path object each mousmove.
There is a nice explanation for creating a path object at the end of the page : http://fabricjs.com/fabric-intro-part-1
Simpler solution would be to set the image as a html element positioned on top of the canvas. with pointer-events disabled on the image you could click through and draw on the fabric canvas.
from your codepen:
<div class="row">
<img class="overlay" src="https://sandmoshi.github.io/eColorBook/pages/fox-trans.png"/>
<div class="col-8">
<canvas id="c" height="600" width="800" style="border:1px solid #aaa;"></canvas>
</div>
...
.overlay{
position:absolute;
top: 0;
left: 0;
z-index: 1000;
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
user-drag: none;
pointer-events: none;
}
i have forked your pen to demonstrate : https://codepen.io/TheNils/pen/QWjdEOR

Related

How to place tree or more canvases on top of one another?

I want three or more canvases overlay properly. I found similar topics (How to place two canvases on top of one another?), just can not do it for overlaying all 3 or 4 canvases together. After the 2nd canvas all other canvases renders below the second canvas.
What I want is a canvas for the base layer. A canvas for the color map and a canvas for the information, which i can click on the 3rd canvas and request the object
Code i'm using:
<style>
#wrapper{ position: relative; }
.canvas { position: absolute; top: 0; left: 0; }
</style>
<div id="wrapper">
<canvas class="canvas" id="canvast" style="z-index: -2;"></canvas>
<canvas class="canvas" id="canvast1" style="z-index: 1;"></canvas>
<canvas class="canvas" id="canvast2" style="z-index: -2;"> </canvas>
</div>
Note: fabric.js library canvas code to fill the canvases
canvas = new fabric.Canvas("canvast"); //(canvast1 etc.)
canvas.renderOnAddRemove = false; // faster loading of canvas
canvas.add(RectangleObject); //adding object
canvas.renderAll(); //rendering canvas
I don't know fabric.js, so I don't know how helpful my answer can be.
I made this jsfiddle : https://jsfiddle.net/xn78jzg3/4/
You can see layering three is not a Problem, even with most of your code (only thing I changed was the z-index on canvast2 from -2 to 2 and adding some Styling:
.canvas {
position: absolute;
top: 0;
left: 0;
border: #333 solid 2px;
width: 200px;
height: 200px;
}
).
So whatever goes wrong with the rendering of your 3rd Canvas, the error might come from fabric.js.

Is it possible to create a paper.js PointText object with multiple colors and font sizes?

I'm working on an image annotator that utilizes paper.js PointText objects for part of it. One thing we're looking into is allowing the user to highlight different parts of the text of a given PointText object with different colors and font sizes.
I saw the Gradient option on the paper.js website, but that would feel like more of a hack to get working, assuming it would work in the first place. Then I would have to get it to display properly in the textarea used for editing the PointText, which sounds even more hacky; I would like a cleaner solution.
Any solutions must allow the text to be draggable within the bounds of the canvas.
I don't have any code to show because I haven't found anything to try, but I wanted to see if the SO community is aware of any possible solutions.
I think text tools are still in development in Paper.js*, so I guess you have to create one PointText by color or use gradients as you suggested if you want to stick with Paper.js.
In my opinion you should really consider overlaying text on top of the canvas and handle styles with CSS. Here is an example:
html:
<canvas id="PaperCanvas"></canvas>
<div id="container">
<div id="text" contenteditable='true'>
Your text
</div>
</div>
coffeescript:
### ... some paper.js code ...
# drag & drop:
$('#container').mousedown (event)->
if event.target.id != "container"
return
global.drag = true
global.delta = new Point( $('#container').offset().left - event.pageX, $('#container').offset().top - event.pageY)
$("#text").addClass("noselect")
return
$("html").mousemove (event)->
if global.drag
$('#container').css( left: event.pageX + global.delta.x, top: event.pageY + global.delta.y)
return
$("html").mouseup (event)->
global.drag = false
$("#text").removeClass("noselect")
return
css:
canvas {
border: 1px solid black;
width: 500px;
height: 500px;
}
#container {
position: absolute;
top: 50px;
left: 50px;
padding: 20px;
border: 1px solid black;
background-color: 'red';
}
#text {
padding: 20px;
background-color: 'white';
border: 1px solid black;
}
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
*http://paperjs.org/reference/textitem/
The TextItem type allows you to create typography. Its functionality is inherited by different text item types such as PointText, and AreaText (coming soon).
Edit
You can then use html-to-canvas or rasterizeHTML.js to convert your colored text into an image that you can paste onto the paper.js canvas at the correct location. (You can use Raster to import your image into paper.js)

snap svg animation unwanted cropping

I have an svg animated with snap - mina.elastic. Due to the nature of this animation the paths I'm animating go beyond the size of the svg and crops the shapes. I want to see the strech of the whole path animation.
here is the HTML
<svg width="130px" height="113px" viewBox="0 0 130 113" id="svg">
</svg>
the CSS
body{
text-align: center;
padding: 2em;
background-color: #07AD91;
}
JS
s = Snap("#svg");
var firstShape = s.path("M119.297,113L119.297,113v-11.488H130l0,0V113H119.297z").attr({
fill: "#07AD91"
});
var secondShape = s.path("M0,11.488L0,11.488V0h10.703l0,0v11.488H0z").attr({
fill: "#07AD91"
});
firstShape.animate({ d: "M10.011,112.182L0,94.098l54.068-92.65l40.161,71.15H73.607L53.62,37.577L10.011,112.182z;" fill:"#46CEB4" }, 9000, mina.elastic);
secondShape.animate({ d: "M130,91.641H49.094l11.094-16.658h38.5L56.472,0h20.471l42.236,72.818L130,91.641z" fill:"#97E8DA" }, 9000, mina.elastic);
Here is the CODEPEN
I've tried enlarging the svg height and width but then the paths stay top left and crop there.
I just added this to the css to fix my issue
#svg{
overflow: visible;
}
I've just been working to solve this issue. I found this css selector overrides the overflow:hidden for SVG elements in Chrome and Firefox.
svg:not(:root) {
overflow: visible !important;
}

How to access bottom canvas layer in HTML?

I have such html:
<div id="main_window">
<canvas id="canvas_hex_logic" width="200" height="100"></canvas>
<canvas id="canvas_ground" width="200" height="100"></canvas>
</div>
and css:
#canvas_hex_logic{
position: absolute;
top:31px;
left:201px;
z-index: 0;
}
#canvas_ground{
position: absolute;
top:31px;
left:201px;
z-index: 1;
}
in #canvas_hex_logic I'm rendering mask for my hexagons:
over it I'm placing ground layer:
part of JS code, for picking color under mouse:
..... mouse event handler above .....
var c_hex = document.getElementById("canvas_hex_logic");
var ctx_hex = c_hex.getContext("2d");
..... ..... ..... ..... ..... .....
var color = ctx_hex.getImageData(mouseX, mouseY, 1, 1).data;
This code working, if #canvas_hex_logic is on tom of other layers.
So, question is - how to pick color under mouse from #canvas_hex_logic layer when it is overlayed with another layer?
Thanks!
Thanks!
Acuallty, I've founded easiest way:
#canvas_ground {
left: 201px;
pointer-events: none; <<--------- this helps
position: absolute;
top: 31px;
z-index: 1;
}
Get the coordinates of your click in the canvas that's on top and find the color at the corresponding pixel in the canvas that's below.
Click events have data associated to them that contains the coordinates of the click.
See this. Or rather, see this for even greater detail!

How to change the height and width of canvas using css while using fabric

As the title says everything. I want to change the size of my HTML5 canvas. I am using fabricjs library to work with HTML5 canvas. However, fabricjs makes the size of the canvas smaller. Now I want to its size using css but it does not affect it. When I give other css rules to canvas then it does affect but not width and height.
jsfiddle
Here is my fabricjs code
var canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
left: 50,
top: 50,
fill: 'red',
width: 100,
height: 100
});
canvas.add(rect);
here is my html
<canvas id="c"></canvas>
and here is my CSS
#c {
width: 100%;
border: 1px solid green;
}
Found the answer. Below solution works for me
var canvas = new fabric.Canvas('c');
canvas.setHeight(500);
canvas.setWidth(800);
Second solution is
<canvas id="c" width="900" height="600"></canvas>

Categories