Bind HTML element with the object that is already created - javascript

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/

Related

javascript - last image clicked bring to front

I'm trying to make a really simple website in javascript.
I want the website to have a stack of images that you can drag.
So far I managed to do it. But now I want to always bring to front the last clicked image.
How can I do this ? Thanks !
Here is my code :
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva#8.4.0/konva.min.js"></script>
<meta charset="utf-8" />
<title></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();
stage.add(layer);
var img1 = new Konva.Image({
x: 20,
y: 20,
width: 400,
height: 566,
draggable: true,
});
layer.add(img1);
var img2 = new Konva.Image({
x: 100,
y: 20,
width: 400,
height: 566,
draggable: true,
});
layer.add(img2);
var imageObj1 = new Image();
imageObj1.onload = function () {
img1.image(imageObj1);
};
imageObj1.src = 'imgs/img1.jpg';
var imageObj2 = new Image();
imageObj2.onload = function () {
img2.image(imageObj2);
};
imageObj2.src = 'imgs/img2.jpg';
</script>
</body>
</html>
I've seen this code on another post, but I don't know how to make it work ..
$("img.myclass").click(function() {
$("img.myclass").not(this).css("z-index", 0);
$(this).css("z-index", 100);
});
The "code on another post" is written in jQuery wich is an javascript library and need to be added to your page as you do with konva.
Konva is a tool that draw an canvas.
You can change zIndex (property that will change order of your stack) when you click on image.
For example:
img1.zIndex(0);
img2.zIndex(1); // will set img2 higher
If image didn't have zIndex() function you can try to wrap it to a group.
const group1 = new Konva.Group();
group1.add(img1);
group1.zIndex(0);
Edit:
Increase zIndex on click.
let zIndex = 0;
img.onclick = function () {
zIndex += 1;
img.zIndex(zIndex);
}

KineticJS - Cannot add dynamic object

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>

How to vertically center text inside a KineticJS Wedge?

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>

KineticJS - How draw repeat line like ruler?

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>

Dragging and dropping images within multiple boundries in HTML5 canvas

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);
});

Categories