jsPlumb and jQuery.PanZoom dragging issue - javascript

I used jquery.panzoom plugin in order to zoom and pan jsPlumb diagrams and every things is working find but when i zoom and drag an element this one goes far away from the pointer!
Does someone facing the same issue? can some one help me with this?
Thanks

see this
http://jsfiddle.net/a4v2guvt/
$panzoom.on('panzoomzoom', function (e, panzoom, scale) {
jsPlumb.setZoom(scale);
});

To fix this i used jQueryUI/draggable instead of builtin one:
var currentScale = 1;
$container.find(".diagram .item").draggable({
start: function(e){
var pz = $container.find(".panzoom");
//we need current scale factor to adjust coordinates of dragging element
currentScale = pz.panzoom("getMatrix")[0];
$(this).css("cursor","move");
pz.panzoom("disable");//disable panzoom to avoid double offset
},
drag:function(e,ui){
//fix scale issue
ui.position.left = ui.position.left/currentScale;
ui.position.top = ui.position.top/currentScale;
if($(this).hasClass("jsplumb-connected"))
{
plumb.repaint($(this).attr('id'),ui.position);
}
},
stop: function(e,ui){
var nodeId = $(this).attr('id');
plumb.repaint(nodeId,ui.position);
$(this).css("cursor","");
//enable panzoom back
$container.find(".panzoom").panzoom("enable");
}
});
Look at this demo

Related

Draggable containment buggs when the draggable element is rotated

I have a draggable element, which is also resizable and rotatable. These rotations are handled by CSS transformations, however, when an element is rotated, it makes the draggable feature spin out of control.
Heres a (updated) fiddle: Click me
What I think happens is that when an element is rotated, it's height and width obviously stay the same, just at an angle, however, jQuery doesn't account for the rotation, making it think that the element is in it's normal horizontal way, which results in the "bugg" shown in the fiddle above.
In a wild goose chase for the answer, I read somewhere that this would do the trick:
refreshPositions: true,
But it didn't work. Neither did destroying the draggable function on the element and then reinitiating it. Is there a way to fix this, so the containment will function normally, thus making jQuery recognise the rotation?
Thanks.
One option is to handle the containment yourself. Here is one possible way to do that.
I am using getBoundingClientRect to get the height and width of the rotated element. Using these values I can get an idea of where the dragged element resides in relation to it's parent container and force it to stay within those bounds.
var boundingContainer, boundingDraggable, prevLeft, prevTop;
$(".draggable").draggable({
classes: {
"ui-draggable-dragging": "highlight-draggable"
},
start: function(event, ui) {
boundingDraggable = ui.helper[0].getBoundingClientRect();
boundingContainer = ui.helper.closest('#draggableContainer')[0].getBoundingClientRect();
},
drag: function(event, ui) {
if(ui.offset.left <= boundingContainer.left){
if(ui.position.left < prevLeft){
ui.position.left = prevLeft;
}
}
if(ui.offset.top <= boundingContainer.top){
if(ui.position.top < prevTop){
ui.position.top = prevTop;
}
}
if(ui.offset.left+boundingDraggable.width >= boundingContainer.right){
if(ui.position.left > prevLeft){
ui.position.left = prevLeft;
}
}
if(ui.offset.top+boundingDraggable.height >= boundingContainer.bottom){
if(ui.position.top > prevTop){
ui.position.top = prevTop;
}
}
prevLeft = ui.position.left;
prevTop = ui.position.top;
}
});
Fiddle

Adding a scale to canvas image zoom

