I am trying to do a bit of experimentation with KinetiJs Canvas library. What I have done below is - Draw a Rectangle, and whenever there is a mouseover I want a line to be drawn between specific points.
The problem is, I do not see any line when a mouseover happens.
I have tried checking if the onmousemove function gets called or not and it does get called, but the line doesn't get drawn. Can anyone please explain why?
$(document).ready(function () {
var stage = new Kinetic.Stage({
container: "sketchcanvas",
width: 600,
height: 600
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 50,
y: 50,
width: 500,
height: 500,
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4
});
rect.on("mousemove", function () {
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y;
var line = new Kinetic.Line({
points: [60, 60, 80, 80, 100, 200],
stroke: "black",
strokeWidth: 15,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
});
layer.add(rect);
stage.add(layer);
});
In KineticJS, after you make alterations or additions to a layer, you need to draw() to the layer for effects to show
...
layer.add(line);
layer.draw();
Related
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 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 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?
I have following codes for a Rect by kinetics, why I could not resize the rect though I have resize properties defined in the rect.
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
resize: true
});
// add the shape to the layer
layer.add(rect);
// add the layer to the stage
stage.add(layer);
KineticJS has no resize property.
You have to resize manually:
rect.setSize(newWidth,newHeight);
layer.draw();
Is there a simple way to "stamp" a transparent section from within another shape (or layer) using KineticJS?
For example, using the following code:
var stage = new Kinetic.Stage({
container: 'canvas',
width: 100,
height: 100
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 1,
y: 1,
width: 96,
height: 96,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
layer.add(rect);
var star = new Kinetic.Star({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
numPoints: 5,
innerRadius: 15,
outerRadius: 40,
fill: 'yellow'
});
layer.add(star);
stage.add(layer);
How would I make the star shape within the green box transparent so that elements behind the canvas are visible. Here's an example fiddle: http://jsfiddle.net/ZPVxa/
I have looked into filters, and I think that may be the way to go, but I can't seem to find what I'm looking for in the documentation.
You can use a Kinetic Shape Object to do custom drawing, including your star cut-out
The Shape gives you access to a context which gives you access to the full range of canvas operations.
The operation needed for “cutting” your star from your background is globalCompositeOperation.
The “destination-out” composite will cut out the next drawn shape (your star) from any existing drawings (your green rect).
Here is how you draw the green rect and use composition to cut out the star.
var rect = new Kinetic.Shape({
drawFunc: function(canvas){
context=canvas.getContext("2d");
context.save();
context.beginPath();
context.rect(0,0,96,96);
context.fillStyle="green";
context.fill();
context.globalCompositeOperation="destination-out";
drawStar(context,45,50,5,40,15);
canvas.fillStroke(this);
context.restore();
},
width: 96,
height: 96,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
Since the star is not a native canvas shape, you will also need this code to draw a star:
function drawStar(ctx,cx,cy,spikes,outerRadius,innerRadius){
var rot=Math.PI/2*3;
var x=cx;
var y=cy;
var step=Math.PI/spikes;
ctx.strokeSyle="#000";
ctx.beginPath();
ctx.moveTo(cx,cy-outerRadius)
for(i=0;i<spikes;i++){
x=cx+Math.cos(rot)*outerRadius;
y=cy+Math.sin(rot)*outerRadius;
ctx.lineTo(x,y)
rot+=step
x=cx+Math.cos(rot)*innerRadius;
y=cy+Math.sin(rot)*innerRadius;
ctx.lineTo(x,y)
rot+=step
}
ctx.lineTo(cx,cy-outerRadius)
ctx.closePath();
ctx.fill();
}
That’s pretty much it!
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/VVrZT/
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.3.min.js"></script>
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var rect = new Kinetic.Shape({
drawFunc: function(canvas){
context=canvas.getContext("2d");
context.save();
context.beginPath();
context.rect(0,0,96,96);
context.fillStyle="green";
context.fill();
context.globalCompositeOperation="destination-out";
drawStar(context,45,50,5,40,15);
canvas.fillStroke(this);
context.restore();
},
width: 96,
height: 96,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
layer.add(rect);
layer.draw();
function drawStar(ctx,cx,cy,spikes,outerRadius,innerRadius){
var rot=Math.PI/2*3;
var x=cx;
var y=cy;
var step=Math.PI/spikes;
ctx.strokeSyle="#000";
ctx.beginPath();
ctx.moveTo(cx,cy-outerRadius)
for(i=0;i<spikes;i++){
x=cx+Math.cos(rot)*outerRadius;
y=cy+Math.sin(rot)*outerRadius;
ctx.lineTo(x,y)
rot+=step
x=cx+Math.cos(rot)*innerRadius;
y=cy+Math.sin(rot)*innerRadius;
ctx.lineTo(x,y)
rot+=step
}
ctx.lineTo(cx,cy-outerRadius)
ctx.closePath();
ctx.fill();
}
</script>
</body>
</html>