i'm working on a drag&drop-function for images. I've oriented myself on this example here:
http://www.html5canvastutorials.com/labs/html5-canvas-drag-and-drop-resize-and-invert-images/
The JS framework KineticJS is used there.
In this example the properties (x,y,width,height) of Kinetic.Group and Kinetic.Image are set with 'normal' number values.
my problem is that i need this properties as variables, because my uploaded images have different values for height, width etc.
I've tried to change the code from the example for my own drag&drop web application, but it doesn't work as i want...
I can load and display images correctly, but i can't move or resize them. With number values for x,y,width,height it works all.
Here is the code of the changed method "initStage()" (the other methods are unchanged):
function initStage(images) {
stage = new Kinetic.Stage({
container: 'wb_dropzone',
width: 500,
height: 400
});
var imageGroups = new Array();
var imageInstances = new Array();
var layer = new Kinetic.Layer();
for(var i=0; i<Object.size(images); i++)
{
imageGroups[i] = new Kinetic.Group({
x: fileInfos[i][2][0]/*0*/,
y: fileInfos[i][2][1]/*0*/,
draggable: true
});
layer.add(imageGroups[i]);
imageInstances[i] = new Kinetic.Image({
x: 0/*fileInfos[i][2][0]*/,
y: 0/*fileInfos[i][2][1]*/,
image: images[i],
width: fileInfos[i][1][0],
height: fileInfos[i][1][1],
name: 'image',
stroke: 'black',
strokeWidth: 2,
dashArray: [10, 2]
});
imageGroups[i].add(imageInstances[i]);
addAnchor(imageGroups[i], 0, 0, 'topLeft');
addAnchor(imageGroups[i], fileInfos[i][1][0], 0, 'topRight');
addAnchor(imageGroups[i], fileInfos[i][1][0], fileInfos[i][1][1], 'bottomRight');
addAnchor(imageGroups[i], 0, fileInfos[i][1][1], 'bottomLeft');
imageGroups[i].on('dragstart', function() {
this.moveToTop();
});
}
stage.add(layer);
stage.draw();
}
More informations about "fileInfos":
[imagePath, [width, height], [X-pos., Y-pos.]]
(all dropped images are uploaded in a folder. The properties of each image are saved in a database.
Default x- and y-position is "0".)
Does anybody have an idea, how i can solve this problem?
I'm grateful for any help!
How to create draggable/resizable images that are loaded from your fileInfos
Call a function that creates the group+image+anchors based on your fileInfos[i]:
// pull info supplied by fileInfos for this “i”
var imgWidth=fileInfos[i][1][0];
var imgHeight=fileInfos[i][1][1];
var groupX=fileInfos[i][2][0];
var groupY=fileInfos[i][2][1];
// call a function that creates the draggable/resizable group
addImageGroup( images[i], imgWidth,imgHeight, groupX,groupY );
Here’s that function that creates the draggable/resizable group element:
function addImageGroup(image,imageWidth,imageHeight,groupX,groupY){
// width and height are based on the images width/height
var w=imageWidth;
var h=imageHeight;
var kGroup = new Kinetic.Group({
x:groupX,
y:groupY,
width:w+20, // must allow 10+10=20 for anchors
height:h+20,
draggable:true
});
layer.add(kGroup);
kGroup.on('dragstart', function() {
this.moveToTop();
});
var kImage = new Kinetic.Image({
x: 0,
y: 0,
image: image,
width: w,
height: h,
name: 'image',
stroke: 'black',
strokeWidth: 2,
dashArray: [10, 2]
});
kGroup.add(kImage);
addAnchor(kGroup, 0, 0, 'topLeft');
addAnchor(kGroup, w, 0, 'topRight');
addAnchor(kGroup, w, h, 'bottomRight');
addAnchor(kGroup, 0, h, 'bottomLeft');
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/buCzH/
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
#container{
border:1px solid red;
width:350px;
height:350px;
}
</style>
</head>
<body onmousedown="return false;">
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.2.min.js"></script>
<script>
// create the stage
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer=new Kinetic.Layer();
stage.add(layer);
// build a test fileInfos array
// width/height will be gotten from actual images, so leave width/height==0
var fileInfos=[];
function addFile(x,y,w,h,imgURL){
fileInfos.push([imgURL,[w,h],[x,y]]);
}
addFile(30,100,102,102,"https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg");
addFile(200,100,102,102,"https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg");
// load all the images
var images=[];
loadAllImages();
function loadAllImages(){
var imagesOK=0;
for (var i = 0; i < fileInfos.length; i++) {
var img = new Image();
images.push(img);
img.onload = function(){
if (++imagesOK==fileInfos.length ) {
// all images are loaded, so build the groups
for(var i=0;i<fileInfos.length;i++){
var imgWidth=fileInfos[i][1][0];
var imgHeight=fileInfos[i][1][1];
var groupX=fileInfos[i][2][0];
var groupY=fileInfos[i][2][1];
addImageGroup( images[i], imgWidth,imgHeight, groupX,groupY );
}
layer.draw();
}
};
img.src = fileInfos[i][0];
}
}
function addImageGroup(image,imageWidth,imageHeight,groupX,groupY){
// width and height are based on the images width/height
var w=imageWidth;
var h=imageHeight;
var kGroup = new Kinetic.Group({
x:groupX,
y:groupY,
width:w+20, // must allow 10+10=20 for anchors
height:h+20,
draggable:true
});
layer.add(kGroup);
kGroup.on('dragstart', function() {
this.moveToTop();
});
var kImage = new Kinetic.Image({
x: 0,
y: 0,
image: image,
width: w,
height: h,
name: 'image',
stroke: 'black',
strokeWidth: 2,
dashArray: [10, 2]
});
kGroup.add(kImage);
addAnchor(kGroup, 0, 0, 'topLeft');
addAnchor(kGroup, w, 0, 'topRight');
addAnchor(kGroup, w, h, 'bottomRight');
addAnchor(kGroup, 0, h, 'bottomLeft');
}
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var image = group.get('.image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
image.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
</script>
</body>
</html>
Related
I am inspired with KonvaJS tutorial Modify Curves with Anchor Points to make my own example which is to create multiple custom arrows.
on click on the selectionBox create an anchor.
on the creation of the third anchor create the curved arrow.
on the fourth click reset all variables in order to draw a new curved arrow.
var width = window.innerWidth;
var height = window.innerHeight;
// globals
var selectionBoxLayer, curveLayer, lineLayer, anchorLayer, quad, bezier;
function updateDottedLines() {
var q = quad;
var quadLine = lineLayer.get('#quadLine')[0];
quadLine.setPoints([q.start.attrs.x, q.start.attrs.y, q.control.attrs.x, q.control.attrs.y, q.end.attrs.x, q.end.attrs.y]);
lineLayer.draw();
}
function buildAnchor(x, y) {
var anchor = new Konva.Circle({
x: x,
y: y,
radius: 20,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
draggable: true
});
// add hover styling
anchor.on('mouseover', function() {
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
anchorLayer.draw();
});
anchor.on('mouseout', function() {
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
anchorLayer.draw();
});
anchor.on('dragend', function() {
drawCurves();
updateDottedLines();
});
anchorLayer.add(anchor);
anchorLayer.draw();
return anchor;
}
function drawCurves() {
var context = curveLayer.getContext();
var arrowLine = new Konva.Shape({
sceneFunc: function(context){
debugger;
// draw quad
context.beginPath();
context.moveTo(quad.start.attrs.x, quad.start.attrs.y);
context.quadraticCurveTo(quad.control.attrs.x, quad.control.attrs.y, quad.end.attrs.x, quad.end.attrs.y);
//Draw Arrow Head
var headlen = 10; // length of head in pixels
var angle = Math.atan2(quad.end.attrs.y - quad.control.attrs.y, quad.end.attrs.x - quad.control.attrs.x);
context.lineTo(quad.end.attrs.x-headlen*Math.cos(angle-Math.PI/6), quad.end.attrs.y-headlen*Math.sin(angle-Math.PI/6));
context.moveTo(quad.end.attrs.x, quad.end.attrs.y);
context.lineTo(quad.end.attrs.x- headlen*Math.cos(angle+Math.PI/6), quad.end.attrs.y-headlen*Math.sin(angle+Math.PI/6));
context.fillStrokeShape(this);
},
stroke: 'black',
strokeWidth: 4
});
curveLayer.add(arrowLine);
curveLayer.draw();
}
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
selectionBoxLayer = new Konva.Layer();
anchorLayer = new Konva.Layer();
lineLayer = new Konva.Layer();
// curveLayer just contains a canvas which is drawn
// onto with the existing canvas API
curveLayer = new Konva.Layer();
var quadLine = new Konva.Line({
dash: [10, 10, 0, 10],
strokeWidth: 3,
stroke: 'black',
lineCap: 'round',
id: 'quadLine',
opacity: 0.3,
points: [0, 0]
});
// add dotted line connectors
lineLayer.add(quadLine);
quad = {};
// keep curves insync with the lines
anchorLayer.on('beforeDraw', function() {
if(quad.start && quad.control && quad.end){
drawCurves();
updateDottedLines();
}
});
var selectionBoxBackground = new Konva.Rect({
x: 0,
y: 0,
height:stage.height(),
width: stage.width(),
fill: 'transparent',
draggable: false,
name: 'selectionBoxBackground'
});
selectionBoxLayer.add(selectionBoxBackground);
var clickCounter = 0;
selectionBoxBackground.on("click", function(){
clickCounter +=1;
var mousePos = {};
switch(clickCounter){
case 1:
mousePos = stage.getPointerPosition();
quad.start = buildAnchor(mousePos.x, mousePos.y);
break;
case 2:
mousePos = stage.getPointerPosition();
quad.control = buildAnchor(mousePos.x, mousePos.y);
break;
case 3:
mousePos = stage.getPointerPosition();
quad.end = buildAnchor(mousePos.x, mousePos.y);
drawCurves();
updateDottedLines();
break;
default:
clickCounter = 0;
quad = {};
anchorLayer.destroyChildren();
anchorLayer.draw();
}
});
stage.add(curveLayer);
stage.add(lineLayer);
stage.add(selectionBoxLayer);
stage.add(anchorLayer);
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
<script src="https://cdn.rawgit.com/konvajs/konva/0.11.1/konva.min.js"></script>
<body>
<div id="container"></div>
</body>
P.S Please note when I write in the browser console curveLayer.children, it will bring all created curved arrows.
Hint: I think on the creation of new Shape() the values of all created shapes will be changed to the new one.
I don't know what I am missing.
I am developing canvas to create hotel floor view. I am drawing images on canvas from database. I am taking x,y co-ordinates from database and drawing image on that points. But i want to give touch event to those images. I want to replace image on touch or click event. I want to create same functionality as that of book my show .
this is my code.
<!DOCTYPE HTML>
<html>
<head>
<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>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:100%;
height:100%;
}
html,body,kineticjs-content {
width:100%;
height:100%;
margin: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://localhost/zoilo_admin/public/kinetic-v5.1.0.js"></script>
<script defer="defer">
function writeMessage(message) {
text.setText(message);
layer.draw();
}
function loadImages(sources, position, callback) {
var assetDir = '';
var images = {};
var loadedImages = 0;
var numImages = 0;
for (i = 0; i < sources.length; i++)
{
numImages++;
}
for (i = 0; i < sources.length; i++)
{
images[i] = new Image();
images[i].onload = function () {
if (loadedImages == (sources.length - 1)) {
callback(images, position);
}
loadedImages++;
};
images[i].src = assetDir + sources[i];
}
}
function buildStage(images, position) {
var positionIndex = 0;
var tableActual = {};
console.log(images);
for (var i = 0; i < sources.length; i++)
{
console.log("Here");
tableActual[i] = new Kinetic.Image({
image: images[i],
x: position[i].x,
y: position[i].y
});
// var tableName = src;
// var table1 = new Kinetic.Image({
// image: images[src],
// x: position[positionIndex].x,
// y: position[positionIndex].y
// });
tableActual[i].on('click', function () {
console.log(this.index);
var image = new Kinetic.Image({
image: '4top.png',
x: position[this.index].x,
y: position[this.index].y
});
drawImage(image);
switch (this.index)
{
case 0:
writeMessage('Click on Table ' + 0);
tableActual[positionIndex] = new Kinetic.Image({
image: images[positionIndex],
x: position[positionIndex].x,
y: position[positionIndex].y
});
this.setIm = "4top.png";
break;
case 1:
writeMessage('Click on Table ' + 1);
break;
case 2:
writeMessage('Click on Table ' + 2);
break;
case 3:
writeMessage('Click on Table ' + 3);
break;
case 4:
writeMessage('Click on Table ' + 4);
break;
}
writeMessage('mouseover ' + this[src]);
});
drawImage(tableActual[i]);
positionIndex++;
}
// finally, we need to redraw the layer hit graph
layer.drawHit();
}
var stage = new Kinetic.Stage({
container: 'container',
width: $(window).width(),
height: $(window).height()
});
var layer = new Kinetic.Layer();
var text = new Kinetic.Text({
x: 10,
y: 10,
fontFamily: 'Calibri',
fontSize: 24,
text: '',
fill: 'black'
});
var sources = [
'house204-2.jpg',
'house204-1.jpg',
'4top.png',
'house204-1.jpg',
'4top.png'
];
var position = [
{
x: 380,
y: 60
},
{
x: 180,
y: 60
}
,
{
x: 90,
y: 60
},
{
x: 260,
y: 60
},
{
x: 50,
y: 60
}
];
loadImages(sources, position, buildStage);
function drawImage(Image)
{
layer.add(Image);
layer.add(text);
stage.add(layer);
// in order to ignore transparent pixels in an image when detecting
// events, we first need to cache the image
Image.cache();
// next, we need to redraw the hit graph using the cached image
Image.drawHitFromCache();
}
</script>
</body>
</html>
Yes! you can change it on touch/click event by changing source of that java script image.
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.3.min.js"></script>
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
var yoda = new Kinetic.Image({
x: 140,
y: stage.getHeight() / 2 - 59,
image: imageObj,
width: 106,
height: 118
});
var filteredYoda = new Kinetic.Image({
x: 320,
y: stage.getHeight() / 2 - 59,
image: imageObj,
width: 106,
height: 118
});
// add the shape to the layer
layer.add(yoda);
layer.add(filteredYoda);
// add the layer to the stage
stage.add(layer);
stage.on('click',function(){
imageObj.src = 'http://crushlabs.com/wp-content/uploads/2013/01/jacee-terry-hello-card-business-card-design-back.jpg';
});
// apply grayscale filter to second image
filteredYoda.applyFilter(Kinetic.Filters.Grayscale, null, function() {
layer.draw();
});
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
</script>
var stages = new Array() ;
var limites = new Array() ;
numStage=0;
r = {
'x':65,
'y':120,
'xwidth':335,
'yheight':210
};
limites.push(r);
stages[numStage] = new Kinetic.Stage({
container: 'cmg_canvas_'+numStage,
width: 450,
height: 450
});
//creation image
obj = new Image();
obj.src = 'http://i.imgur.com/zFZgKuS.jpg';
image = new Kinetic.Image({
image: obj,
width: 450,
height: 450
});
// add image to calque
layer = new Kinetic.Layer();
layer.add(image);
stages[numStage].add(layer); //add image to canvas
layer = new Kinetic.Layer();
//set limit x y h l
/*var rect = new Kinetic.Rect({
name: 'limite',
x: limites[numStage].x,
y: limites[numStage].y,
width: limites[numStage].xwidth,
height: limites[numStage].yheight,
stroke: 'black',
strokeWidth: 0.5
});*/
//layer.add(rect);// add to canvas
stages[numStage].add(layer);
$('.cmg_text').live('blur', function(){
idText = 'cmg_line0';
numStage = 0;
drawTextPath(numStage, idText,$(this).val(),50,22,numStage);
//text = getText(this).text;
});
function getSVG(x,y,w,verif) {
halfw = parseFloat((w/2).toFixed(2));
x1 = parseFloat((halfw/2).toFixed(2));
x2 = parseFloat(halfw + x1);
if(parseInt(verif))
{
y1 = parseFloat(y) * 2 +18;
y2 = parseFloat(y) * 2 +18;
}
else
{
y1 = -18;
y2 = -18;
}
str = 'M '+x+','+y+' C '+x1+','+y1+' '+x2+','+y2+' '+w+','+y;
return str;
}
function drawTextPath(numStage, textId,text,valueSlider, newFontSize,numStage){
//'M 0,115 C42,-18 126,-18 165,115';
//'M 0,115 C45,230 180,230 180,115';
var arcOnly = 0;
if(textId == 'cmg_line0')
{
console.log('limites[numStage].yheight/2'+limites[numStage].yheight/2);
console.log('limites[numStage].xwidth'+limites[numStage].xwidth);
svg = getSVG(0,valueSlider,valueSlider*6.3,0);
arcOnly = 0;
}
//alert(svg);
console.log(parseFloat(limites[numStage].y));
console.log(parseFloat(arcOnly));
console.log(parseFloat(limites[numStage].y - arcOnly));
var layer = new Kinetic.Layer({name:'textPathLayer',draggable:true});
var textpath = new Kinetic.TextPath({
name:'TextPath',
id: textId,
//x: 0,
//x: limites[numStage].x + limites[numStage].xwidth/2,
//y: 0,
//y: limites[numStage].y + limites[numStage].yheight/2,
x: limites[numStage].x ,
y: limites[numStage].y + limites[numStage].yheight/2,
fill: '#000',
fontSize: newFontSize,
fontFamily: 'Arial',
text: text,
//offsetX:0,
//offsetY:0,
draggable: true,
dragBoundFunc: function(pos){
p = textParams(this, pos);
return {x: p.newX, y: p.newY};
},
data: svg
});
//
layer.add(textpath);
stages[numStage].add(layer);
//layer.moveToTop();
//layer.draw();
//stages[0].draw();
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/kineticjs/4.6.0/kinetic.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div id="cmg_canvas_0"></div>
<input type='text' class='cmg_text' />
I have to draw a draggable textpath with kineticjs, with text given by an input text, the action is triggered in blur.
I have a stage that contain 3 layers;
Layer for the background, and one layer for the textpath.
My problem that the draggable in the textpath is not working,
i tried to set the text layer in the top, but i didn't get it draggable.
This is my jsfiddle
I have a doubt of inner layer problem.
Thanks in advance.
I want to be able to upload images onto this canvas from the persons computer just for the time being while they use the canvas. I also want it to be moveable and resizeable like the other 2 images I have setup right now. Can someone help create a code that goes along with what I currently have. This is everything I have for it so far so if you could name such with the right class/ids that the parts of mine have. Thank you
<style>
canvas:active{
cursor:pointer;
}
.bg1{
background-image:url('http://s23.postimg.org/bxtmsd2tn/boutiquebase.jpg');
}
.bg2{
background-image:url('http://s4.postimg.org/bnevxi1y5/wall8.png');
}
.bg3{
background-image:url('http://s13.postimg.org/6cgbaoblh/wall9.png');
}
</style>
<div id="container" class="bg1"></div>
<img src="http://s23.postimg.org/bxtmsd2tn/boutiquebase.jpg" width="50px" id="wall1">
<img src="http://s4.postimg.org/bnevxi1y5/wall8.png" width="50px" id="wall2">
<img src="http://s13.postimg.org/6cgbaoblh/wall9.png" width="50px" id="wall3">
<table><tr>
<td>
<center> <img src="http://s29.postimg.org/yn6t21ah3/sidetable.png" id="shower" width="100px" style="cursor:pointer;">
<br>
<span id="hider1" class="sendingBut" style="cursor:pointer;">Remove </span>
</center></td>
</tr>
</table>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.2.min.js"></script>
<script>
$('#wall2').click(function() {
$('#container').removeClass('bg3').removeClass('bg1').addClass('bg2');
});
$('#wall1').click(function() {
$('#container').removeClass('bg3').removeClass('bg2').addClass('bg1');
});
$('#wall3').click(function() {
$('#container').removeClass('bg1').removeClass('bg2').addClass('bg3');
});
</script>
<script>
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.find('.topLeft')[0];
var topRight = group.find('.topRight')[0];
var bottomRight = group.find('.bottomRight')[0];
var bottomLeft = group.find('.bottomLeft')[0];
var image = group.find('.image')[0];
var anchorX = activeAnchor.x();
var anchorY = activeAnchor.y();
// update anchor positions
switch (activeAnchor.name()) {
case 'topLeft':
topRight.y(anchorY);
bottomLeft.x(anchorX);
break;
case 'topRight':
topLeft.y(anchorY);
bottomRight.x(anchorX);
break;
case 'bottomRight':
bottomLeft.y(anchorY);
topRight.x(anchorX);
break;
case 'bottomLeft':
bottomRight.y(anchorY);
topLeft.x(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
var width = topRight.x() - topLeft.x();
var height = bottomLeft.y() - topLeft.y();
if(width && height) {
image.setSize({width:width, height: height});
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false,
opacity: .01
});
anchor.on('mouseout', function () {
this.opacity(.01);
layer.draw()
});
anchor.on('mouseenter', function () {
this.opacity(1.00);
layer.draw()
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.strokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 764
});
var layer = new Kinetic.Layer();
var furniGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var yodaGroup = new Kinetic.Group({
x: 100,
y: 110,
draggable: true
});
/*
* go ahead and add the groups
* to the layer and the layer to the
* stage so that the groups have knowledge
* of its layer and stage
*/
layer.add(furniGroup);
layer.add(yodaGroup);
stage.add(layer);
document.getElementById('shower').addEventListener('click', function() {
furniImg.show();
layer.draw();
}, false);
document.getElementById('hider1').addEventListener('click', function() {
furniImg.hide();
layer.draw();
}, false);
var furniImg = new Kinetic.Image({
x: 0,
y: 0,
width: 338,
height: 285,
image: images.furni,
name: 'image'
});
furniGroup.add(furniImg);
addAnchor(furniGroup, 0, 0, 'topLeft');
addAnchor(furniGroup, 338, 0, 'topRight');
addAnchor(furniGroup, 338, 285, 'bottomRight');
addAnchor(furniGroup, 0, 285, 'bottomLeft');
furniGroup.on('dragstart', function() {
this.moveToTop();
});
var yodaImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.yoda,
width: 422,
height: 243,
name: 'image'
});
yodaGroup.add(yodaImg);
addAnchor(yodaGroup, 0, 0, 'topLeft');
addAnchor(yodaGroup, 422, 0, 'topRight');
addAnchor(yodaGroup, 422, 243, 'bottomRight');
addAnchor(yodaGroup, 0, 243, 'bottomLeft');
yodaGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
var sources = {
furni: 'http://s29.postimg.org/yn6t21ah3/sidetable.png',
yoda: 'http://s28.postimg.org/58nni8dzh/blackf10.png'
};
loadImages(sources, initStage);
</script>
This code lets you drag an image from the users desktop onto the Kinetic container div.
A new Kinetic.Image will be created from the dropped image.
Example code and a Demo: http://jsfiddle.net/m1erickson/w9onv0nm/
<!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-v5.1.0.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
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);
// drag image to the div with id='container'
var container=document.getElementById("container");
container.addEventListener("dragover", function(e){ e.preventDefault(); }, false);
container.addEventListener("drop", function(e){
var files = e.dataTransfer.files;
if (files.length>0) {
var file=files[0];
if (typeof FileReader !== "undefined" && file.type.indexOf("image") != -1) {
var reader=new FileReader();
reader.onload=function (e) {
var dragImage=new Image();
dragImage.onload=function(){
newDraggedImage(dragImage);
};
dragImage.src=e.target.result;
};
reader.readAsDataURL(file);
}
}
e.preventDefault();
}, false);
// create a new Kinetic.Image from the dropped image
function newDraggedImage(img){
layer.add(new Kinetic.Image({
image:img,
draggable:true,
}));
layer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag an image onto the container to create a Kinetic.Image</h4>
<div id="container"></div><br>
</body>
</html>
[ Addition - creating group & anchors for dropped images ]
Warning! This is untested code...tweaking is probably required!
function createGroup(groupId,img,x,y){
var group = new Kinetic.Group({
id:groupId,
x:x,
y:y,
draggable: true
});
layer.add(group);
var image = new Kinetic.Image({
x: 0,
y: 0,
image:img,
width:img.width,
height:img.height,
name: 'image'
});
group.add(image);
addAnchor(group, 0, 0, 'topLeft');
addAnchor(group, img.width, 0, 'topRight');
addAnchor(group, img.width, img.height, 'bottomRight');
addAnchor(group, 0, img.height, 'bottomLeft');
group.on('dragstart', function() {
this.moveToTop();
});
return(group);
}
I'm trying to add an image uploader for users so that they can upload images from their computer onto the canvas and move it/resize like these other images. I don't have an online storage to use php, so is it possible to do this without one. These images they use won't need stored anywhere, will just be used in the canvas that one time and then they'll be able to save the canvas to their computer(so storing the image online shouldn't be needed). Anyways I could really use help with this I'm new to javascript, here is the page I have so far...
<style>
canvas:active{
cursor:pointer;
}
.bg1{
background-image:url('http://s23.postimg.org/bxtmsd2tn/boutiquebase.jpg');
}
.bg2{
background-image:url('http://s4.postimg.org/bnevxi1y5/wall8.png');
}
.bg3{
background-image:url('http://s13.postimg.org/6cgbaoblh/wall9.png');
}
</style>
<div id="container" class="bg1"></div>
<img src="http://s23.postimg.org/bxtmsd2tn/boutiquebase.jpg" width="50px" id="wall1">
<img src="http://s4.postimg.org/bnevxi1y5/wall8.png" width="50px" id="wall2">
<img src="http://s13.postimg.org/6cgbaoblh/wall9.png" width="50px" id="wall3">
<table><tr>
<td>
<center> <img src="http://s29.postimg.org/yn6t21ah3/sidetable.png" id="shower" width="100px" style="cursor:pointer;">
<br>
<span id="hider1" class="sendingBut" style="cursor:pointer;">Remove </span>
</center></td>
</tr>
</table>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.2.min.js"></script>
<script>
$('#wall2').click(function() {
$('#container').removeClass('bg3').removeClass('bg1').addClass('bg2');
});
$('#wall1').click(function() {
$('#container').removeClass('bg3').removeClass('bg2').addClass('bg1');
});
$('#wall3').click(function() {
$('#container').removeClass('bg1').removeClass('bg2').addClass('bg3');
});
</script>
<script>
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.find('.topLeft')[0];
var topRight = group.find('.topRight')[0];
var bottomRight = group.find('.bottomRight')[0];
var bottomLeft = group.find('.bottomLeft')[0];
var image = group.find('.image')[0];
var anchorX = activeAnchor.x();
var anchorY = activeAnchor.y();
// update anchor positions
switch (activeAnchor.name()) {
case 'topLeft':
topRight.y(anchorY);
bottomLeft.x(anchorX);
break;
case 'topRight':
topLeft.y(anchorY);
bottomRight.x(anchorX);
break;
case 'bottomRight':
bottomLeft.y(anchorY);
topRight.x(anchorX);
break;
case 'bottomLeft':
bottomRight.y(anchorY);
topLeft.x(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
var width = topRight.x() - topLeft.x();
var height = bottomLeft.y() - topLeft.y();
if(width && height) {
image.setSize({width:width, height: height});
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false,
opacity: .01
});
anchor.on('mouseout', function () {
this.opacity(.01);
layer.draw()
});
anchor.on('mouseenter', function () {
this.opacity(1.00);
layer.draw()
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.strokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 764
});
var layer = new Kinetic.Layer();
var furniGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var yodaGroup = new Kinetic.Group({
x: 100,
y: 110,
draggable: true
});
/*
* go ahead and add the groups
* to the layer and the layer to the
* stage so that the groups have knowledge
* of its layer and stage
*/
layer.add(furniGroup);
layer.add(yodaGroup);
stage.add(layer);
document.getElementById('shower').addEventListener('click', function() {
furniImg.show();
layer.draw();
}, false);
document.getElementById('hider1').addEventListener('click', function() {
furniImg.hide();
layer.draw();
}, false);
var furniImg = new Kinetic.Image({
x: 0,
y: 0,
width: 338,
height: 285,
image: images.furni,
name: 'image'
});
furniGroup.add(furniImg);
addAnchor(furniGroup, 0, 0, 'topLeft');
addAnchor(furniGroup, 338, 0, 'topRight');
addAnchor(furniGroup, 338, 285, 'bottomRight');
addAnchor(furniGroup, 0, 285, 'bottomLeft');
furniGroup.on('dragstart', function() {
this.moveToTop();
});
var yodaImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.yoda,
width: 93,
height: 104,
name: 'image'
});
yodaGroup.add(yodaImg);
addAnchor(yodaGroup, 0, 0, 'topLeft');
addAnchor(yodaGroup, 93, 0, 'topRight');
addAnchor(yodaGroup, 93, 104, 'bottomRight');
addAnchor(yodaGroup, 0, 104, 'bottomLeft');
yodaGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
var sources = {
furni: 'http://s29.postimg.org/yn6t21ah3/sidetable.png',
yoda: 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg'
};
loadImages(sources, initStage);
</script>
You could use the FileReader.
This has the advantage of being cross-domain security compliant so that you can use .toDataURL to save the canvas.
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
canvas {border: 1px solid #aaa;}
</style>
<script>
$(function(){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// drag image to canvas
canvas.addEventListener("dragover", function(e){ e.preventDefault(); }, false);
canvas.addEventListener("drop", function(e){
var files = e.dataTransfer.files;
if (files.length>0) {
var file=files[0];
if (typeof FileReader !== "undefined" && file.type.indexOf("image") != -1) {
var reader=new FileReader();
reader.onload=function (e) {
var dragImage=new Image();
dragImage.onload=function(){
newDraggedImage(dragImage);
};
dragImage.src=e.target.result;
};
reader.readAsDataURL(file);
}
}
e.preventDefault();
}, false);
function newDraggedImage(img){
ctx.drawImage(img,0,0);
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Drag an image onto the canvas.</p>
<canvas id="canvas" width="300" height="300"></canvas>
</body>
</html>