I'm using a some code from https://github.com/dimxasnewfrozen/Panning-Zooming-Canvas-Demos/blob/master/demo12/main.js (demo at http://dayobject.me/canvas/demo12/) to zoom in on an image using the Canvas element.
However, when zooming the jump between one zoom level and the next is too large, so I need to add a scale parameter.
How would I got about doing this?
In your main.js, you can change your zoomLevel here,
mouseWheel: function (e) {
e.preventDefault() // Please add this, coz the scroll event bubbles up to document.
var zoomLevel = 2;
...
if (delta > 0)
{
// ZOOMING IN
var zoomedX = canvasPos.deltaX - (canvasZoomX - canvasPos.deltaX);
var zoomedY = canvasPos.deltaY - (canvasZoomY - canvasPos.deltaY);
// scale the image up by 2
initialImageWidth = initialImageWidth * zoomLevel;
}
else
{
// ZOOMING OUT
var zoomedX = (canvasPos.deltaX + canvasZoomX);
var zoomedY = (canvasPos.deltaY + canvasZoomY);
// scale the image down by 2
initialImageWidth = initialImageWidth / zoomLevel;
}
}
Disclaimer: this ruins the zoomedX and zoomedY values. You gotta fix them :)
It seams to me as if the algorithm always takes half of the dimension befor the zoom. At the end of you code you see it in main.js the mouseWheel function:
initialImageWidth = initialImageWidth * 2;
the width is divided by 2 so just change the used value.
You said the step used to zoom in and out is too big.
So I suggest that you generate the new value by using the dimensions of the image you want to zoom. For example you take a percentage of the biggest dimension of the current image.
That's how you can implement a zoom function that zooms according to the dimensions of the image

Covering the first element or block of the page when scrolling downwards

I wanted to achieve an effect like this http://www.offset.com/
as you can see when it scrolls it slowly covering the carousel rather than scrolling with it.
I've tried using background fixed but the problem is the elements inside it will not stay in its position
Maybe there is a good technique in achieving this, Thanks
this is called parallax scrolling here is an example of how to do this using Jquery :
Live Demo
// Y axis scroll speed
var velocity = 0.5;
function update(){
var pos = $(window).scrollTop();
$('.container').each(function() {
var $element = $(this);
// subtract some from the height b/c of the padding
var height = $element.height()-18;
$(this).css('backgroundPosition', '50% ' + Math.round((height - pos) * velocity) + 'px');
});
};
$(window).bind('scroll', update);
an other example it might help DEMO

How to drag a DIV so its width and height are negative values?

