change height and width of dropped element dynamically - javascript

I have created a drag n drop file in which the user will enter the coordinates like 3*4 when the dropped element is clicked, using scalar factor I get height and width for the element. I want to change the height and width of the dropped element. Can anyone help?
$(document).ready(function () {
var x = null;
// Make element draggable
$(".drag").draggable({
helper: 'clone',
cursor: 'move',
tolerance: 'fit'
});
var i = 1, j = 0;
var x1, x2, y1, y2, tmp, tmp2;
var sf = pf;
$("#droppable").droppable({
drop: function(e, ui) {
var attr = ui.helper.attr('id');
if (typeof attr == typeof undefined || attr == false) {
ui.helper.attr('id',"id"+i);
}
tmp = ui.helper.attr('id');
x = ui.helper.clone().bind("click",'img',function(){
alert("clicked"+ ui.helper.attr('id') + tmp);
leftpos = ui.offset.left-210;
toppos = ui.offset.top;
var cor = window.prompt("Enter coordinates x1,y1");
var c = cor.split(',');
var w = c[0]*sf;
var h = c[1]*sf;
w = w/2;
h = h/2;
ui.helper.width(leftpos-w);
ui.helper.height(toppos-h);
});
x.draggable({
helper: 'original',
containment: '#droppable',
tolerance: 'fit',
});
x.appendTo('#droppable');
ui.helper.remove();
i++;
}
});
});

