KineticJS - Crop fill image - image

I'm trying to use a tileset in my game. I want to crop the fill image but can't because
I can't fill a shape with a Kinetic.Image() object.
I can't crop a Image() object.
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 64,
height: 64,
fill:{
image: imageObj,
crop:{
x: 128,
y: 128,
width: 64,
height: 64
},
},
strokeWidth: 1
});
This doesn't work, and I also can't replace image: imageObj with a Kinetic.Image() object that is precropped. Any ideas?
EDIT: Looks like it might be possible by drawing the Kinetic.Image to the scene, using toDataUrl to load the cropped Kinetic.Image into a image object useable by fill, then continue with the map script. This introduces a ton of performance issues/loading times so I'm going to go ahead and assume what I want to do just isn't feasible. If anyone has any ideas on how to do this properly please let me know.

You can get fill to accept an image, as shown in this example with the Vader/Yoda:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-set-fill-with-kineticjs/
What i'd suggest is loading your images into an array (as he does in the example) then calling the images out as you create the tile.
I changed the code for the first Pentagon to a Rectangle on that example like so:
var colorPentagon = new Kinetic.Rect({
x: 40,
y: 50,
width: 100,
height: 100,
fill: {
image: images.darthVader,
offset: [-220, -70]
},
stroke: "black",
strokeWidth: 4,
draggable: true
});
And it worked, so no reason that can't give you what you want.

Related

How to draw an inverted element on a layer in KonvaJS

is there any way to add a shape in KonvaJS which draws outside of it's boundries? Basically a "hole" in the layer, so that I can highlight a spot in the canvas by making everything around a circle darker (black with low opacity).
Any help is much appreciated!
Cheers
Edit:
Here is an image of what I mean (I'm not allowed to embed it yet):
https://i.imgur.com/gvTqgN0.jpg
I was hoping there might be something like this:
Konva.Circle({
x: 100,
y: 100,
radius: 50,
opacity: 0.3,
fill: 'black',
inverted: true
})
and this would then in turn "not draw" a circle, but everything around it would then take the given attributes. In this case it would all be darkend a bit besides the circle.
You can do this with a custom shape:
const shape = new Konva.Shape({
width: stage.width(),
height: stage.height(),
// what is color of background ?
fill: 'rgba(0,0,0,0.2)',
sceneFunc: (ctx, shape) => {
// draw background
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(shape.width(), 0);
ctx.lineTo(shape.width(), shape.height());
ctx.lineTo(0, shape.height());
ctx.lineTo(0, 0);
// now cut circle from the background
// we can do this by useing arc
const x = 200;
const y = 200;
const radius = 10;
// but it must be counter-clockwise
// so the last argument true is very important here
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);
ctx.fillStrokeShape(shape);
},
// remove shape from hit graph, so it is not visible for events
listening: false
});
Demo: https://jsbin.com/tevejujafi/3/edit?html,js,output

how can I free drawing on shapes in konvajs