I'm a bit stumped here. I am developing a feedback utility that will allow the user to "draw" boxes on a web page to highlight problem areas. Right now I have an overlay DIV that fills the screen and jQuery allows you to draw red outlined DIVs by clicking and dragging.
Here is the JS:
{
var $feedbackOverlay = jQuery('#feedbackOverlay');
var $original = { top: 0, left:0 };
$feedbackOverlay.bind('mousedown', function (e)
{
jQuery('<div id="currentHighlight"></div>')
.css('width', '1px')
.css('height', '1px')
.css('border', 'solid 3px #ff0000')
.css('border-radius', '5px')
.css('position', 'absolute')
.css('left', e.pageX)
.css('top', e.pageY)
.css('z-index', '8000001')
.appendTo('body');
$original = { top: e.pageY, left: e.pageX };
});
$feedbackOverlay.bind('mousemove', function (e)
{
var $currentHighlight = jQuery('#currentHighlight');
if ($currentHighlight.length > 0)
{
var $pos = { top: e.pageY, left: e.pageX };
if($pos.top < $original.top) $currentHighlight.css('top', $pos.top);
if ($pos.left < $original.left) $currentHighlight.css('left', $pos.left);
$currentHighlight.height(Math.abs($pos.top - $original.top));
$currentHighlight.width(Math.abs($pos.left - $original.left));
}
});
$feedbackOverlay.bind('mouseup', function (e)
{
var $currentHighlight = jQuery('#currentHighlight');
$currentHighlight.removeAttr('id');
});
var $feedbackInstructions = jQuery('#feedbackInstructions');
$feedbackInstructions.fadeIn(1000, function ()
{
setTimeout(function ()
{
$feedbackInstructions.fadeOut(1000);
}, 3000);
});
$feedbackOverlay.height(jQuery(document).height());
});
Here is a jsFiddle for the above:
http://jsfiddle.net/Chevex/RSYTq/
The problem is that I can't drag the boxes up or left. The first click puts the top left corner where the mouse clicked. After that subsequent dragging will change the width of the box. Letting go of the mouse completes the box and you may then start drawing another one. If you try to drag the DIV left or up while drawing it's width will remain at 0 but won't go negative.
Here you can find working solution: http://jsfiddle.net/RSYTq/34/
Something like this will get you closer to what you want: http://jsfiddle.net/RSYTq/18/
Doesn't quite handle move up and to the left and then switching to moving down and to the right quite right yet but it gives you the idea.
There's no such thing a a negative width - these are not coorindinates. You need to reposition and recalculate the corner positions relative to the corner that's not being moved.
Sounds like you need to check if the click origin (x,y) is > than the current mouse position, and then swap which one you use for the CSS top-left.
You would need to track the original start point somewhere (variables, data attributes on #currentHighlight, wherever you want), and check for width or height < 0. When so, set the #currentHighlight left/top CSS to be offset by original + (e.pageX - $currentHighlight.position().left) (for example). Then set the #currentHighlight width/height to the same difference (but positive: (e.pageX - $currentHighlight.position().left) * -1).

jQuery UI draggable wont go back to first point

I have a jQuery UI draggable element. It's extremely simple. It's just a div (container) with another div inside (draggable piece) set to a grid. The problem is after I move the element one time I can't go back to the first point. If i change the grid size it works, but I need it to work on this grid as it's matching some element below it
Relevant JS:
$('<div class="slider_wrap"><div class="slider"></div></div>').appendTo('#chart');
$('#chart .slider')
.draggable({
containment:'parent',
grid:[distanceBetweenPoints,0],
opacity: 0.25
})
.bind('mousedown', function(e, ui){
// bring target to front
$(e.target.parentElement).append( e.target );
})
.bind('drag', function(e, ui){
// update coordinates manually, since top/left style props don't work on SVG
e.target.setAttribute('x', ui.position.left);
})
.bind('dragstop',function(e, ui){
//a = true offset of slider piece
var a = ui.position.left + distanceBetweenPoints;
var b = containerWidth;
var c = thePoints.length;
var d = b / c;
var x = a / d;
//Since the points are in an array which starts at 0, not 1, we -1 from the currentPoint
console.log(x)
var currentPoint = Math.round(x)-1;
thisPointIndex = currentPoint;
chart.series[0].data[currentPoint].select(true);
});
Any ideas?
Example:
http://jsbin.com/ucebar
You're using a fractional grid size, for example 39.7 px. So, with each drag, the div gets offset a pixel to the left. This means that position zero quickly becomes unavailable:
That is: at point 1, ui.position.left will be 38 pixels or less.
Since moving the minimum jump (39.7px) -- towards point 0 -- will take the div outside the bounding rectangle, that move is not allowed.
And, using the nearest integer for grid size will quickly result in misalignment between the grid and the data points.
One way around all this is to:
Delete the grid:[distanceBetweenPoints,0], parameter.
Instead, snap the div upon drag stop, like so:
/*--- Snap to nearest grid.
*/
var gridPos = Math.round (
Math.round (ui.position.left / distanceBetweenPoints)
* distanceBetweenPoints
);
var delta = gridPos - ui.position.left;
var newOffset = $(this).offset ().left + delta;
$(this).offset ( {left: newOffset} );
See it in action at jsBin.
I didnt have time to work out a real solution, but I found that if you drag and drop the slider moves slightly more to the left each time. The reason it can't go back into first place is that after the first drop, there is not enough room anymore. Good luck!
I was able to solve it with the following:
.draggable({
...
drag : function(event, ui) {
ui.position.left = Math.round(ui.position.left / distance_between_points) * distance_between_points;
}
});

Categories