I am using Fabric JS to allow the user to have an interactive experience on my React app. Is it possible to apply a frame around a Fabric JS that is taken from an image? For instance, if the canvas is 400x400 px I can resize an image of a frame that is transparent in the middle to 410x410px and apply it on top of the canvas for the user to see? I have attached two images for reference.
Edit: This is the code I am using for zooming in
const zoomIn = useCallback(() => {
// Get original height of canvas
const canvasDimensions = getInitialCanvasSize()
let zoom = HTML5Canvas.getZoom()
zoom += 0.2
if (zoom >= 2) zoom = 2
HTML5Canvas.setZoom(zoom)
HTML5Canvas.setWidth(canvasDimensions.width * HTML5Canvas.getZoom());
HTML5Canvas.setHeight(canvasDimensions.height * HTML5Canvas.getZoom());
}, [HTML5Canvas])
There is no option for canvas's border in fabricjs canvas docs
But you can still achieve this easily using following steps.
PART 1: Creating the Illusion of border
CSS Method
First one can easily create CSS border around the canvas.
Best way to do this is to create div around canvas, as fabricjs split canvas in 2 while running.
You can create slider to control width and color/image for div's border.
This will looks like exactly your second image with customization.
OR
Another Canvas Method
Behind current canvas put this second canvas and control its width and image.
I don't recommend this one, as this will make it more complex to implement.
PART 2: Making Illusion real
If you used CSS METHOD
Now you get what your canvas looks like. You have width of border, image/color of border.
Steps:
Create new canvas (lets' call it 2nd Canvas) of 410px if canvas's width 400px with border of 5px.
Export main canvas as image and put it over 2nd Canvas. And now you can export this as final image.
For 2nd step check my answer on this stack
If you used Another Canvas Method
Directly follow above 2nd step
Export main canvas as image and put it over 2nd Canvas. And now you can export this as final image.
For 2nd step check my answer on this stack
Related
I'm using konva.js to draw elements on an HTML Canvas. When the user finishes its design in the canvas, the creation can be exported into a PDF file. In this context, my HTML structure is the following:
a div "canvas" to append all the canvas
a div "canvas0/canvas1" and so on to append each konva-canvas
an auto-generated div "konvajs-content"
and finally, multiple canvases depending on the number of layers
So, to export the PDF I have to go through each div "canvas + number" and then go through each canvas childNodes to use the getContext('2d') and drawImage function to draw an Image with the contents of each canvas (hopefully this description is not too confusing...).
Well, I'm able to export the pdf with multiple pages according to the number of canvases drawn, but the image drawn from the canvas has very low quality. Finally, my doubt is, how can I export it with higher quality?
Theres a clever trick to i crease the resolution.
step 1
make your canvas twice bigger like this:
canvas.width=innerWidth*2;
canvas.height=innerHeight*2;
step 2
to make canvas cover entire width set its width and height from css like this:
canvas{ width:100%; }
thats it . At the end you will have doubled the image resolution and make sure you use width:100%; in css not as its attribute in html.
Hope that works for you.
If you are using Konva you should use its method to do an export.
stage.toDataURL()
If you want to increase quality of output image you can use pixelRatio property.
// it will produce 4x bigger image
stage.toDataURL({ pixelRatio: 2})
https://konvajs.org/docs/data_and_serialization/High-Quality-Export.html
I do have some pictures, and I need to crop them in a circular shapes before using them in React Native to use as ViroImage in react-viro (a library that render 360Images).
I can not apply much styles to the pictures and the borderRadius doesn't seem to solve my problem.
create a container with border radius = 30 and then place your image inside it
I've created react-native-image-tools-wm library when I had to process an image on the client and couldn't find anything worth using. Try it.
Example:
const image = Image.resolveAssetSource(require('./my-image.jpg)).uri;
const maskImage = Image.resolveAssetSource(require('./mask-image.png)).uri;
RNImageTools.mask(image, maskImage).then(({ uri, width, height }) => {
// Sync with your app state
});
Please note that your mask image should be black on white on iOS and black on transparent on Android. Black part will be replaced with your image and white/transparent will become transparent. You can use .android and .ios suffix on names and RN will load them conditionally.
You can also create a mask using createMaskFromShape method but you'll have to generate shape points yourself.
The problem: I'm trying to create a simple drawing app using p5.js. Instead of the standard cursor image, I'd like to show a circle at my cursor location that represents the size of the drawing brush.
Potential solution 1: Replace the cursor using the cursor() function native to p5.
Why it doesn't work: The p5 cursor function only takes the following parameters:
ARROW, CROSS, HAND, MOVE, TEXT, or WAIT, or path for image
As such, there's no native way to replace the cursor using the ellipse class.
Potential solution 2: Use the noCursor() function and then draw the circle at the cursor location, while also drawing the background, as such:
var brushSize = 50;
function setup() {
createCanvas(1080,720);
noCursor();
}
function draw() {
background(100);
ellipse(mouseX,mouseY,brushSize);
}
Why it doesn't work: While this solution gets the desired effect i.e. replacing the cursor with a circle the size of the brush, the constantly updating background prevents me from actually drawing to the canvas with the brush when I want to.
Is there some way I can replace the cursor without actually drawing the ellipse to the canvas? Is there any way to save and then instantly reload a canvas in p5? I couldn't find such a method searching through the API docs. Any hints are appreciated.
According to the reference, you can pass a URL into the cursor() function to set an image.
If you want to use an image that you draw, you're going to have to draw them ahead of time and save them to files, and then use those files. Something like this:
cursor('images/ellipse-15.png');
Where ellipse-15.png is an image that you generated ahead of time, to match when brushSize is 15, for example.
Btw P5.js is just setting the cursor CSS property. You can read more about it here.
If you want to go with the noCursor() approach and draw the ellipse yourself, you could draw your drawing to a buffer (the createGraphics() function is your friend) and then draw the ellipse on top of that every frame. I'd still probably use a cross cursor just because there's going to be some annoying lag if you draw it yourself.
Create a circular DIV inside the canvas container and show it on top of the actual canvas.
I've created a canvas that I've drawn images and texts on. Is it possible to add more space (height in my case) to the current canvas without having to redraw everything? I would like to add text below the already drawn items but to do this I have to add more height to canvas.
Or can I do it the other way around - create a too large canvas to start with and then add all my texts and in the end crop the canvas (removing white unused space)?
I like recursive's idea using a container that you first size short and then expand to reveal the extra canvas space needed to draw text.
Another common way of resizing a canvas is to bounce the canvas contents off a temporary canvas.
// create a temp canvas (no need to add it to the DOM)
var tempCanvas=document.createElement('canvas');
var tempCtx=tempCanvas.getContext('2d');
tempCanvas.width=mainCanvas.width;
tempCanvas.height=mainCanvas.height;
// draw the main canvas to the temp canvas
tempCtx.drawImage(mainCanvas,0,0);
// resize the main canvas
mainCanvas.height+=30;
// restore the main canvas content by drawing the temp canvas
mainCtx.drawImage(tempCanvas,0,0);
You could put your canvas inside a container with a fixed target height. If you set its overflow to hidden, then you can control how much can be seen.
Changing the dimensions of a canvas clear it, so that won't work.
Actually. I have created two canvas one containing some static content & over that another canvas containing some dynamic content. Now I have show snap of both the canvas with zoom in a separate canvas where the snap will change according to the moving object. I am using getImage & putImage but unable to zoom the image content. Even getImage is not working for the canvas contating dynamic content because security error is showing.
context.drawImage can use another canvas as its source image.
context.drawImage can scale the source image when drawing.
context.drawImage does not run afoul of CORS security like getImageData does.
For example, assume sourceCanvas has the original image located at coordinate[20,30] sized at 100x140.
If you have a context to the destination canvas, you can scale it 2X and draw it on the destination canvas at [50,60] like this:
context.drawImage(
sourceCanvas,
20,30,100,140, // grabs 100x140 pixels from sourceCanvas at [20,30]
50,60,200,280 // scale the grabbed pixels to 200x280 and draw it at [50,60]
);