Closed radheprasad closed 6 years ago
@radheprasad Sorry to say, but there's no easy way to drag a rectangle layer in jCanvas between two canvases. The layer is confined to the canvas on which it is created. Furthermore, jCanvas's event bindings are canvas-specific, so your drag events wouldn't be able to pass from one canvas to another anyway.
How could I change the x or y positon of one layer in a canvas when I am moving a layer in another canvas.
please find the attached
@radheprasad That's an easier thing to do. See the following code, which you can run in the jCanvas Sandbox (make sure you set the dropdown to render 2 canvases). Try it; if you drag the green circle, the blue circle will drag with it.
var $canvases = $('canvas');
var $canvas1 = $canvases.eq(0);
var $canvas2 = $canvases.eq(1);
$canvas1.drawArc({
layer: true,
draggable: true,
name: 'circle',
fillStyle: '#6c3',
x: 100, y: 100,
radius: 50,
drag: function (layer) {
$canvas2.setLayer('circle', {
x: layer.x, y: layer.y
}).drawLayers();
}
});
$canvas2.drawArc({
layer: true,
draggable: true,
name: 'circle',
fillStyle: '#36c',
x: 100, y: 100,
radius: 50,
drag: function (layer) {
$canvas1.setLayer('circle', {
x: layer.x, y: layer.y
}).drawLayers();
}
});
Thanks Sir, Let me implement this in my project. I will update you on this.
Thanks, now it working
my second query, How to show x, y and z coordinates value in html text boxes while dragging rectangle box with mouse. please help on this.
Hi I think got the coordinates values as below code. drag: function (layer) { $myCanvasTop.setLayer(layer.name, { x: layer.x }).drawLayers(); if (selectedLayer === "frontLayer0") { document.getElementById("MainContent_mytxt0").value = layer.x; document.getElementById("MainContent_mytxt1").value = layer.y; } else if (selectedLayer === "frontLayer1") { document.getElementById("MainContent_mytxt3").value = layer.x; document.getElementById("MainContent_mytxt4").value = layer.y;
}
}
please suggest me if my code is wrong.
Hi using 3d cube, how to get x y and z coordinates value on mouse drag?
Also this coordinates values should be changed by entering values in Asp.net text boxes.
please help by providing examples and supporting documents.
When I enter value into a html text box and the tab out. then how to change x, y coordinates of particular layer ? please help on this.
@radheprasad Maybe something like this?
$('#myInput').on('change', function () {
var parts = $(this).val().split(/,\s*/);
var x = parseFloat(parts[0]).x;
var y = parseFloat(parts[1]).y;
$('#mycanvas').setLayer('myLayerName', {
x: x, y: y
});
});
Thanks.
The provided code above is not helping to change x and y value of myLayerName. this below code I have used for my project. $('input').on('change', function () { var x = 200; //parseFloat(parts[0]).x; var y = 100; //parseFloat(parts[1]).y; var layers = $('canvas').getLayers(); $('#canvasFront').setLayer(layers[0].name, { x: x, y: y }); alert(layers[0].x)
});
x or y value not getting changed. please help.
now this is working after adding .drawlayers()
@radheprasad Yes, my apologies. You are correct in that you need to call drawLayers()
after calling setLayer()
; I forgot that part.
Hi Sir, No problem. Thanks for swift reply.
@radheprasad x: 0
and y: 0
actually reference the top-left corner of the canvas. Try setting your x
and y
to the width/height of the canvas divided by 2:
var $canvas = $('#mycanvas');
$canvas.drawRect({
layer: true,
name: 'myrect',
x: $canvas.width() / 2,
y: $canvas.height() / 2
});
Thanks for your support.
sir, How to show x and y direction with arrow marks beside of Jcanvas? Please find the attached file for your refe.
So far I got what needed. Thanks for your support.
Example: When I drag a layer from TOP canvas then a layer which in FRONT canvas should be Front. Please help. Refer the attached snapshot
The below code drag: function (layer) { $canvasFront.setLayer(layer.name, { x: layer.x, bringToFront: true }).drawLayers();
Please find the below full code
$canvasTop.drawRect({ layer: true, draggable: true, bringToFront: false, name: layerName, fillStyle: setRandomColor,//frontFillStyle[i], x: xPos + $canvasTop.width() / 2, y: zposFromTextbox, //yPos, width: Width, height: 10, shadowColor: 'rgba(0, 0, 0, 0.8)', mousedown: function (layer) { selectedLayer = layer.name; layersSplit = layer.name.split("_"); }, drag: function (layer) { $canvasFront.setLayer(layer.name, { x: layer.x, bringToFront: true }).drawLayers(); $canvasSide.setLayer(layer.name, { x: layer.y }).drawLayers();
When I drag a layer from TOP canvas then a layer which in FRONT canvas should be Front.
@radheprasad My apologies, but I do not understand your question. Could you please rephrase?
I have two canvas TOP and FRONT. My requirement is, when I am dragging a green line in TOP canvas and as soon as this green line crosses the red line in TOP canvas then the green square box in FRONT canvas should be shown in front and the red square box should be behind the green square box (mean swiped each other). here attached is snapshot for the same. please help on this.
please help on this.
@radheprasad You closed the issue recently, so I thought you had resolved it yourself. I see you have reopened it now, though.
I will try to help you tonight, but please bear with me—I have a lot going on this week.
@radheprasad Here I am! If I understand your intent correctly, you should be able to do this by combining the drag
event callback with the moveLayer
method.
The logic is a little tricky and surely took me a few tries, but it works perfectly now. Please test the following code in the jCanvas Sandbox with two canvases selected. If you drag the black circle across the line, the shapes on the second canvas will swap (I presume this is what you wanted, in essence).
var $canvas1 = $('canvas').eq(0);
var $canvas2 = $('canvas').eq(1);
var lockA = false;
var lockB = true;
function swapLayers() {
$canvas2
.moveLayer('square',
$canvas2.getLayer('circle').index)
.drawLayers();
}
$canvas1.drawArc({
layer: true,
draggable: true,
name: 'circle',
fillStyle: '#000',
x: 50, y: 50,
radius: 20,
drag: function(layer) {
if (!lockA && lockB && (layer.y >= $canvas1.getLayer('line').y1)) {
lockA = true;
lockB = false;
swapLayers();
}
if (lockA && !lockB && (layer.y <= $canvas1.getLayer('line').y1)) {
lockA = false;
lockB = true;
swapLayers();
}
}
});
$canvas1.drawLine({
layer: true,
name: 'line',
strokeStyle: '#000',
strokeWidth: 4,
x1: 0, y1: 120,
x2: 320, y2: 120
});
$canvas2
.drawArc({
layer: true,
draggable: true,
name: 'circle',
fillStyle: '#36c',
x: 150, y: 150,
radius: 50
})
.drawRect({
layer: true,
draggable: true,
name: 'square',
fillStyle: '#6c1',
x: 100, y: 100,
width: 100, height: 100
});
Thanks sir. I will let you know, after my try with the code provided me.
The code provided to me is working correct. but only for two layers. How to tackle if multiple layers. please find the snapshot in attachment. Basically, I want that,
@radheprasad facepalm I can't believe I missed how Top and Front are related. I see exactly what you want to do now.
Here's some code you can run in the jCanvas Sandbox (set to two canvases). The solution is pretty different compared to what I offered previously, and I'm pretty proud of it.
var $canvases = $('canvas');
var $canvas1 = $canvases.eq(0);
var $canvas2 = $canvases.eq(1);
function reorderSheets() {
// Order sheets according to their y-position
var topSheets = $canvas1.getLayerGroup('sheets');
topSheets.sort(function (sheet1, sheet2) {
return sheet1.y - sheet2.y;
});
topSheets.forEach(function (sheet, s) {
// Update z-position of front sheet according to above order
$canvas2.moveLayer(sheet.name, s);
// Update x/y of front sheet according to new z-position
$canvas2.setLayer(sheet.name, {
x: 120 + (10 * s),
y: 90 + (10 * s)
})
.drawLayers();
});
}
// Top
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'blue',
groups: ['sheets'],
fillStyle: '#36c',
x: 160, y: 40,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'purple',
groups: ['sheets'],
fillStyle: '#c3c',
x: 160, y: 80,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'orange',
groups: ['sheets'],
fillStyle: '#f70',
x: 160, y: 120,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'green',
groups: ['sheets'],
fillStyle: '#6c3',
x: 160, y: 160,
width: 250, height: 16,
drag: reorderSheets
});
// Front
$canvas2.drawRect({
layer: true,
name: 'blue',
groups: ['sheets'],
fillStyle: '#36c',
x: 120, y: 90,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'purple',
groups: ['sheets'],
fillStyle: '#c3c',
x: 130, y: 100,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'orange',
groups: ['sheets'],
fillStyle: '#f70',
x: 140, y: 110,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'green',
groups: ['sheets'],
fillStyle: '#6c3',
x: 150, y: 120,
width: 150, height: 150
});
Please let me know how that works for you.
Thanks for your support. this is very helpful sir. It is working fine.
Hello Sir, Thanks for your valuable support. I believe this could be my last query.
1.when X and Y coordinates are zero then my layers are going somewhat inside of Canvas. How to fix this issue so that they will be just edge of the canvas?
If you look at my layers in TOP Canvas, There is no space between them so what is command to provide space between layers (fyi I am using for loop for displaying layers and x, y & z values getting from table as shown in screenshot moreover my z value is nothing but y value in only TOP canvas)? FYI The below codes are used by me //Top layer------------------------------------------------------------------------------------------------- $canvasTop.drawRect({ layer: true, draggable: true, name: layerName, fillStyle: setRandomColor, y: zposFromTextbox + depthFromTextbox + pz, width: xPos + 1 Width + Height, height: depthFromTextbox2, shadowColor: 'rgba(0, 0, 0, 0.8)',
});
//Side Layer---------------------------------------------------------------------
$canvasSide.drawRect({
layer: true,
draggable: true,
bringToFront: false,
name: layerName,
fillStyle: setRandomColor,
x: zposFromTextbox + depthFromTextbox + pz,
y: yPos,
width: depthFromTextbox*2,
height: xPos + 1 * Width + Height,
shadowColor: 'rgba(0, 0, 0, 0.8)',
});
//Front Layer--------------------------------------------------------------------- $canvasFront.drawRect({ layer: true, draggable: true, //bringToFront: false, name: layerName, fillStyle: setRandomColor, x: xPos, y: yPos, width: xPos + 1 Width, height: yPos + 1 Height, });
please help on this.
Finally our images should come as below image
By default, jCanvas drawings are drawn from their center. That is, the (x, y) properties for a given shape lie at the center of that shape. If you set fromCenter: false
, it will draw from the top-left corner instead. I think this is what you want.
Great question. You can try using scaleCanvas()
(with restoreCanvas()
to transform the canvas coordinate system, like so:
var $canvas = $('canvas');
// Flip coordinate system so that (0, 0)
// is at bottom-left corner of canvas
$canvas.translateCanvas({
layer: true,
translateY: $canvas.height()
});
$canvas.scaleCanvas({
layer: true,
scaleY: -1,
x: 0, y: 0
});
// Draw the rest of your layers between
// scaleCanvas() and restoreCanvas()
$canvas.drawArc({
layer: true,
fillStyle: '#000',
x: 100, y: 100,
radius: 50
});
// Restore transformations
$canvas.restoreCanvas({
layer: true,
count: 2
});
Try it out in the jCanvas Sandbox.
Thanks yes this is what i need. Thanks a lot a gain. Last my query.
Hi Sir, with regarding to point no. 2 (show images in bottom left corner of canvas)
this code is working fine. but while dragging top layer image then images in bottom is immediate moving towards top of canvas. the below code please run it on jCanvas Sandbox. var $canvases = $('canvas'); var $canvas1 = $canvases.eq(0); var $canvas2 = $canvases.eq(1);
function reorderSheets() {
// Order sheets according to their y-position
var topSheets = $canvas1.getLayerGroup('sheets');
topSheets.sort(function (sheet1, sheet2) {
return sheet1.y - sheet2.y;
});
topSheets.forEach(function (sheet, s) {
// Update z-position of front sheet according to above order
$canvas2.moveLayer(sheet.name, s);
// Update x/y of front sheet according to new z-position
$canvas2.setLayer(sheet.name, {
x: sheet.x ,// + (10 * s), //
y: sheet.y// + (10 * s) ,//
})
.drawLayers();
});
}
//// Top
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'blue',
groups: ['sheets'],
fillStyle: '#36c',
x: 160, y:40,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'purple',
groups: ['sheets'],
fillStyle: '#c3c',
x: 160, y: 80,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'orange',
groups: ['sheets'],
fillStyle: '#f70',
x: 160, y: 120,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'green',
groups: ['sheets'],
fillStyle: '#6c3',
x: 160, y: 160,
width: 250, height: 16,
drag: reorderSheets
});
// Front
// Flip coordinate system so that (0, 0)
// is at bottom-left corner of canvas
$canvas2.translateCanvas({
layer: true,
translateY: $canvas2.height()
});
$canvas2.scaleCanvas({
layer: true,
scaleY: -1,
x: 0, y: 0
});
$canvas2.drawRect({
layer: true,
name: 'blue',
draggable:true,
groups: ['sheets'],
fillStyle: '#36c',
x: 130, y: 90,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'purple',
draggable: true,
groups: ['sheets'],
fillStyle: '#c3c',
x: 130, y: 100,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'orange',
draggable: true,
groups: ['sheets'],
fillStyle: '#f70',
x: 140, y: 110,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'green',
draggable: true,
groups: ['sheets'],
fillStyle: '#6c3',
x: 150, y: 120,
width: 150, height: 150
});
// Restore transformations
$canvas2.restoreCanvas({
layer: true
,count: 2
});
please help me to fix this issue. need your help here
@radheprasad I see exactly what you mean. Try the below code in the jCanvas Sandbox. I'm pretty proud of it; the math was fun to work out.
Please tweak it according to your needs, and don't hesitate to send me any questions about how it's implemented. The trick was to account for the initial X/Y positions of all layers, combined with some math to better handle the movement on each canvas.
var $canvases = $('canvas');
var $canvas1 = $canvases.eq(0);
var $canvas2 = $canvases.eq(1);
function reorderSheets() {
// Order sheets according to their y-position
var topSheets = $canvas1.getLayerGroup('sheets');
topSheets.sort(function (sheet1, sheet2) {
return sheet1.y - sheet2.y;
});
topSheets.forEach(function (sheet, s) {
var topSheet = $canvas1.getLayer(sheet.name);
var bottomSheet = $canvas2.getLayer(sheet.name);
// Update z-position of front sheet according to above order
$canvas2.moveLayer(sheet.name, s);
// Update x/y of front sheet according to new z-position
var diffTopX = (topSheet._origX - topSheet.x);
var diffTopY = (topSheet._origY - topSheet.y);
// The percentage of x/y change on the top canvas that defines the x/y
// change on the bottom canvas (for example, dragging a sheet 100px on
// the top canvas equates to 25px of movement the bottom canvas)
var movementDelta = 0.25;
$canvas2.setLayer(sheet.name, {
x: bottomSheet._origX + diffTopX - (diffTopY * movementDelta),
y: $canvas2.prop('height') - (bottomSheet._origY - diffTopY * movementDelta)
})
.drawLayers();
});
}
//// Top
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'blue',
groups: ['sheets'],
fillStyle: '#36c',
x: 160, y:40,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'purple',
groups: ['sheets'],
fillStyle: '#c3c',
x: 160, y: 80,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'orange',
groups: ['sheets'],
fillStyle: '#f70',
x: 160, y: 120,
width: 250, height: 16,
drag: reorderSheets
});
$canvas1.drawRect({
layer: true,
draggable: true,
name: 'green',
groups: ['sheets'],
fillStyle: '#6c3',
x: 160, y: 160,
width: 250, height: 16,
drag: reorderSheets
});
// Front
// Flip coordinate system so that (0, 0)
// is at bottom-left corner of canvas
$canvas2.translateCanvas({
layer: true,
translateY: $canvas2.height()
});
$canvas2.scaleCanvas({
layer: true,
scaleY: -1,
x: 0, y: 0
});
$canvas2.drawRect({
layer: true,
name: 'blue',
draggable:true,
groups: ['sheets'],
fillStyle: '#36c',
x: 120, y: 90,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'purple',
draggable: true,
groups: ['sheets'],
fillStyle: '#c3c',
x: 130, y: 100,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'orange',
draggable: true,
groups: ['sheets'],
fillStyle: '#f70',
x: 140, y: 110,
width: 150, height: 150
});
$canvas2.drawRect({
layer: true,
name: 'green',
draggable: true,
groups: ['sheets'],
fillStyle: '#6c3',
x: 150, y: 120,
width: 150, height: 150
});
// Restore transformations
$canvas2.restoreCanvas({
layer: true
,count: 2
});
$canvas1.getLayerGroup('sheets').forEach(function (topSheet) {
topSheet._origX = topSheet.x;
topSheet._origY = topSheet.y;
});
$canvas2.getLayerGroup('sheets').forEach(function (bottomSheet) {
bottomSheet._origX = bottomSheet.x;
bottomSheet._origY = bottomSheet.y;
});
Thanks for reply/support. I go through this code and update you.
Hi Sir, How to show quite big layers inside the canvases, so that these layers are in clear visibility please?
Basically, I don't want zoom the layers on any event. Just I want to show quite big size of layers inside the canvases by default so that layers could be more visibility. If you look at TOP canvas, lines/layers are quite smaller ( I mean Canvas is a big and layers are small). please help on this to achieve my requirement.
Hi again, @radheprasad. Please check out my jCanvas Panzoom Demo, which has all the code you should need to implement panning/zooming with jCanvas:
https://github.com/caleb531/jcanvas-panzoom-demo
How to show layer name using tooltip on mouse over and mouse out event please? Waiting for this please.
@radheprasad Apologies for my long delay in response.
But in short, you'll need to have three layers: one is the main layer that you hover over, one for the tooltip body, and one for the tooltip text. See my code example below—be sure to try it in the Sandbox:
var $canvas = $('canvas');
$canvas.addLayer({
type: 'text',
layer: true,
groups: ['tooltip-mycircle'],
opacity: 0,
fillStyle: '#000',
x: 150, y: 100,
fontSize: 24,
fontFamily: 'Verdana, sans-serif',
text: 'Hello'
});
var textProps = $canvas.measureText(0);
$canvas.addLayer({
type: 'rectangle',
layer: true,
index: 0,
groups: ['tooltip-mycircle'],
opacity: 0,
fillStyle: '#9cf',
strokeStyle: '#000',
strokeWidth: 1,
x: 150, y: 100,
width: textProps.width + 20, height: textProps.height + 15
});
$canvas.addLayer({
type: 'arc',
layer: true,
name: 'mycircle',
index: 0,
fillStyle: '#c33',
strokeStyle: '#000',
strokeWidth: 1,
x: 150, y: 180,
radius: 50,
mouseover: function (layer) {
$canvas
.stopLayerGroup('tooltip-' + layer.name)
.animateLayerGroup('tooltip-' + layer.name, {
opacity: 1
});
},
mouseout: function (layer) {
$canvas
.stopLayerGroup('tooltip-' + layer.name)
.animateLayerGroup('tooltip-' + layer.name, {
opacity: 0
});
}
});
$canvas.drawLayers();
Hi Sir, How to show quite big layers inside the canvases, so that these layers are in clear visibility please? Basically, I don't want zoom the layers on any event. Just I want to show quite big size of layers inside the canvases by default so that layers could be more visible. If you look at TOP canvas, lines/layers are tiny ( I mean Canvas is a big and layers are so small). please help on this to achieve my requirement and the attachment for your reference.
@radheprasad My sincere apologies for my very late response.
You have a few options:
You already have some rectangles with lines. You draw them by passing them points, widths, and heights. If you multiply those values by some number, you can make the shapes appear larger.
For example, if you are doing this:
$canvas.addLayer({
type: 'rectangle',
layer: true,
index: 0,
groups: ['tooltip-mycircle'],
opacity: 0,
fillStyle: '#9cf',
strokeStyle: '#000',
strokeWidth: 1,
x: 150, y: 100,
width: textProps.width + 20, height: textProps.height + 15
});
You can modify the numbers to scale them up by 2:
var scale = 10;
$canvas.addLayer({
type: 'rectangle',
layer: true,
index: 0,
groups: ['tooltip-mycircle'],
opacity: 0,
fillStyle: '#9cf',
strokeStyle: '#000',
strokeWidth: 1 * scale,
x: 150 * scale, y: 100 * scale,
width: (textProps.width + 20) * scale, height: (textProps.height + 15) * scale
});
Check out https://projects.calebevans.me/jcanvas/docs/scaleCanvas/#layers. For the top canvas at least, you will want to use a scaleCanvas
layer that's applied as the first layer on your canvas (so it affects successive layers). Then use a restoreCanvas()
to reset the transformation for the next redraw.
$('canvas').scaleCanvas({
layer: true,
name: 'zoom'
});
// your other layers here ->
$('canvas').restoreCanvas({
layer: true
});
Caleb
I have created three canvas for Rectangle boxes. now my query is, how to move a rectangle in one canvas
when dragging a rectangle box in another canvas. please help me as soon as possible.