I've got the following code:
var text = new Kinetic.Text({
text: carNames,
fontFamily: 'Calibri',
fontSize: 17,
fill: 'black',
align: 'center'
});
text.toImage({
width: text.getWidth(),
height: text.getHeight(),
callback: function (img) {
var cachedText = new Kinetic.Image({
image: img,
x: 180,
y: 0
});
wedge.add(cachedText);
layer.draw();
}
});
Which produces wedges and text that look like this:
But I need the text to be centered inside the wedge, like this:
Does anyone know of a way to achieve this? I've tried several things but I just can't get the text to align as in the second image.
Thanks in advance for your trouble.
One way to do it is using the text's offset in combination with the text's rotationDeg:
Demo: http://jsfiddle.net/m1erickson/mqsY3/
Here's code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var cx=175;
var cy=175;
var wedgeRadius=120;
var accumAngle=0;
var center = new Kinetic.Circle({
x:cx,
y:cy,
radius:5,
fill: 'red'
});
layer.add(center);
for(var i=0;i<12;i++){
newTextWedge(30,"Element # "+i);
}
function newTextWedge(angle,text){
var wedge = new Kinetic.Wedge({
x: cx,
y: cy,
radius: wedgeRadius,
angleDeg: angle,
stroke: 'gray',
strokeWidth: 1,
rotationDeg:-accumAngle+angle/2
});
layer.add(wedge);
if(accumAngle>90 && accumAngle<270){
var offset=[wedgeRadius-10,7];
var textAngle=accumAngle-180;
}else{
var offset=[-50,7];
var textAngle=accumAngle;
}
var text = new Kinetic.Text({
x:cx,
y:cy,
text:text,
fill: 'red',
offset:offset,
rotationDeg:textAngle
});
layer.add(text);
layer.draw();
accumAngle+=angle;
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Related
I'd like to drag a Konva layer even if empty. I see that I can drag the layer only where objects are present (the code shows that you can drag where the rectangle is but nowhere else).
How can I drag the layer dragging empty parts?
Moreover, I see that also the mouseenter and mousleave aren't respected if you are out of the objects of the layer.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<body>
<script src="js/modulePattern.js"></script>
<script src="https://unpkg.com/konva#2.4.2/konva.min.js"></script>
<div id="container"></div>
<script>
function demo() {
var stage = new Konva.Stage({
container: 'container',
width: 100,
height: 100
});
var layer = new Konva.Layer({draggable: true});
stage.add(layer);
layer.on("dragmove", function() {
console.log(this.x(), this.y())
});
layer.on("mouseenter", function() {
stage.container().style.cursor = 'pointer';
});
layer.on("mouseleave", function() {
stage.container().style.cursor = 'default';
});
var rect = new Konva.Rect({
width: 50,
height: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 5
});
layer.add(rect);
stage.draw();
}
demo();
</script>
</body>
</html>
Konva does not detect events on empty space of layers. And it is unclear how can it do it if you have several layers on the stage.
If you still need to listen on empty layers and make a layer draggable at any space you can:
Make stage draggable instead and listen events on it (click will work on empty space too).
Add a transparent rectangle as a background, so it will be used to listen to events:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<body>
<script src="js/modulePattern.js"></script>
<script src="https://unpkg.com/konva#2.4.2/konva.min.js"></script>
<div id="container"></div>
<script>
function demo() {
var stage = new Konva.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Konva.Layer({draggable: true});
stage.add(layer);
layer.on("mouseenter", function() {
stage.container().style.cursor = 'pointer';
});
layer.on("mouseleave", function() {
stage.container().style.cursor = 'default';
});
var rect = new Konva.Rect({
width: 50,
height: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 5
});
var back = new Konva.Rect({
fill: 'red',
width: stage.width(),
height: stage.height()
})
layer.add(back);
// move rectangle so it always stay on the screen, no matter where layer it
layer.on('dragend', function() {
back.setAbsolutePosition({x: 0, y: 0});
layer.draw();
});
layer.add(rect);
stage.draw();
}
demo();
</script>
</body>
</html>
I need to create a kind of container to manage dynamic actions with KineticJS.
I have a simple object from which we will be able to add a circle by using a function.
Here's my code:
function Stage() {
var self = this;
self.stage = new Kinetic.Stage({
container: "museumMapContainer",
width: 500,
height: 500
});
self.layer = new Kinetic.Layer();
self.addCircle = function (x,y) {
var circle = new Kinetic.Circle({
x: x,
y: y,
radius: 40,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
circle.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
circle.on('mouseout', function() {
document.body.style.cursor = 'default';
});
self.layer.add(circle);
}
self.stage.add(self.layer);
}
stage = new Stage();
stage.addCircle(250,250);
Normally, if I don't put the code inside a function, I can easily create a circle without any problems. However, this code doesn't work and I really don't know why.
Here's a Plunker: http://plnkr.co/edit/E1fbCFMeZwGNAKhsArhm?p=preview
There are no errors in the console and nothing is showing and I don't know why...
Make sure you do layer.draw after creating your new circles:
<!DOCTYPE html>
<html>
<head>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
<div id="museumMapContainer" style="width:500px;height:500px;border:1px solid black;"></div>
<script defer="defer">
function Stage() {
var self = this;
self.stage = new Kinetic.Stage({
container: "museumMapContainer",
width: 500,
height: 500
});
self.layer = new Kinetic.Layer();
self.stage.add(self.layer);
self.addCircle = function (x,y) {
var circle = new Kinetic.Circle({
x: x,
y: y,
radius: 40,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
circle.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
circle.on('mouseout', function() {
document.body.style.cursor = 'default';
});
self.layer.add(circle);
self.layer.draw();
}
}
stage = new Stage();
stage.addCircle(250,250);
</script>
</body>
</html>
I am new to KineticJS, I want to make a repeated line like a ruler. Is there any other way making line without call line1, line2, line3, etc? I try to make that with for, but error happen. Anyone could help?
Ruler I want make :
My error code :
for (int i = 0; i < 10; i++) {
var rects = new Kinetic.Rect({
x: 70,
y: 75,
width: 3,
height: 10,
fill: 'grey'
});
layer.add(rects);
}
JsFiddle
Thanks
You can make your ruler like this:
Start with a group.
Add a Rect with gradient background.
Add a custom Shape with markings.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/UcZ9H/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var ruler=new Kinetic.Group({
x:50,
y:50,
width:265,
height:70,
draggable:true
});
layer.add(ruler);
var rulerBG=new Kinetic.Rect({
x:0,
y:0,
width:265,
height:70,
fillLinearGradientStartPoint: [107, 0],
fillLinearGradientEndPoint: [107, 70],
fillLinearGradientColorStops: [0,'white', .75,"rgba(236,247,252,1)", 1,"rgba(204,234,246,1)"],
stroke:"rgba(204,234,246,1)",
strokeWidth:.5
});
ruler.add(rulerBG);
var rulerMarks = new Kinetic.Shape({
x:0,
y:0,
drawFunc: function(context) {
context.beginPath();
for(var i=0;i<5;i++){
context.moveTo(10+i*50,50);
context.lineTo(10+i*50,30);
context.fillText((i*20),10+i*50-5,20);
for(var j=0;j<5;j++){
context.moveTo(10+i*50+j*10,45);
context.lineTo(10+i*50+j*10,35);
}
}
context.moveTo(5*50,50);
context.lineTo(5*50,30);
context.fillText((5*20),5*50-8,20);
context.fillStrokeShape(this);
},
stroke: 'black',
strokeWidth:2
});
ruler.add(rulerMarks);
layer.draw();
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
I want to add images on canvas by using library Kinetic.js
The images are loaded from a database after I create the canvas. How I can bind this canvas with the elements that are created after the canvas?
JS Fiddle
HTML
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Design</title>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/v4.2.0/kinetic-v4.2.0.min.js" type="text/javascript"></script>
<style>
#wrapper{
width:300px;
height:200px;
margin:auto;
border-radius: 15px;
border: 4px solid black;
}
#container{
height:120px;
width:100%;
border:1px solid red;
}
#items, #cliparts{
height:55px;
border:1px solid green;
width:100%;
}
#items img, #cliparts img {
max-height:50px;
max-width:40px;
padding: 0 5px;
border:2px double white;
}
#items img:hover, #cliparts img:hover{
border:2px double blue;
cursor:pointer;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="container"> </div>
<div id="cliparts">
</div>
</body>
</html>
JavaScript
$(function() {
var stage = new Kinetic.Stage({
container: "container",
width: 300,
height: 100
});
var layer = new Kinetic.Layer();
var clip_group = new Kinetic.Group({
x: 20,
y: 10,
draggable: true,
});
});
$('#cliparts').append('<img class="clips" id="clip1" src="http://www.clker.com/cliparts/b/9/8/4/12284231761400606271Ricardo_Black_Boy_-_PNG.svg.med.png">');
$('#clip1').live('click', function(){
var imgObj = new Image();
imgObj.src= 'http://www.clker.com/cliparts/b/9/8/4/12284231761400606271Ricardo_Black_Boy_-_PNG.svg.med.png';
imgObj.onload = function(){
var clip_image = new Kinetic.Image({
x: 0,
y: 0,
image: imgObj,
width: 150,
height: 138,
name: "image",
});
// how to access the following elements
clip_group.add(clip_image);
layer.add(clip_group);
stage.add(layer);
stage.draw();
};
});
Im not a JQuery person and bad at technical terms so please excuse me if I get something wrong in this explenation, but rest assured the code will work ;)
$(a) is like saying window.onload do a, well you say a is an anonymous function.
With an anonymous function any variables in it will only be in the scope of itself and not window or global.
Later on your trying to accese variables as if they are global or in the scope of window.
So...you can either move all your code into that function or in that function make the variables you want accesed outside of it global.
Here's a few of examples...
Pass the window object to the anonymous function and declare the variables you want global against that...
$(function(a) {
a.stage = new Kinetic.Stage({
container: "container",
width: 300,
height: 100
});
a.layer = new Kinetic.Layer();
a.clip_group = new Kinetic.Group({
x: 20,
y: 10,
draggable: true,
});
}(window));
http://jsfiddle.net/j234L/1/
Declare your variables against the window object directly...
$(function() {
window.stage = new Kinetic.Stage({
container: "container",
width: 300,
height: 100
});
window.layer = new Kinetic.Layer();
window.clip_group = new Kinetic.Group({
x: 20,
y: 10,
draggable: true,
});
});
http://jsfiddle.net/j234L/2/
Put everything in the onload function....
$(function() {
window.stage = new Kinetic.Stage({
container: "container",
width: 300,
height: 100
});
window.layer = new Kinetic.Layer();
window.clip_group = new Kinetic.Group({
x: 20,
y: 10,
draggable: true,
});
$('#cliparts').append('<img class="clips" id="clip1" src="http://www.clker.com/cliparts/b/9/8/4/12284231761400606271Ricardo_Black_Boy_-_PNG.svg.med.png">');
$('#clip1').live('click', function() {
var imgObj = new Image();
imgObj.src = 'http://www.clker.com/cliparts/b/9/8/4/12284231761400606271Ricardo_Black_Boy_-_PNG.svg.med.png';
imgObj.onload = function() {
var clip_image = new Kinetic.Image({
x: 0,
y: 0,
image: imgObj,
width: 150,
height: 138,
name: "image",
});
// how to access the following elements
clip_group.add(clip_image);
layer.add(clip_group);
stage.add(layer);
stage.draw();
};
});
});
http://jsfiddle.net/j234L/3/
I am new with HTML5.
I have to implement such a functionality that I want images to be dropped within a canvas from outside, then there are visible boundaries within canvas and the images can be moved from one boundary to another. It is the same as in the following link,
http://custom.case-mate.com/diy?bypassLandingPage=true
As, in the site, user selects the pattern and drags images into that. Then he can drag the images between the boundaries. please give some solution for implementing such a functionality.
Here is what I have tried,
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
canvas {position:relative;
left:150%;
border: 10px solid #9C9898;
background-color: grey;
}
</style>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v3.10.0.js"></script>
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
width: 300,
height: 400,
});
var layer = new Kinetic.Layer();
var redLine = new Kinetic.Line({
points: [150, 0, 150, 400],
stroke: "white",
strokeWidth: 2,
});
var blueLine = new Kinetic.Line({
points: [150, 0, 150, 120, 300, 120],
stroke: "white",
strokeWidth: 2,
});
var thirdLine = new Kinetic.Line({
points: [300, 120, 150, 120, 150, 400],
stroke: "white",
strokeWidth: 2,
});
var imageObj = new Image();
imageObj.onload = function() {
var image = new Kinetic.Image({
x: stage.getWidth() / 2 - 50,
y: stage.getHeight() / 2 - 60,
image: imageObj,
width: 100,
height: 120,
});
image.draggable(true);
layer.add(image);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = "images/212.png";
layer.add(redLine);
layer.add(blueLine);
layer.add(thirdLine);
stage.add(layer);
};
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Here's a nice tutorial on HTML5 native drag'n'drop:
http://www.html5rocks.com/en/tutorials/dnd/basics/
Basically you can declare an item as draggable in HTML5 with the draggable attribute
<div class="draggable" draggable="true">A</div>
<div class="draggable" draggable="true">B</div>
...and then use Javascript to handle some events like:
var items = document.querySelectorAll('.draggable');
[].forEach.call(items, function(item) {
item.addEventListener('dragstart', function(){ /*handle drag start*/ }, false);
item.addEventListener('dragenter', function(){ /*handle drag enter*/ }, false)
item.addEventListener('dragover', function(){ /*handle drag over*/ }, false);
item.addEventListener('dragleave', function(){ /*handle drag leave*/ }, false);
item.addEventListener('drop', function(){ /*handle drop*/ }, false);
item.addEventListener('dragend', function(){ /*handle drag end*/ }, false);
});