Creating a repeating image during zooming for kineticJS? - javascript

I'm using KineticJS and trying to get proper zoom functionality. I have a layer to which I have appended a background image at the original dimensions I want.
However when I zoom in (via layer.setScale()), my image shrinks when zooming in along with everything else (leaving exposed white areas).
So how can I make my image repeat even when this happens? Here is the code I used to add my image:
var imageObj = new Image();
imageObj.onload = function() {
var image = new Kinetic.Image({
image: imageObj,
width: width,
height: height
});
// add the shape to the layer
main_layer.add(image);
// add the layer to the stage
stage.add(main_layer);
};
imageObj.src = 'images/blueprint_background.png';

Try to create rectangle and then fill it with the image.
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 2 * imageObj.width,
height: imageObj.height,
fillPatternImage: imageObj,
fillPatternRepeat: 'repeat-x'
});
This rectangle will repeat your image twice by Ox.
You can try to create long rectangle then when you will scale layer or you can dynamically resize rectangle as scale changes.

Related

Set background image for Fabric Canvas dynamically

I want to add draw shapes on a Image, so decided to use Fabric JS. I am able to get all shapes and objects working well. Now How do I background set exactly to Image. The Image is dynamic, I want to draw on top of that image, and basically store the annotations of objects for backend processing.
Existing solution using Canvas
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 903;
canvas.height = 657;
var background = new Image();
background.src = "http://www.samskirrow.com/background.png";
// Make sure the image is loaded first otherwise nothing will draw.
background.onload = function(){
ctx.drawImage(background,0,0);
}
Reference - https://stackoverflow.com/a/14013068/2094670
I like this solution.
Live Demo
My Current Fabric JS Code
// Initialize a simple canvas
var canvas = new fabric.Canvas("c", {
hoverCursor: 'pointer',
selection: true,
selectionBorderColor: 'green',
backgroundColor: null
});
// Define the URL where your background image is located
var imageUrl = "../dog.jpg";
// Define
canvas.setBackgroundImage(imageUrl, canvas.renderAll.bind(canvas), {
// Optionally add an opacity lvl to the image
backgroundImageOpacity: 0.5,
// should the image be resized to fit the container?
backgroundImageStretch: false
});
Html
<canvas id="c"></canvas>
Problem.
The image of dog is full hd image, however I see only portion of it. How to do render the background image to its actual height and width using Fabric Canvas ? Since Images are comming dynamically, I might not know exact height and width to hardcode it.
Here's the way to set canvas size base on image size via fabric.js.
It's done initiating the Fabric canvas inside the onload callback, that way we are able to get the image width and height, then set them into the setDimesions method.
img.onload = function () {
...
canvas.setDimensions({ width: img.width, height: img.height });
};
var imageUrl = "http://i.imgur.com/yf6d9SX.jpg";
var background = new Image();
background.src = imageUrl;
// wait for the image to load, then set Fabric Canvas on the callback that runs after image finishes loading
background.onload = function () {
var canvas = new fabric.Canvas("c", {
hoverCursor: "pointer",
selection: true,
selectionBorderColor: "green",
backgroundColor: null,
});
// set canvas width and height based on image size
canvas.setDimensions({ width: background.width, height: background.height });
canvas.setBackgroundImage(imageUrl, canvas.renderAll.bind(canvas), {
// Optionally add an opacity lvl to the image
backgroundImageOpacity: 0.5,
// should the image be resized to fit the container?
backgroundImageStretch: false,
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.1.0/fabric.min.js"></script>
<canvas id="c"></canvas>

How to save Zoomed and Panned Canvas to dataUrl in Javascript

I build a canvas Element in which you can zoom and pan a background image and by click you can add Icons on it. It is built on fabric js.
So once I added icons and zoomed and panned, I would like to save the image to dataurl. If I just use canvas.toDataURL, I can only see the currently shown area. Does anybody have an Idea, how I can save the entire area of the background image with all elements on the canvas? I therefore need a function, which resets the zoom and the pan and adjusts the size of the canvas to the size of the background image.
I included an example of how initialized my canvas below.
// New Fabric Canvas
var canvas = new fabric.Canvas('c'); //render image to this canvas
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
canvas.setHeight(window.innerHeight);
canvas.setWidth(window.innerWidth);
canvas.renderAll();
}
// resize on init
resizeCanvas();
// Load image
var image = new Image();
image.onload = function() {
loadImage(image, canvas);
canvas.height = image.height;
canvas.width = image.width;
}
function loadImage(image, canv) {
var img = new fabric.Image(image, {
selectable: false,
lockUniScaling: true,
centeredScaling: true,
alignX: "mid",
alignY: "mid",
});
canv.add(img);
canv.centerObject(img);
}
image.src = 'http://placehold.it/350x150';
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.1.0/fabric.all.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvasarea" style="background: #000;">
<canvas id='c' onclick="return false;"></canvas>
</div>
If you just want to generate an image and not change the zoom level of canvas, you can pass multiplier parameter to toDataUrl function.
var dataURL = canvas.toDataURL({
format: 'png',
multiplier: 2
});
This will generate an image after zooming in 200%.
You can even specify the part of the canvas, you want to generate an image of by using:
var dataURL = canvas.toDataURL({
format: 'png',
left: 100,
top: 100,
width: 200,
height: 200
});
Check the details here, toDataUrl function:
http://fabricjs.com/docs/fabric.Canvas.html

How to apply a filter to a shape with image fill in KonvaJS?

I'm using Konva.js to do some canvas animations. I have circle shapes, with an image fill, and would like to apply a color overlay/filter to the shape (RGBA).
This is how I'm creating the Shape object:
var konvaObject = new Konva.Circle({
x: 100,
y: 100,
radius: 300,
stroke: this.color,
strokeWidth: 6,
fillPatternRepeat: 'no-repeat',
});
// load the image into the shape:
var imageObj = new Image();
imageObj.onload = function () {
konvaObject.fillPatternImage(imageObj);
konvaObject.draw();
}
imageObj.src = 'www.demo.com/anImageName.png';
demo: http://jsbin.com/winugimeme/edit?js,output
The Docs outline an RGBA filter, however as far as I can tell it can only be applied to Konva.Image items.
Is there a way to re-work my above code so that I can apply filters to the shape object/fill image?
According to filter documentation, you have to cache shape before applying filters http://konvajs.github.io/api/Konva.Filters.html#RGBA
node.cache();
node.filters([Konva.Filters.RGBA]);
node.blue(120);
node.green(200);
node.alpha(0.3);
Note: jsbin demo will not work with this example as fill image should be CORS enabled (e.g. hosted on same domain).

fabric js - Resize complete canvas according to a rectangle added in a canvas in order to achieve cropping

I am using fabric js for generating templates, I want user to set height and width of a canvas for which I am using following code
canvas.setHeight(height);
canvas.setWidth(width);
However on doing this, the full width canvas stretches itself and the object disappears from the resized canvas as it was lets say 500 px wide before and user resized it to 100px then the items disappear.
I want to achieve a functionality so that if a user wants to change the size of canvas then instead of resizing the canvas I will show a rectangle and user can move rectangle accordingly to get the visible area and once user clicks on save then I will resize the canvas according to that rectangle, so that I can process the SVG later for further conversions but by doing so I am not sure how to get the visible area in that rectangle to the resized canvas, in short I want functionality like Darkroom js but for fabric js canvas object.
The current functionality is added to this JS fiddle http://jsfiddle.net/tbqrn/102/
Finally after doing some research I am able to do that, instead of resizing the canvas I am adding a rectangle object with "cropper" type as mentioned below
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'transparent',
width: 400,
height: 400,
strokeDashArray: [5, 5],
stroke: 'black',
type: 'cropper',
lockScalingX: true,
lockScalingY: true,
lockRotation: true
});
canvas.add(rect);
This rectangle will serve as the cropper, when a user submits the form then I am getting that cropper's dimensions as follow along with changing canvas size
var i;
var croppedLeft = 0;
var croppedTop = 0;
var canvasJson = canvas.getObjects();
// Cropping canvas according to cropper rectangle
if (canvas.getObjects().length > 0) {
var i;
for (i = 0; i < canvas.getObjects().length; i++) {
if (canvas.getObjects()[i].type == 'cropper') {
croppedLeft = canvas.getObjects()[i].left;
croppedTop = canvas.getObjects()[i].top;
canvas.setHeight(canvas.getObjects()[i].height);
canvas.setWidth(canvas.getObjects()[i].width);
canvas.getObjects()[i].remove();
}
}
}
And after that I am shifting all the other canvas objects accordingly as follow.
for (i = 0; i < canvasJson.length; i++) {
canvas.getObjects()[i].left = canvas.getObjects()[i].left - croppedLeft
canvas.getObjects()[i].top = canvas.getObjects()[i].top - croppedTop
canvas.renderAll();
}
And after doing that I am able to achieve the desired functionality, hope this helps someone.
Here is my fiddle http://jsfiddle.net/tbqrn/115/