I want to make free drawing on top of shapes at konvajs. like an exp; Can u give me advise about shapes attrs like zindex or smt.
https://ibb.co/jq9pUK
Your question is very broad and you are not showing what you have tried so far. You would get better help faster if you give a clear description and post cut-down sample code for your questions.
Konvajs works on top of the HTML5 canvas. When working with a konvajs you put shapes, lines, images and text on to layers. Layers have a z-order and shapes on a layer have a z-order.
To answer your question, I would follow the pattern:
- create the stage
- create the shape layer
- add the shapes to the shape layer - triangles, rectangles, circles, etc
- add another layer for the freehand drawing
- draw on this layer.
Because of the sequence of adding the components to the canvas the z-order will support what you ask for in your question. If you wanted the drawing to happen 'behind' the shapes you would create the layers in the opposite sequence.
The working snippet below shows how to do the steps that I have listed above, and how to listen for the events you need to make it operate. You can extend from this starter code to handle erasing, selecting line colour, thickness, and stroke style. See the Konvajs drawing tutorial for more information.
Good luck.
// Set up the canvas / stage
var s1 = new Konva.Stage({container: 'container1', width: 300, height: 200});
// Add a layer for the shapes
var layer1 = new Konva.Layer({draggable: false});
s1.add(layer1);
// draw a cirlce
var circle = new Konva.Circle({
x: 80,
y: s1.getHeight() / 2,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
})
layer1.add(circle)
// draw a wedge.
var wedge = new Konva.Wedge({
x: 200,
y: s1.getHeight() / 2,
radius: 70,
angle: 60,
fill: 'gold',
stroke: 'black',
strokeWidth: 4,
rotation: -120
});
layer1.add(wedge)
// Now add a layer for freehand drawing
var layer2 = new Konva.Layer({draggable: false});
s1.add(layer2);
// Add a rectangle to layer2 to catch events. Make it semi-transparent
var r = new Konva.Rect({x:0, y: 0, width: 300, height: 200, fill: 'blue', opacity: 0.1})
layer2.add(r)
// Everything is ready so draw the canvas objects set up so far.
s1.draw()
var drawingLine = null; // handle to the line we are drawing
var isPaint = false; // flag to indicate we are painting
// Listen for mouse down on the rectangle. When we get one, get a new line and set the initial point
r.on('mousedown touchstart', function () {
isPaint = true;
var pos = s1.getPointerPosition();
drawingLine = newLine(pos.x, pos.y);
drawingLine.points(drawingLine.points().concat(pos.x,pos.y));
layer2.draw();
});
// Listen for mouse up ON THE STAGE, because the mouseup will not fire on the rect because the mouse is actually over the line point we just drew when it is released.
s1.on('mouseup touchend', function () {
isPaint = false;
drawingLine = null;
});
// when the mouse is moved, add the position to the line points and refresh the layer to see the effect.
r.on('mousemove touchmove', function () {
if (!isPaint) {
return;
}
var pos = s1.getPointerPosition();
drawingLine.points(drawingLine.points().concat(pos.x,pos.y));
layer2.draw();
})
// Function to add and return a line object. We will extend this line to give the appearance of drawing.
function newLine(x,y){
var line = new Konva.Line({
points: [x,y,x,y],
stroke: 'limegreen',
strokeWidth: 4,
lineCap: 'round',
lineJoin: 'round'
});
layer2.add(line)
return line;
}
p
{
padding: 4px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>
<p>Click & drag on the canvas to draw a line over the shapes.
</p>
<div id='container1' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; position: relative;"></div>

Rotation and getBounds() in Phaser

I'm using Phaser 2.3.0 and I want to know the bounds of a rotated sprite.
But when I change sprite.rotation, the values of sprite.getBounds() don't change:
sprite = game.add.sprite(0, 0, "img"); // game.load.spritesheet("img", "grid.png", 32, 32);
console.log(sprite.getBounds()); // Object { x: 0, y: 0, width: 32, height: 32, type: 22 }
sprite.rotation = 0.52; // 30°
console.log(sprite.getBounds()); // Object { x: 0, y: 0, width: 32, height: 32, type: 22 }
What's wrong?
How can I get the correct bounds?
As far as I know, getBounds() will return the smallest possible rectangle that the object fits in and since Phaser.Rectangle doesn't have a rotation property, you will get the same rectangle both times.
It's being 6 years since this question, but just for the people who end up here after a Google search, the right answer is that the getBounds() is based on the object's worldTransform which is updated at the end of the render() cycle. So changing something in the object and in the next line trying to get its bounds will give you the old value. The solution is to wait a frame or call updateTransform():
const sprite = game.add.sprite(0, 0, "img");
console.log(sprite.getBounds());
// Phaser.Rectangle { x: 0, y: 0, width: 32, height: 32, type: 22 }
sprite.rotation = 0.52; // 30°
sprite.updateTransform();
console.log(sprite.getBounds());
// Phaser.Rectangle {x: -15.900164410999576, y: 0, width: 43.67037816068437, height: 43.67037816068437, type: 22}
https://photonstorm.github.io/phaser-ce/Phaser.Sprite.html#getBounds
Keep in mind that if the object is inside an hierarchy of objects, you should call updateTransform() in the highest object.

Kinetic.Image config cornerRadius doesn't work

I currently used KineticJS (version:4.2.0) to do something, but when I want to set corner radius for a kinetic image object, it seems it doesn't work at all. Do anyone have any ideas?
My code is like this:
var stage = new Kinetic.Stage({
container: 'container',
width: 901,
height: 532,
});
var bg = new Kinetic.Layer(); // slot's shell
var bgObj = new Image();
bgObj.onload = function() {
var item = new Kinetic.Image({
x: 0,
y: 0,
width: 901,
height: 532,
image: bgObj,
cornerRadius: 25
});
bg.add(item);
stage.add(bg);
};
bgObj.src = "background.png";
Thanks.
corner radius currently isn't implemented for Image. In fact there's an error with the documentation because only Rectangle supports rounded corners. Images will support rounded corners soon.

Showing image inside hexagon with html5 and kineticjs

I want to draw a hexagon and show an image inside that using html5.
I have tried it out but I am not getting image as the result.
I want to use kineticjs only for this.
Here is the code:
function hexagon(){
var stage = new Kinetic.Stage({
container: "container"
});
var layer = new Kinetic.Layer();
var hexagon = new Kinetic.RegularPolygon({
x: 100,
y: 100,
sides: 6,
radius: 100,
fill: {image: "css/images/logo.png"},
stroke: "royalblue",
strokeWidth: 2
});
// add the shape to the layer
layer.add(hexagon);
// add the layer to the stage
stage.add(layer);
}
fill takes an image object. Try the following:
var layer = new Kinetic.Layer();
logo = new Image();
logo.src = "css/images/logo.png";
var hexagon = new Kinetic.RegularPolygon({
x: 100,
y: 100,
sides: 6,
radius: 100,
fill: {image: logo},
stroke: "royalblue",
strokeWidth: 2
});
// add the shape to the layer
layer.add(hexagon);
// add the layer to the stage
stage.add(layer);
}
The author of KinectJS has written some really great tutorials. In this one he draws an image in a pentagon, as well as a few other things. Should be enough to help you.
http://www.html5canvastutorials.com/kineticjs/html5-canvas-set-fill-with-kineticjs/
I have got the solution.
Posting it late (better late than never)
It should be:
fill: {image: "css/images/logo.png", offset: [0, 0]}

Resources