Displaying value on KineticJs Text() - javascript

I want to change the text in my container for kinetic js using keyup event in jquery but it doesn't display. I tried getting the value then display it on a span element and it works fine.
Here's my code:
var stage = new Kinetic.Stage({
container: 'canvasContainer',
width: 800,
height: 800
});
var layer = new Kinetic.Layer();
var message = '';
$(function(){
$('#txtArea').change(function(){
message = $(this).val();
$('.output').text(message);
var simpleText = new Kinetic.Text({
x: 0,
y: 10,
text: message,
fontSize: 30,
fontFamily: 'Calibri',
fill: 'blue'
});
layer.add(simpleText);
}).keyup(function(){
$(this).change();
});
});
stage.add(layer);

After you add or change a Kinetic object, be sure you call layer.draw() to cause the drawing to be visible.
BTW, instead of adding a new simpleText with each change, you might want to just change the text in the existing text object
// declare simpleText before .change()
var simpleText = new Kinetic.Text({
x: 0,
y: 10,
text: "",
fontSize: 30,
fontFamily: 'Calibri',
fill: 'blue'
});
layer.add(simpleText);
// then inside .change()
simpleText.setText(message);
layer.draw();

Related

How to track the clickable element over a HTML5 canvas

I am creating a editor in which I have used kinetic js. In my editor there is dynamic text which are draggable, but in case of editing text I need to get the click element for individual text over the canvas so that when user click on a text I can track that and edit that text .
Here is the script
var stage = new Kinetic.Stage({
container: 'editor',
width: 600,
height: 600
});
var boxLayer = new Kinetic.Layer();
var rectX = 0;
var rectY = 0;
stage.add(boxLayer);
function add_text() {
alert('test');
var complexText1 = new Kinetic.Text({
x: 25,
y: 25,
text: 'Designer',
fontSize: 18,
fontFamily: 'Calibri',
fill: '#555',
width: 150,
padding: 20,
align: 'center',
draggable: true
});
boxLayer.add(complexText1);
boxLayer.draw();
complexText1.destroy();
complexText1.on('mouseover', function() {
this.fill('orange');
});
}
also I have user complexText1.destroy(); and after this draggable function is not working . I am new in canvas editor so need help to create it, any help regarding this will be appreciable.

get position of canvas element after drag relative to canvas