There are couple of things which are missing in your code.
The click event handler is a closure , which means it would have access to ui.helper even though the event handler function is executed outside its defined scope. but to change the width and height, you need to refer to the current event bounded object via this keyword.
variable pf is undefined, so I have defined one local variable with the same name.
With your current logic, the target dropped item looks odd, so I have set the static value of 300 for width and height in below jsfiddle.
JS CODE:
x= ui.helper.clone().bind("click", 'img', function() {
//leftpos = ui.helper.offset.left - 210;
//toppos = ui.helper.offset.top;
leftpos = ($(this).offset().left) - 210;
toppos = ($(this).offset().top);
...
//ui.helper.width(leftpos-w);
//ui.helper.height(toppos-h);
$(this).width(300);
$(this).height(300);
Live Demo # JSFiddle

Related

issue with jquery-ui and helper/ghost blocking elements identity

the code below is a standard resizable() jQuery-ui Widget.
how is it possible to know what is the object it being dragged on to ?
i have tried to catch it using the clientX and more... but it did not "deliver" the actual element. i have tried without ghost which was inter-fearing in middle of the way to discover what is layed under. though this is not the issue i guess.
$([selector]).resizable({
//some featurs/options and then
resize:
function (event, obj) {
var x = event.clientX, y = event.clientY,
var elementMouseIsOver = document.elementFromPoint(x, y);
}
});
any help would be appreciated .
take a look on the z-index i have applied to resizable div
i have lowered it conditionally.
so if it is over some other ide'd object, i will then be able to access its properties rather the blocking resizable .
$('document').ready(function () {
$('#resz').resizable({
handles: 'n, s',
resize:
function (event, obj) {
var H = obj.size.height;
var curobj = $(this);
var target = curobj;
var x = event.clientX, y = event.clientY;
var elementMouseIsOver = document.elementFromPoint(x, y);
if (elementMouseIsOver.id != "") //&& elementMouseIsOver.id != this.id)
{
curobj.css("z-index", "-1");
target = $("#" + elementMouseIsOver.id); //.css('display', 'none');
$("#deb").html("found " + target.attr("id") + " at " + target.css("z-index"));
}
}
});
});

Moving randomly placed boxes with the mouse

I have created a program that populates the canvas with randomly positioned boxes with random colors. That part was easy, problem im having is that I would like to move any of these colored boxes around with my mouse. As well, the pointer must stay a costant distance from the top-left corner. My code is below, any help would be greatly appreciated!
window.onload = init;
function init() {
var x= Math.floor(Math.random()*400);
var y= Math.floor(Math.random()*400);
var body = document.getElementsByTagName("body")[0];
var canvas = document.createElement("canvas");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
var context = canvas.getContext("2d");
// Repeat to draw a rectangle 100 times
for(var i=0;i<100;i++){
var color = '#'+ Math.round(0xffffff * Math.random()).toString(16);
context.fillStyle = color;
//Each rectangle is at (0 ~ width of window, 0 ~ height of window)
//Each rectangle's size is 50x50)
context.fillRect(Math.random()*window.innerWidth,
Math.random()*window.innerHeight, 50, 50);
}
document.body.appendChild(canvas);
}
var mousePiece = null;
function init2() {
//we are grabbing the div elm by uts id
// var divEl = document.getElementById("ace");
var cx = document.querySelector("canvas").getContext("2d");
//divEl.style.top = getStyle(divEl,"top");
//divEl.style.left = getStyle(divEl,"left");
addEvent(cx, "mousedown", mouseGrab, false);
}
function mouseGrab(e) {
var evt = e || window.event;
mousePiece = evt.target || evt.srcElement;
addEvent(document, "mousemove", mouseMove, false);
addEvent(document, "mouseup", mouseDrop, false);
}
function mouseMove(e) {
var evt = e || window.event;
var mouseX = evt.clientX;
var mouseY = evt.clientY;
mousePiece.style.left = mouseX + "px";
mousePiece.style.top = mouseY + "px";
}
function mouseDrop(e) {
mousePiece = null;
removeEvent(document, "mousemove", mouseMove, false);
removeEvent(document, "mouseup", mouseDrop, false);
}
function addEvent(object, evName, fnName, cap) {
if (object.attachEvent)
object.attachEvent("on" + evName, fnName);
else if (object.addEventListener)
object.addEventListener(evName, fnName, cap);
}
function removeEvent(object, evName, fnName, cap) {
if (object.detachEvent)
object.detachEvent("on" + evName, fnName);
else if (object.removeEventListener)
object.removeEventListener(evName, fnName, cap);
}
function getStyle(object, styleName) {
if (window.getComputedStyle) {
return document.defaultView.getComputedStyle(object,
null).getPropertyValue(styleName);
} else if (object.currentStyle) {
return object.currentStyle[styleName]
}
}
I would consider JQuery UI draggable. I made you a JS Fiddle with random colors and all. There are many things you can do with JQuery UI so check the docs to find exactly what you need.
$( document ).ready( function () {
for ( var i = 0; i < 50; i++ ) {
var randomColor = Math.floor(Math.random()*16777215).toString(16);
var ranNum = Math.round( Math.random() * 65 )
$( ".boxHolder" ).append( '<div class="pos' + i + ' draggable ui-widget-content"></div>' )
$( ".pos" + i ).css({
"background" : "#" + randomColor,
"top" : 10 * i + "px",
"left" : ranNum * 6 + "px"
})
}
})
$( function() {
$( ".draggable" ).draggable()
})
The bad news is that the canvas element is a pixel map: when you draw something on it, you modify pixel values as if you were updating an image. Drawing on the canvas does not create HTML elements that can be assigned an id, grabbed, or moved around using event.target (the target in your case will be the canvas element).
The good news is that there are canvas libraries that create an object model on top of the canvas for items separately placed and then allow you to move them around. For example have a look at fabric.js for demonstrations of the operations it supports. Feel free to do more research on your options!
Also note two issues with the random color string:
Use Math.floor instead of Math.round to avoid ending up with a value of 2^24 (also corrected in ALFmachine's reply)
Defining CSS colors usig a hex digit string requires either 3 or 6 hex digits preceeded by '#'. To avoid color values being discarded by the CSS parser in your case, lead fill the hex digits with '0' to make up the 6 digits as required.
You could construct a CSS rbg() color string using three random integers in range 0 to 255 as the alternative.

jquery draggable containment array values for scaled container

If anyone could help me figure out how to make the draggable elements contained in a div that changes scale based on window size, i'd really appreciate any guidance.
If I do:
element.draggable({
cursor: "move",
containment: '#container'
});
What will happen is it gives me the containment for the regular size of the container. So if I have a transform: scale(1.5), there will be space in the container that the draggable element can not go.
I've also tried containment: 'parent' but that get's very glitchy.
EDIT
I've found out how to get the top and left containment but I can't figure out how to get the right and bottom.
var containmentArea = $("#container");
containment: [containmentArea.offset().left, containmentArea.offset().top, ???, ???]
I've tried width and height from containmentArea[0].getBoundingClientRect() but that doesn't seem to be the right move either.
Here is a jsfiddle of some example code.
A version with resetting the coordinates in the drag event (since they were being recalculated already for the scale transformations), without using the containment:
var percent = 1, containmentArea = $("#container");
function dragFix(event, ui) {
var contWidth = containmentArea.width(), contHeight = containmentArea.height();
ui.position.left = Math.max(0, Math.min(ui.position.left / percent , contWidth - ui.helper.width()));
ui.position.top = Math.max(0, Math.min(ui.position.top / percent, contHeight- ui.helper.height()));
}
$(".draggable").draggable({
cursor: "move",
drag: dragFix,
});
//scaling here (where the percent variable is set too)
Fiddle
In the example width and height of the container are obtained inside the dragevent, you could also store them when scaling for better performance. By having them calculated inside the event, they still work after rescaling, although the percent variable still has to be set. To be truly generic, it could be obtained inside the event as well (and instead of a fixed container, ui.helper.parent() could be used)
Since the offset inside the dragevent is (0,0) related to the container (at least it is for the current setup), took the liberty of simplifying originalleft + (position - originalposition)/percent to position / percent
Start offset didn't seem to be necessary any more, so left it out in the fiddle, but can be re-added if needed.
Take a look to this :
http://jsfiddle.net/z0gqy9w2/3/
The edited code is the following one :
// Matrix regex to take the scale value property of $('#container') element
var matrixRegex = /matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/,
matches = $('#container').css('transform').match(matrixRegex);
// Matches have this value : ["matrix(1.5, 0, 0, 1.5, 0, 0)", "1.5", "1.5"] , so we need matches[1] value :
var scaleValue = matches[1];
$(".draggable").draggable({
cursor: "move",
start: startFix,
drag: dragFix,
containment: [containmentArea.offset().left, containmentArea.offset().top,
( ( containmentArea.offset().left + ( containmentArea.width() * scaleValue ) ) - ( $(".draggable").width() * scaleValue ) ) ,
( ( containmentArea.offset().top + ( containmentArea.height() * scaleValue ) ) - ( $(".draggable").height() * scaleValue ) ) ]
});
As you see, here is the trick :
( ( containmentArea.offset().left + ( containmentArea.width() * scaleValue ) ) - ( $(".draggable").width() * scaleValue ) )
Your right max position will be : The main container left offset + the true width of the container ( with scale ) - the item true width (to let it inside the container).
(Tip: Be free to change the "percent" var value as you want too see the results)
regex ref
Here is my solution:
var _zoom = 1.2,
$element = $('.draggable-element'),
$container = $('#container');
var containmentW,
containmentH,
objW,
objH;
$element.draggable({
start: function(evt, ui) {
ui.position.left = 0;
ui.position.top = 0;
containmentW = $container.width() * _zoom;
containmentH = $container.height() * _zoom;
objW = $(this).outerWidth() * _zoom;
objH = $(this).outerHeight() * _zoom;
},
drag: function(evt, ui) {
var boundReached = false,
changeLeft = ui.position.left - ui.originalPosition.left,
newLeft = ui.originalPosition.left + changeLeft / _zoom,
changeTop = ui.position.top - ui.originalPosition.top,
newTop = ui.originalPosition.top + changeTop / _zoom;
// right bound check
if(ui.position.left > containmentW - objW) {
newLeft = (containmentW - objW) / _zoom;
boundReached = true;
}
// left bound check
if(newLeft < 0) {
newLeft = 0;
boundReached = true;
}
// bottom bound check
if(ui.position.top > containmentH - objH) {
newTop = (containmentH - objH) / _zoom;
boundReached = true;
}
// top bound check
if(newTop < 0) {
newTop = 0;
boundReached = true;
}
// fix position
ui.position.left = newLeft;
ui.position.top = newTop;
// inside bounds
if(!boundReached) {
// do stuff when element is dragged inside bounds
}
}
});
Link to fiddle

making a function works on specific widths

I am trying to make this function works only when the screen size is above 1024px.
//Parallax background image
var velocity = 0.5;
function update(){
var pos = $(window).scrollTop();
$('.parallax').each(function() {
var $element = $(this);
var height = $element.height();
$(this).css('background-position', '40%' + Math.round((height - pos) * velocity) + 'px');
});
};$(window).bind('scroll', update); update();
Here is what I have tried to do:
//Parallax background image
var velocity = 0.5;
$(window).on("ready resize", function() {
if ($(window).width() < 770) {
function update(){
var pos = $(window).scrollTop();
$('.parallax').each(function() {
var $element = $(this);
var height = $element.height();
$(this).css('background-position', '40%' + Math.round((height - pos) * velocity) + 'px');
});
};});$(window).bind('scroll', update); update();
I really don't know what I am doing wrong...
You haven't stated what the problem you're coming across is. If it's "my code doesn't work", then perhaps you should check your syntax first. Your braces are messed up.
//Initialize velocity and empty update function
var velocity = 0.5;
var update = function () {};
//When window is ready (content loaded) OR resized, execute the following function
$(window).on("ready resize", function () {
if ($(window).width() >= 1024) { //Check if window width is 1024px wide or larger
update = function () { //Set update to run this function when executed.
var pos = $(window).scrollTop(); //Get scrollbar position https://api.jquery.com/scrollTop/
//For each element with 'parallax' class, execute the following function
$('.parallax').each(function () {
var $element = $(this); //Get the current parallax-classed element
var height = $element.height(); //Save the current height of this element
//Set the CSS of this parallax-classed element set the background position
$(this).css('background-position', '40% + ' + Math.round((height - pos) * velocity) + 'px');
});
};
} else { //Execute if screen width is < 1024px
update = function () {}; //Set update to do nothing
}
});
//When window is scrolled through, run the update function
$(window).bind('scroll', update);
//update();
Last line is unnecessary, as resize will handle function value, and scroll will handle the execution.
You were missing a + or - within the background-position setting.
So for example, if the result of your Math.round() was "30", then Javascript would interpret that line as $(this).css('background-position', '40%30px'); which obviously would cause issues. I'm sure you wanted it to say something like $(this).css('background-position', '40% + 30px');.

How to know if a node intersects another node?

I want to know if a node intersects another node like this schema:
Use the DOM attributes top and left attributes to figure out where they are along with clientWidth and clientHeight
This fiddle checks for overlaps (assuming you move both boxes): http://jsfiddle.net/maniator/JnTaq/
Code:
$('.drag').draggable({
stop: function(event, ui) {
var others = $('.drag').not(this),
_self = this,
length = $(_self).width();
others.each(function(i, item) {
var this_left = parseInt(item.style.left) - length,
this_top = parseInt(item.style.top) - length;
if (ui.position.left > this_left && ui.position.top > this_top) {
var left = Math.abs(ui.position.left - this_left),
top = Math.abs(ui.position.top - this_top);
if (left <= (length*2) && top <= (length*2)) {
alert('overlap');
}
}
});
}
});

Categories