screenslot in the pixijs webgl screenslot problem - pixi.js

i use screentslot in pixijs webgl
but get base64 image width and height is not canvas's width and height
how can i do it
this my code
var app = new PIXI.Application({
width: 750,
height: 750,
transparent: true
});
$('body').html(app.view);
const perlin = PIXI.Sprite.from('https://wxserver.knowway.cn//caitongxiaonian/images/4/p4_wrap1_wrap2_4.png');
app.stage.addChild(perlin)
setTimeout(function(){
var xss=app.renderer.extract.canvas(app.stage);
let base64Img = xss.toDataURL('image/png')
console.log(base64Img);
},3000)
https://codepen.io/a6965921/pen/wvoBQde

Related

Set coords for Bounding Rect of a Path after moving it in fabricjs

There are dozen of topics on Stackoverflow on this problem, none of them shows a solution. So the problem is painful for many.
The problem: when I move a path, it's BoundingRect is not moving.
Possible solutions:
the creators of the library recommend _setPath method, but there are no examples, I can't understand how to use it;
Somehow to set Left, Top, Width and Height separately to the bounding rect (pathLine.getBoundingRect()). I don't know how, it's not working with Set().
To set Left, Top, Width and Height to the path. If I do so, the bounding rect is correct, but pathline is also shifting. I can't make it work.
delete and add path from canvas every time it moves. Bad solution :(
Remarkable that _calcDimensions() works correct with path coords.
Which means there are methods that work with path, we just need to find a proper one.
var pathLine = new fabric.Path('M 10 10 L 10 100 L 100 100', {
fill: '',
stroke: 'black',
objectCaching: false
})
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'grey',
width: 50,
height: 50,
});
function createCanvas(id){
canvas = new fabric.Canvas(id);
canvas.add(pathLine);
canvas.add(rect);
pathLine.perPixelTargetFind = true;
canvas.on('object:moving', function(e) {
rect.setCoords();
const { width, height, left, top } = pathLine._calcDimensions();
var bound = pathLine.getBoundingRect();
pathLine.path[2][1] = rect.left ;
pathLine.path[2][2] = rect.top ;
canvas.renderAll();
});
return canvas;
}
Any ideas?

How to render a circle in pixijs

i'm banging my head to wall. I cannot render simple circle in pixijs. Any healp appreciated?
Playgroud link - https://pixiplayground.com/#/edit/eE~VcTxQSEi_I_DZk6Agz
If you are just trying to render a circle, this is all you need:
var app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x2c3e50
});
document.body.appendChild(app.view);
const gr = new PIXI.Graphics();
gr.beginFill(0xffffff);
gr.drawCircle(30, 30, 30);
gr.endFill();
app.stage.addChild(gr)
Here is a working example: https://www.pixiplayground.com/#/edit/5_EeuD2_YmdV8oleXRZ2P

how to stretch image size to match fabric.Image object