I double click on a canvas to create an element, and the user can do this n times. Each element is draggable.
For each element, if I drag it to within a certain rectangle of x/y coordinates, I want to then clearRect() within that rectangle, effectively deleting the dragged element.
How implement this?
Current:
var stage = new Kinetic.Stage({
container: 'container',
width: 662,
height: 983
});
var layer = new Kinetic.Layer();
stage.add(layer);
$(stage.getContent()).on('dblclick', function (event) {
var pos = stage.getMousePosition();
var mouseX = parseInt(pos.x);
var mouseY = parseInt(pos.y);
var text = new Kinetic.Text({
x: mouseX,
y: mouseY,
text: cc,
fill: "blue",
draggable: true,
});
layer.add(text);
layer.draw();
}
You can use yourElement.on("dragend",handler) to test if the element is inside the deletion rectangle.
If it is inside you can use yourElement.destroy() to destroy that element.
Example code and a Demo: http://jsfiddle.net/m1erickson/jqPhe/
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
// define the boundaries of the deletion box
var dx=200;
var dy=40;
var dw=100;
var dh=100;
// create the deletion box
var deleteMe=new Kinetic.Rect({
x:dx,
y:dy,
width:dw,
height:dh,
stroke:"red"
});
layer.add(deleteMe);
var label=new Kinetic.Text({
x:dx,
y:10,
text:"Drag here to delete\n(Must be fully inside)",
fill:"black"
});
layer.add(label);
// create a circle element for testing purposes
var circle1 = new Kinetic.Circle({
x:100,
y:100,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
// on dragend: test if this circle is inside the deletion rectangle. If yes, delete this circle.
circle1.on("dragend",function(){
var x=this.getX();
var y=this.getY();
if(x>=dx && x<=dx+dw && y>=dy && y<=dy+dh){
this.destroy();
layer.draw();
}
});
layer.add(circle1);
layer.draw();

How can I make a Kinetic.Line fire an event like the other Kinetic shapes?

You can interact with this code here on jsFiddle
In the fiddle you can see that I have made a flag (Kinetic.Rect) on a flagpole (Kinetic.Line). I desire to fire an event when the user moves the mouse over any portion of the flag or flagpole. In prior attempts I have attached event handlers to each shape individually, only to learn that Kinetic.Line does not fire events.
In this latest attempt I added the shapes to a group and attached the handler to the group thinking this would solve the issue: it does not.
Is there any way to achieve the desired behavior? Thank you, and remember to press F12 to see the handler's console messages.
var handler = function(e) {
console.log("Event fired.");
};
var stage = new Kinetic.Stage({
container: 'testBlock',
width: 200,
height: 200
});
var layer = new Kinetic.Layer();
var group = new Kinetic.Group();
var rect = new Kinetic.Rect({
x: 75,
y: 10,
width: 50,
height: 50,
fill: 'silver',
});
line = new Kinetic.Line({
points: [
{x: 125, y: 10},
{x: 125, y: 160},
],
stroke: 'black',
strokeWidth: 1
});
// add the shapes to the group
group.add(rect);
group.add(line);
// event handler for the group
group.on("mouseover", handler);
// add the group to the layer
layer.add(group);
// add the layer to the stage
stage.add(layer);
Kinetic.Line's have trouble with events when the stroke is too small, you can see this evident with any line with stroke < 3px.
This was the response I got from Eric Rowell (creator of KineticJS):
yep, KineticJS ignores the anti-aliased pixels. If you're drawing a 1px diagonal line, and you want it to be detectable, you need to create a custom hit function to define the hit region. You probably will want to create a hit region that's a line which is about 5px thick or so. Here's an example on creating custom hit regions:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-custom-hit-function-tutorial/
So in addition to Ani's answer, you can also use the drawHitFunc property to make a custom hit region for the line that is thicker than the actual line:
line = new Kinetic.Line({
points: [
{x: 125, y: 10},
{x: 125, y: 160},
],
stroke: 'black',
strokeWidth: 1,
drawHitFunc: function(canvas) {
var x1=this.getPoints()[0].x;
var x2=this.getPoints()[1].x;
var y1=this.getPoints()[0].y;
var y2=this.getPoints()[1].y;
var ctx = canvas.getContext();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(x1-3,y1-3);
ctx.lineTo(x1-3,y2+3);
ctx.lineTo(x2+3,y2+3);
ctx.lineTo(x2+3,y1-3);
ctx.closePath();
canvas.fillStroke(this);
}
});
jsfiddle
Try this fiddle
I'm using Kinetic.Rect with width=1 and height= y2-y1 of your line.
line = new Kinetic.Rect({
x: 125, y: 10,
width: 1, height: 150,
fill: 'black',
});

Create a masked overlay with draggable/resizable underneath

I'm trying to get kineticjs down and worked out a little app which makes my images draggable and resizable. So far so good;
However: I want an overlay with a variable height/width block in the center which should show the image underneath(With the draggable/resizable intact) with a semi-transparent overlay.
I want to be able to still resize/drag behind the overlay while the overlay is still intact(Like this, but with kineticjs: http://envyum.nl/pointer/)
Is there a way to do so? By cutting a block out of an overlaying rectangle perhaps? And can the mouse ignore the overlay such as pointer-events: none can in css3?
Thanks in advance,
I have a sample of what I was talking about in the comments above: http://jsfiddle.net/KwQBB/
This did not require a new layer, but might be good practice to do so.
You can tailor the logic to be whatever you want, especially to simulate a 'cut-out'
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 500
});
var layer = new Kinetic.Layer();
var pentagon = new Kinetic.RegularPolygon({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
sides: 5,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true,
dragOnTop: false
});
var rect1 = new Kinetic.Rect({ // overlay
x: 0,
y: 0,
width: stage.getWidth(),
height: 100,
fill: 'gray',
opacity: 0.5,
listening: false // <------ Extremely important
});
var rect2 = new Kinetic.Rect({ // overlay
x: 0,
y: stage.getHeight()/2,
width: stage.getWidth(),
height: 100,
fill: 'gray',
opacity: 0.5,
listening: false // <------ Extremely important
});
// add the shape to the layer
layer.add(pentagon);
layer.add(rect1);
layer.add(rect2); // add more rectangles to complete overlay
// add the layer to the stage
stage.add(layer);

moving more than two arrow lines on canvas

This is my code using kinetic.js
I draw three lines and move using mouse.
$(document).ready(function(){
var y1=50;
var stage = new Kinetic.Stage({
container: "container",
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var group=new Kinetic.Group({
draggable: true,
dragConstraint : 'horizontal'
});
var lineme =function(pts){
var line1 = new Kinetic.Line({
points: pts,
stroke: "black",
strokeWidth: 4,
lineCap: 'round',
lineJoin: 'round',
});
group.add(line1);
}
for(a=0;a<=2;a++)
{
var points1 = [{
x: 73,
y: y1
}, {
x: 300,
y: y1
}];
lineme(points1);
y1=y1+50;
}
group.on("mouseover", function(){
document.body.style.cursor = "pointer";
});
group.on("mouseout", function() {
document.body.style.cursor = "default";
});
// add the shape to the layer
layer.add(group);
// add the layer to the stage
stage.add(layer);
});
I want to draw arrow line I tried more time but I cant find out the proper solution. Is their any arrow function in kinetic js can anyone help me
You have to create a group and add both lines to the group.
Check the following example:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-a-group-with-kineticjs/
Hope it helps!
var line2 = .....
// add another line to the layer before adding it to the stage
layer.add(line2);
surely?

Categories