I'm trying to create a T-Shirt editor using Fabric. I set a shirt as a background image on the canvas. Now I'm trying to get an area in the middle of the T-shirt that will act as a clipping mask. I only want objects that are inside this area to be visible.
Here's my code: http://jsfiddle.net/mtb2p3Lx/4/
var canvas = new fabric.Canvas('c');
// set background
fabric.Image.fromURL('https://qstomizr.s3.amazonaws.com/11102-9LDAQLKA1585254870.5083.jpg', (img) => {
canvas.setBackgroundImage(img, null, {
originX: 'center',
originY: 'center',
top: canvas.getCenter().top,
left: canvas.getCenter().left,
stroke: 'black',
strokeWidth: 1,
});
canvas.renderAll();
});
// set masking area
var area = new fabric.Rect({
originX: 'center',
originY: 'center',
top: this.canvas.getCenter().top,
left: this.canvas.getCenter().left + 10,
width: 250,
height: 300,
selectable: false,
fill: 'transparent',
stroke: 'black',
strokeWidth: 2,
});
canvas.add(area)
// set example rect
var rect = new fabric.Rect({
originX: 'center',
originY: 'center',
top: this.canvas.getCenter().top + 50,
left: this.canvas.getCenter().left + 150,
height: 100,
width: 100,
fill: 'pink',
});
canvas.add(rect)
I tried adding a clip path to the area rect, also tried playing around with globalCompositeOperation, but I couldn't get anything to work without having to sacrifice the background image.
Is there a way to get the transparent area rect to act as a clipping mask for the other objects in the canvas?
As you can see on this site https://printio.ru/tees/new_v2. For implementing background image was used img tag without setBackgroundImage. And I make an example for you here
https://jsfiddle.net/RamanNikitsenka/4suna7yo/1/
Related
I use a clipping area with fabric.js to create a graph. However, the grid lines look different on a canvas size bigger than about 1000px. It only occurs with imageSmoothingEnabled: false. See the image. Note: the size of the frames have nothing to do with the size of the canvas.
To create the grid lines, I create one original that is wider than the area, and then clone them. The cloned lines are added to the clipArea object. Here is the relevant code.
HTML:
<canvas id="canvas" width="966" height="520"></canvas>
Javascript:
var canvas = new fabric.StaticCanvas('canvas', {
imageSmoothingEnabled: false
});
var rect = new fabric.Rect({
originX: 'left',
originY: 'top',
fill: 'transparent',
width: x1-x0,
height: y1-y0
});
var clipArea = new fabric.Group([rect], {
originX: 'left',
originY: 'top',
width: canvas.width*2,
height: canvas.height*2,
left: -canvas.width,
top: -canvas.height
});
rect=clipArea.item(0)
rect.set({left: x0,top: y0});
clipArea.clipPath = rect;
canvas.add(clipArea);
var yline = new fabric.Line([0, 0, 1200, 0], {
originX: 'left',
originY: 'center',
stroke: myFrameColor,
strokeWidth: 2,
strokeDashArray: [1, 3.4]
});
// clipArea.add(yline)
Of course I could draw the gridlines in a different way without using clipping, but I need a clipping area anyway. And I'd like to understand why this is happening.
I am working on image cropper using fabric js version 1.7.22.
As usually, every cropper display black transparent overlay over the image (where image look like dull), and also display one Rect. (crop Area where image look full with color).
we can create this functionality using fabric js with background image and fabric.Rect object.
My problem is that when I use GlobalCompositeOperation with destination-out property to fabric.Rect object. It will make hole through canvas.
In simple word :
when I add globalCompositeOperation to destination-out, it will make hole through canvas also.
Expected result of canvas:
Current Result of canvas:
I have made one codepen for demonstration :
https://codepen.io/mayurkukadiya0/pen/zYYWOGL?editors=0110
I have found one codepen also for do same but they are add multiple canvas for display image in separate layer and rect and overlay in separate layer
Is there any way to do this without add external any canvas or css image behind canvas ?
Here is that reference : https://codepen.io/s0nnyv123/pen/eravaN
try using setOverlayImage
here'a demonstration, based on your codepen
var canvas = new fabric.Canvas('canvas', {preserveObjectStacking: 'true'});
canvas.setHeight(300);
canvas.setWidth(300);
canvas.setOverlayImage('https://images.pexels.com/videos/856973/free-video-856973.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500', canvas.renderAll.bind(canvas), {
top: 0,
left: 0,
width: 300,
height:300,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
selectable: false,
globalCompositeOperation: 'destination-atop',
});
var overlay = new fabric.Rect({
left: 0,
top: 0,
width: 300,
height: 300,
fill: '#00000050',
selectable: false,
globalCompositeOperation: 'source-over'
});
canvas.add(overlay);
var rect = new fabric.Rect({
left: 100,
top: 100,
width: 100,
height: 100,
fill: '#451245',
globalCompositeOperation: 'destination-out'
});
canvas.add(rect);
canvas.renderAll();
I want to clip image, BUT default clipping behaviour just hiding a part of image which out of border. Is there a way to make it visible and set less opacity for overflowed content?
There's one of old clipping examples I told about. It also using lodash to bind clip name to object:
return _.bind(clipByName, pug)(ctx)
Is there a way to replace this functionality with vanilla es5?
I found unclear solution. Again.
Background color of canvas could make an opacity and background image could be clipping object (w/o clipping by itself).
Also, loaded image shoul define globalCompositeOperation set to source-atop.
var canvas = new fabric.Canvas('c');
var clipingRect = new fabric.Rect({
originX: 'left',
originY: 'top',
top: 50,
left: 50,
height: 300,
width: 300,
fill: 'white',
selectable: false
});
canvas.backgroundColor = 'rgba(255,255,0,0.5)';
canvas.setBackgroundImage(clipingRect);
fabric.Image.fromURL('http://placeimg.com/640/480/any', function(fimg) {
canvas.add(fimg.set({
left: 0,
top: 0,
width: canvas.getWidth(),
height: canvas.getHeight(),
globalCompositeOperation: 'source-atop'
}));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.12/fabric.min.js"></script>
<canvas id="c" width="400" height="400"></canvas>
In this jsfiddle I have an IText with fontWeight: 'normal', still the font is displayed with bold letters. How to make this text NOT bold?
Javascript:
var canvas = new fabric.Canvas('c');
var text = new fabric.IText('This is the text',{
left: 20,
top: 20,
fontFamily: 'Arial',
fontWeight: 'normal',
fontSize: 18,
stroke: 'black',
fill: 'black'
});
canvas.add(text);
The stroke effect makes it appear bold.
The text itself has the normal standard weight, here is a comparison without the stroke effect.
var text = new fabric.IText('This is the text',{
left: 20,
top: 20,
fontFamily: 'Arial',
fontWeight: 'normal',
fontSize: 18,
fill: 'black'
});
This is just because of stroke, if you remove the stroke then you will get fontweight:'Normal', please find the fiddle https://jsfiddle.net/Gauravkakkar25/ruoa19r7/1/
i use fabric.js library for my html5 canvas application.
i create group of objects that i need to have stable text objects (stable position), while i rotate the group object.
to achieve that , i created a group object with the 2 texts and i added inside the parent group object.
on the 'object:rotation' event , i find the inside group and i keep the angle stable :
if (obj.type == 'group'){
obj.angle = -actObj.angle;
actObj.setCoords();
canvas.renderAll();
}
please take a look at my fiddle example :
if i change the top position of the texts , their position is not stable when they rotate, I have to put top:-5 on the 1st text and top:5 on the 2nd text.
If i put top:-10 on the one text object and top:0 on the other , they are not stable on rotation
var text = new fabric.Text(N, {
fontSize: fontSizeTable,
fontWeight: 'bold',
originX: 'center',
originY: 'center',
top: -5,
fill: 'black'
});
text2 = new fabric.Text('table name rotonta', {
fontSize: fontSizeTable,
fontWeight: 'bold',
originX: 'center',
originY: 'center',
top: 5,
fill: 'black'
});
My jsfiddle example is here : http://jsfiddle.net/tornado1979/x5q34etw/55/
You need to put the group in the center by setting top to 0:
var textsGroup = new fabric.Group(texts, {
originX: 'center',
originY: 'center',
top:0,
objectGroupType: 'texts'
});
Updated fiddle : http://jsfiddle.net/x5q34etw/63/