I am using fabricjs to implement image editing and I try to use a fabric.Image object as the background image of canvas to store the data. And the following is the code:
var canvas = new fabric.Canvas('canvasId');
var imageObject = new fabric.Image($originImage);
canvas.add(imageObject);
but I found the $originImage's size is much larger than canvas' size and also imageObject's size, so the canvas can only show part of the image. I want to know how to stretch the $originImage to adapt the canvas then canvas can display all of the $originImage?
Here what I have done
$canvas.width = $originImage.clientWidth;
$canvas.height = $originImage.clientHeight;
var fabricCanvas = new fabric.Canvas('canvasId');
// canvas.setFabricCanvas(fabricCanvas);
var imageObject = new fabric.Image($originImage);
// fabricCanvas.add(imageObject);
// fabricCanvas.isDrawingMode = true;
fabricCanvas.setBackgroundImage(imageObject, fabricCanvas.renderAll.bind(fabricCanvas), {
scaleX: fabricCanvas.width / $originImage.naturalWidth,
scaleY: fabricCanvas.height / $originImage.naturalHeight
});
the upper is my related code and below is the display:
it is solved, and the previous question is because I resize the $originImage first, so when I input the image src as setBackgroundImage's parameter, it can display normally.
For version 2.0 of fabricjs, they have changed the way to handle width/height compared to previous version. If you apply width/height, then it basically crop the image to that particular size compared to the original image size. In order to resize it to a proper size, you have to switch to use scaleX/scaleY like other people have suggested.
For example, I use image.fromUrl to load an image and set it to be the background:
fabric.Image.fromURL(imgUrl, function(img) {
img.set({
scaleX: currentWidth / img.width,
scaleY: currentHeight / img.height,
top: topPosition,
left: leftPosition
originX: 'left', originY: 'top'
});
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
});
where currentWidth/currentHeight can be your canvas size if you want full background or they can be a specific width/height that you want (in my project, I want to do letter-boxed image instead so I set the width and height based on my letter-boxing algorithm), and top/left is the location that you want to place your image in the canvas (leave it none if you want to be full background image). Do not set any width and height since that will crop the scaled image rather than setting the image to be the exact size.
If this does not work, check the backgroundImage object from the canvas and see if its dimension and scale properties are different compared to a manual calculation. If you take a look, you will see the width and height properties are your natural image width and height, but it will have scaleX and scaleY less than 1 if your canvas size is less than the image size or more than 1 if it is bigger.
Also I see you are loading image directly into an image object. That might be different compared to load the data and set it directly using setBackgroundImage.
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
scaleX: canvas.width / $originalImg.naturalWidth,
scaleY: canvas.width / $originalImg.naturalHeight
});
use scaleX,scaleY to resize.
(function() {
var $originalImg = $('#originalImage')[0];
console.dir($originalImg)
var canvas = this.__canvas = new fabric.Canvas('c');
var img = new fabric.Image($originalImg);
canvas.setBackgroundImage(img,canvas.renderAll.bind(canvas),{
scaleX:canvas.width/$originalImg.naturalWidth,
scaleY:canvas.width/$originalImg.naturalHeight
});
})();
canvas{
border-width: 1pz;
border-style: solid;
border-color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-rc.3/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id='originalImage'src='http://fabricjs.com/assets/pug_small.jpg'>
<canvas id='c' width=200 height=200></canvas>
I am using the following script to ensure the image is no larger than the canvas width:
var aspect = image.width / image.height; //Aspect ratio of image
new fabric.Image(image, {
scaleX: canvas.width / image.width,
scaleY: canvas.width / (image.height * aspect)
});

Canvas client size in fabric js

In a usual canvas css width and client width could be not equal to each other, how to get this on Fabricjs? As an example: I want 640*360px canvas on a page with 1280*720px image inside.
I know I could scale image, but dataUrl will give me a smaller picture, isn't it?
There is a solution. You could init Fabric.js with CSS sizes and then setDimensions with backstoreOnly flag or init with desired client size and use setDimensions with cssOnly flag.
Example #1:
var canvas = new fabric.Canvas('c', {width: 640, height: 360});
canvas.setDimensions({width: 1280, height: 720}, {backstoreOnly: true});
Example #2:
var canvas = new fabric.Canvas('c', {width: 1280, height: 720});
canvas.setDimensions({width: '640px', height: '360px'}, {cssOnly: true});
You can change the size of the canvas using the setWidth/setHeight properties of the canvas http://fabricjs.com/docs/fabric.StaticCanvas.html#setWidth
e.g.
canvas = new fabric.Canvas('c');
canvas.setWidth(640);
canvas.setHeight(360);
Though you should clarify what you mean.

how to set height and width of image in fabric.js?

I had loaded image in canvas using fabric.Image.fromURL and working fine with default image width and height.
Now I want to minimize width and height of an image.
How to do this?
Thanks in advance.
Hope this will help
var src; //Image source here
fabric.Image.fromURL(src, function(oImg) {
oImg.scaleToWidth(50);
oImg.scaleToHeight(50);
});
We can use scalex / scaley to set height / width as below.
fabric.util.loadImage(imgsrc, function (img) {
var legimg = new fabric.Image(img, {
left: 30,
top: marker.top,
scaleX: 20 / img.width,
scaleY: 20 / img.height
});
canvas.add(legimg);
canvas.renderAll();
});
Thanks
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 0, top: 0, angle: 00,width:100, height:100}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
canvas{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="450" height="450"></canvas>
We can set width and height.
Check this JSfiddle: https://jsfiddle.net/varunPes/8gt6d7op/5/
This working code I have tested:
fabric.Image.fromURL(el.src, function(image) {
image.set({
left: left,
top: top,
angle: 0,
padding: 10,
cornersize: 10,
hasRotatingPoint:true
});
image.scaleToHeight(100);
image.scaleToWidth(200);
canvas.add(image);
});
Work with the image scale properties and not the image size. This worked for me. When I had set the image width and height, and not the scale, when I applied a filter it reset back to original width and height because the scale was 1.0. Hope this helps.
Well I am not sure how are you trying to do it but you could while
adding the image use canvas object in the editor and pass it the Image
in a function called centerObject. Here is the code that worked for
me.
My ReactJS code centers a shirt image in the canvas as given below
const { editor, onReady } = useFabricJSEditor()
const add_image = () => {
fabric.Image.fromURL('assets/custom/shirt_green.png',(oImg) => {
oImg.scaleToHeight(240)
oImg.scaleToWidth(240)
editor.canvas.add(oImg)
editor.canvas.centerObject(oImg)
})
}
Over to the frontend UI we render using
<div>
<FabricJSCanvas className={styles.canvas} onReady={onReady} />
</div>

Resources