i want to draw a line beetween a circle everytime i add a circle on konva js. and the circle is dragable. so i want the line follow the circle when i drag it. How to do it? or maybe i'm doing it wrong. Here my code https://jsfiddle.net/nutsi/2L7v6hy3/13/
var stage = new Konva.Stage({
height: window.innerHeight * 0.85,
width: window.innerWidth * 0.85,
container: "konva"
});
var layer = new Konva.Layer();
stage.on("click", function(){
var points = [];
var pos = this.getRelativePointerPosition();
var dot = new Konva.Circle({
x: pos.x,
y: pos.y,
fill: 'red',
radius: 5,
id: "seljal",
draggable: true
});
layer.add(dot)
var a = layer.find("#seljal")
for(let x = 0; x < a.length; x++){
points.push(a[x].attrs.x, a[x].attrs.y)
}
var line = new Konva.Line({
points: points,
stroke: "red",
strokeWidth: 2,
dash: [5, 5],
opacity: 1,
closed: !0,
id: "line"
})
var b = layer.find("#line")[0]
if(b) b.destroy();
layer.add(line);
})
stage.add(layer);
stage.draw();
I'am trying to clip the FabricJS rect shape to the polygon shape. The clipping works okay until the polygon shape which need to be clipped is now scaled. After this there is some weird offset that is caused by the polygon clipping.
Can anyone help me how can i fix the function to prevent the polygon offset issue when clip object is scaled.
This is how it looks before scalling. The clipping works fine
Image => https://i.imgur.com/Eop2YJh.png
And then there is the problem when the polygon is scaled.
2: Image => https://i.imgur.com/ICkP8SG.png
Here is the code on fiddle with the clipping function
https://jsfiddle.net/0xpvc9uq/
So if there is anyone who knows whats the point and how can I fix it I would appriciate it.
Thx
var canvas = new fabric.Canvas('c');
var rect1 = new fabric.Rect({
left: 0, top: 0,
width: 900, height: 900,
fill: 'blue',
selectable: false,
clipTo: clipRegion,
scaleX: 1.5,
scaleY: 1.5
});
var clipPoly = new fabric.Polygon([
{ x: 180, y: 10 },
{ x: 300, y: 50 },
{ x: 300, y: 180 },
{ x: 180, y: 220 }
], {
originX: 'left',
originY: 'top',
left: 180,
top: 10,
fill: 'transparent', /* use transparent for no fill */
strokeWidth: 0,
selectable: false,
strokeWidth: 1,
stroke: "red",
scaleX: 1.3,
scaleY: 1.3
});
canvas.add(rect1, clipPoly);
function clipRegion (ctx) {
rect1.setCoords();
const clipObj = clipPoly;
const scaleXTo1 = (1 / rect1.scaleX);
const scaleYTo1 = (1 / rect1.scaleY);
ctx.save();
const ctxLeft = -( rect1.width / 2 ) - clipObj.strokeWidth - rect1.strokeWidth;
const ctxTop = -( rect1.height / 2 ) - clipObj.strokeWidth - rect1.strokeWidth;
ctx.translate( ctxLeft, ctxTop );
ctx.scale(scaleXTo1, scaleYTo1);
ctx.rotate((rect1.angle * -1) * (Math.PI / 180));
ctx.beginPath();
const matrix = clipPoly.calcTransformMatrix();
let points = [];
clipObj.points.forEach( (point) => {
points.push({
x: ((point.x * matrix[0]) + (clipObj.strokeWidth * clipObj.scaleX)) - rect1.oCoords.tl.x,
y: ((point.y * matrix[3]) + (clipObj.strokeWidth * clipObj.scaleY)) - rect1.oCoords.tl.y
});
});
ctx.moveTo(points[0].x, points[0].y);
points.forEach((point) => {
ctx.lineTo(point.x, point.y);
});
ctx.lineTo(points[0].x, points[0].y);
ctx.closePath();
ctx.restore();
}
I discovered that there is also another approach that can be used and that solves all the problem.
The clipRegion function now looks like:
function clipRegion (ctx) {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
clipPoly.render(ctx);
ctx.restore();
}
Which makes the rendering okay. If still anyone have other way to fix the above problem, I would like to see the answer
I am trying to edit another example that was posted on here but something doesn't seem right. I have a shape and then a couple of shapes that are grouped together with an arrow that is pointing in between the two shapes. As one of the shapes is dragged the arrow position should move as well.
The Problem
The problem is that the shape seems to be on a different coordinate system where its 0,0 point is in the upper left corner, whereas the groups coordinate system where its 0,0 point is right in the middle of the screen. What am I doing wrong?
Code
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.rawgit.com/konvajs/konva/0.13.0/konva.min.js"></script>
<meta charset="utf-8">
<title>Konva Circle Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
var group = new Konva.Group({
x:120,
y:120,
draggable: true,
});
var circle = new Konva.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 40,
fill: 'green',
stroke: 'black',
strokeWidth: 2,
});
var circleA = new Konva.Circle({
x: stage.getWidth() / 5,
y: stage.getHeight() / 5,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 2,
draggable: true
});
var arrow = new Konva.Arrow({
points: [circle.getX(), circle.getY(), circleA.getX(), circleA.getY()],
pointerLength: 10,
pointerWidth: 10,
fill: 'black',
stroke: 'black',
strokeWidth: 4
});
var star = new Konva.Star({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: '#89b717',
opacity: 0.8,
scale: {
x : 1.4,
y : 1.4
},
rotation: Math.random() * 180,
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: {
x : 5,
y : 5
},
shadowOpacity: 0.6,
});
//layer.add(star);
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
function adjustPoint(e){
var p=[circle.getX(), circle.getY(), circleA.getX(), circleA.getY()];
arrow.setPoints(p);
layer.draw();
console.log(group.getX(),group.getY());
console.log(circleA.getX(),circleA.getY());
}
//circle.on('dragmove', adjustPoint);
group.on('dragmove', adjustPoint);
circleA.on('dragmove', adjustPoint);
group.add(star,circle);
//group.add(circle);
layer.add(group);
layer.add(circleA);
// add the shape to the layer
//layer.add(circle);
layer.add(arrow);
//layer.add(star);
// add the layer to the stage
stage.add(layer);
</script>
</body>
</html>
When you put a shape on a group, it's getX() and getY() functions return values relative to the origin point of the group. Your error was to assume that the X, Y position of the circle in the group would change as the group is dragged.
In the working code below, based on your posted code, I changed only the first line of the AdjustPoint() function so that the X, Y position of the circle has added to it the X, Y position of the group.
This fixes your issue.
Tip: as you start using groups be aware that their extent on the page is that of the minimum rectangle needed to contain the group shapes. If you want to specifically control the size and location of a group, add to it a Rect() shape of specific width and height to give a known size to the group.
I also added a call to that function at the end of the code so that the arrow joins when the code initially runs.
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
var group = new Konva.Group({
x:120,
y:10,
draggable: true,
});
var circle = new Konva.Circle({
x: stage.getWidth() / 2,
y: 60,
radius: 40,
fill: 'green',
stroke: 'black',
strokeWidth: 2,
});
var circleA = new Konva.Circle({
x: stage.getWidth() / 5,
y: stage.getHeight() / 5,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 2,
draggable: true
});
var arrow = new Konva.Arrow({
points: [circle.getX(), circle.getY(), circleA.getX(), circleA.getY()],
pointerLength: 10,
pointerWidth: 10,
fill: 'black',
stroke: 'black',
strokeWidth: 4
});
var star = new Konva.Star({
x: stage.getWidth() / 2,
y: 60,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: '#89b717',
opacity: 0.8,
scale: {
x : 1.4,
y : 1.4
},
rotation: Math.random() * 180,
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: {
x : 5,
y : 5
},
shadowOpacity: 0.6,
});
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
function adjustPoint(e){
// changes here
var p=[ group.getX() + circle.getX(), group.getY() + circle.getY(), circleA.getX(), circleA.getY()];
// changes here
arrow.setPoints(p);
layer.draw();
stage.draw();
// console.log('group = ' + group.getX() + ', ' + group.getY());
// console.log('red circle = ' + circleA.getX() + ', ' + circleA.getY());
}
//circle.on('dragmove', adjustPoint);
group.on('dragmove', adjustPoint);
circleA.on('dragmove', adjustPoint);
group.add(star,circle);
//group.add(circle);
layer.add(group);
layer.add(circleA);
// add the shape to the layer
//layer.add(circle);
layer.add(arrow);
//layer.add(star);
// add the layer to the stage
stage.add(layer);
// changes here
adjustPoint();
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
<script src="https://cdn.rawgit.com/konvajs/konva/0.13.0/konva.min.js"></script>
<body>
<div id="container"></div>
</body>
I have a KONVA group with three object in it. I want to show/hide one object of the group.
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
const layer = new Konva.Layer();
stage.add(layer);
const group = new Konva.Group();
layer.add(group);
const circle1 = new Konva.Circle({
x: stage.width() / 2,
y: stage.height() / 2,
radius: 50,
fill: 'green',
visible: true
});
const circle2 = new Konva.Circle({
x: stage.width() / 2,
y: stage.height() / 2,
radius: 30,
fill: 'red',
visible: true
});
const circle3 = new Konva.Circle({
x: stage.width() / 2,
y: stage.height() / 2,
radius: 10,
fill: 'blue',
visible: true
});
group.add(circle1);
group.add(circle2);
group.add(circle3);
layer.draw();
//group.hide(); // if I use this it will hide entire group but i want to hide only one object
layer.draw();
I want to show/hide only the circle2 from the Konva group. can any one please help me?
just call hide method of circle2.
circle2.hide();
This circle2 is added in your group by reference. So if you make any change in circle2, it will reflect in group.
I am creating pie chart using multiple Kinetic.Wedges and a tween that moves the pieces out.
This works fine, but when I attempt to add
shadowColor: 'black',
shadowBlur: 2,
shadowOffset: 10,
shadowOpacity: 0.5
in the wedge instantiation it bugs out - the error "TypeError: b is undefined" comes up. If I comment out the tween instantiation the shape loads without error (with shadows) so I suspect something in tween instantiation is causing it.
Here is code for this purpose.
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200});
var splits = [{perc: 30, colour: "red"},
{perc: 15, colour: "blue"},
{perc: 20, colour: "green"},
{perc: 35, colour: "yellow"}];
var layer = new Kinetic.Layer();
var startPos = 0;
for (var i = 0; i < splits.length; i++){
(function(){
var wedge = new Kinetic.Wedge({
x: stage.getWidth() / 3,
y: stage.getHeight() / 2,
radius: 70,
angleDeg: toAngleDeg(splits[i].perc),
fill: splits[i].colour,
stroke: 'black',
strokeWidth: 1,
rotationDeg: startPos});
layer.add(wedge);
wedge.tween = new Kinetic.Tween({
node: wedge,
rotationDeg: 90 + (180 - (toAngleDeg(splits[i].perc)/2)),
x: stage.getWidth() / 1.5,
easing: Kinetic.Easings.EaseInOut});
startPos += toAngleDeg(splits[i].perc);
wedge.on('mouseup', function(){
wedge.setZIndex(100);
wedge.tween.play();}
);
})()}
stage.add(layer);
What am i doing wrong here?