How to add a background color to Kinetic JS stage or layer?

I have a Kinetic JS stage and a layer
var stage = new Kinetic.Stage({
container: 'container',
width : STAGE_WIDTH,
height : STAGE_HEIGHT
});
var layer = new Kinetic.Layer();
I've set the page color to be #bbb.
body {
background: #bbb;
}
I'd like to set the canvas color to be white. But I can't seem to find a method or a way to add a background color to the stage itself or the layer that I add all the object on.
You can also set the background color of your container element through CSS. That's essentially the same as setting the background color of the stage. If you want a background at the layer level, you'll need to add a filled rectangle or similar, as previously mentioned.
I had the same problem, I wanted to add a "background". I added a rectagle with the 100% height and width, with this code:
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: stageDimensions.width, //full width
height: stageDimensions.height, //full height
fill: 'white', //background color
});
layer.add(rect);
Since I wanted to be able to remove the "background", this is how I manage to solve my problem.
Hope it helps you.
You can change the background color with JavaScript...
document.getElementById('container').style.background = '#fff';
There isn't an API method to add a background color.
Instead add a colored rectangle that covers the layer.
Of course, add the background rectangle before all other shapes.
Old question, but you can use the get properties of the stage, and fill a full rectangle, adding it to the layer before anything else. Sample code:
var stage = new Kinetic.Stage({
container: 'canvas-container',
width: 900,
height: 450
});
// create background
var stageBg = new Kinetic.Rect({
x: 0,
y: 0,
width: stage.getWidth(),
height: stage.getHeight(),
fill: "rgb(40,40,40)"
});
layer.add(stageBg);
stage.add(layer);

Categories

Resources