jQuery Resizable Handles fixed position - javascript

As seen in the attached fiddle https://jsfiddle.net/0ws7fws0/5/, user can resize the triangle using north east and south east position.
Below is the code being used
$(document).ready(function() {
var windowWidth = $("#div1").width();
var windowHeight = $("#div1").height();
$(".triangle").css({
"border-top-width": windowWidth / 2 + 'px '
});
$(".triangle").css({
"transform": "rotate(360deg)"
});
$(".triangle").css({
"border-right": windowWidth + 'px solid lightskyblue'
});
$(".triangle").css({
"border-bottom-width": windowWidth / 2 + 'px '
});
$("#div1").draggable({
containment: ".abcde"
});
});
$("#div1").resizable({
handles: "ne,se",
containment: ".abcde",
minHeight: 40,
minWidth: 40
}, {
start: function(e, ui) {
},
resize: function(e, ui) {
var height = Math.round(ui.size.height);
var width = Math.round(ui.size.width);
$(".triangle").css({
"border-top-width": height / 2 + 'px'
});
$(".triangle").css({
"border-bottom-width": height / 2 + 'px'
});
$(".triangle").css({
"border-right": width + 'px solid lightskyblue'
});
$(".triangle").css({
//"margin-top": height + 'px'
});
$(".triangle").css({
"transform": "rotate(360deg)"
});
},
stop: function(e, ui) {
var height = Math.round(ui.size.height);
var width = Math.round(ui.size.width);
}
});
Here user can stretch the triangle but the handle position should be fixed so that the position is not changed even if its resized i.e. ne and se handles can be used to resize but w handle should be fixed(disabled). How do I achieve the same ?

Solution :
What i have done
Break the triangle into two parts: lower and upper
Keep the fixed handle (let's say pin) at same level
Decrease the opp radius when handle(handle use to resize) and pin comes at the same level
See https://jsfiddle.net/0ws7fws0/12/
$(document).ready(function() {
var windowWidth = $("#div1").width();
var windowHeight = $("#div1").height();
$("#div1").draggable({
containment: ".abcde"
});
});
$("#div1").resizable({
handles: "ne,se",
containment: ".abcde",
minHeight: 40,
minWidth: 40
}, {
start: function(e, ui) {
},
resize: function(e, ui) {
var height = Math.round(ui.size.height);
var width = Math.round(ui.size.width);
},
stop: function(e, ui) {
var height = Math.round(ui.size.height);
var width = Math.round(ui.size.width);
var diff = Math.abs(ui.size.height - ui.originalSize.height);
var bottomW = parseInt($(".lower-triangle").css("borderBottomWidth"),10);
var topW = parseInt($(".upper-triangle").css("borderTopWidth"),10);
if (ui.size.height > ui.originalSize.height) {
if($(e.originalEvent.target).hasClass("ui-resizable-se")) {
$(".lower-triangle").css({
"border-bottom-width": (bottomW + diff) + 'px'
});
} else if ($(e.originalEvent.target).hasClass("ui-resizable-ne")) {
$(".upper-triangle").css({
"border-top-width": (topW + diff) + 'px'
});
}
}
else { /*when you compress*/
if($(e.originalEvent.target).hasClass("ui-resizable-se")) {
if ((bottomW - diff)>0) {
$(".lower-triangle").css({
"border-bottom-width": (bottomW - diff) + 'px'
});
}
else {
$(".lower-triangle").css({
"border-bottom-width": '0px'
});
$(".upper-triangle").css({
"border-top-width": ui.size.height + 'px'
});
}
} else if ($(e.originalEvent.target).hasClass("ui-resizable-ne")) {
if ((topW - diff)>0) {
$(".upper-triangle").css({
"border-top-width": (topw - diff) + 'px'
});
}
else {
$(".upper-triangle").css({
"border-top-width": '0px'
});
$(".lower-triangle").css({
"border-bottom-width": ui.size.height + 'px'
});
}
}
}
$(".lower-triangle, .upper-triangle").css({
"border-right": width + 'px solid lightskyblue'
});
}
});

Related

Resize Angular Material Bottom Sheet, when dragged from the bottom

I am using Angular Material Bottom Sheet, but I want it in such a way, that it should get adjusted, when the user drags it up and down from the bottom.
I have used one plugin to resize the bottom sheet, but the bottom sheet is getting dragged up and down without resizing, it's bottom is not fixed.
Here's the working code in plunkar.
resizer.js:
angular.module('mc.resizer', []).directive('resizer', function($document) {
return function($scope, $element, $attrs) {
$element.on('mousedown', function(event) {
event.preventDefault();
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
});
function mousemove(event) {
if ($attrs.resizer == 'vertical') {
// Handle vertical resizer
var x = event.pageX;
if ($attrs.resizerMax && x > $attrs.resizerMax) {
x = parseInt($attrs.resizerMax);
}
$element.css({
left: x + 'px'
});
$($attrs.resizerLeft).css({
width: x + 'px'
});
$($attrs.resizerRight).css({
left: (x + parseInt($attrs.resizerWidth)) + 'px'
});
} else {
// Handle horizontal resizer
var y = window.innerHeight - event.pageY;
if((window.innerHeight-100 > y)&&(y>100)){
$element.css({
bottom: y + 'px'
});
$($attrs.resizerTop).css({
bottom: (y + parseInt($attrs.resizerHeight)) + 'px'
});
$($attrs.resizerBottom).css({
height: y + 'px'
});
}
}
}
function mouseup() {
$document.unbind('mousemove', mousemove);
$document.unbind('mouseup', mouseup);
}
};
});

jQuery UI Droppable not working as expected on out: function

I would like to reset the score of my div scrolling across the jQuery slider to 0 if it is returned to it's original position.
here is a plnk + some code;
https://plnkr.co/edit/oqhrDeP52vdzcKqpQvbl?p=preview
$(init);
function init() {
function findPosition(e, ui) {
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
var finalMidPosition = ui.offset.left - 53 + Math.round($(divs).width() / 2 - 5)
if (finalMidPosition >= minX && finalMidPosition <= maxX) {
var val = Math.round((finalMidPosition - minX) / tickSize);
sliderDiv.slider("value", val);
$(".slider-value", this).html(val);
$("#text1").val($(".item1 .slider-value").html())
}
}
var range = 100;
var sliderDiv = $('#ratingBar');
sliderDiv.slider({
min: 0,
max: range,
});
var divs = '.itemContainer'
$(divs).draggable({
containment: "#containment",
cursor: 'move',
snap: '#ratingBar',
snapMode: 'outer',
drag: findPosition,
revert: function(event, ui) {
$(this).data("uiDraggable").originalPosition = {
top: 0,
left: 0
};
return !event;
}
});
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
$('#ratingBar').droppable({
tolerance: 'touch',
drop: findPosition,
out: function(event, ui) {
$(".slider-value", ui.draggable).html(0);
$("#text1").val($(".item1 .slider-value").html())
}
});
$(".slider-value").html(sliderDiv.slider('value'));
}
I have had this working as expected in a different plnk, which leads me to believe that the issue is with either using the Drag: findPosition inside the Draggable or using $(".slider-value", this).html(val); instead of a variation of $(".slider-value", ui.draggable).html(val);.
Below, is a plnk which has the desired effect, but does not automatically update the value;
https://plnkr.co/edit/GIfq7Ws0EsjyS7yRhIzl?p=preview
Thanks for any help/advice!
I offer this as a solution. I made some minor HTML changes and then updated the jQuery.
My Fork: https://plnkr.co/edit/IPRoqprQt34Q08pugO9T?p=preview
HTML
<div id="content">
<div id="containment">
<div id="itemArea">
<div id="row">
<div class="itemContainer">
<div class="item1">
<span class="slider-value"></span>
</div>
<div class="candle"></div>
</div>
</div>
<div id="barContainer">
<div id="ratingBar"></div>
</div>
</div>
</div>
</div>
jQuery
$(init);
var over = false;
function init() {
function findPosition(e, off) {
if (e == "out") {
over = false;
sliderDiv.slider("value", 0);
$(".slider-value").html(0);
$("#text1").val(0);
return;
}
if(e == "in"){
over = true;
}
if (over && e == "drag") {
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
var finalMidPosition = off.left - 53 + Math.round($(divs).width() / 2 - 5)
if (finalMidPosition >= minX && finalMidPosition <= maxX) {
var val = Math.round((finalMidPosition - minX) / tickSize); // had to add -12…
sliderDiv.slider("value", val);
$(".slider-value").html(val);
$("#text1").val(val)
}
}
}
var range = 100;
var sliderDiv = $('#ratingBar');
sliderDiv.slider({
min: 0,
max: range,
});
var divs = '.itemContainer'
$(divs).draggable({
containment: "#containment",
cursor: 'move',
snap: '#ratingBar',
snapMode: 'outer',
drag: function(e, ui) {
findPosition("drag", ui.offset);
},
revert: function(event, ui) {
$(this).data("uiDraggable").originalPosition = {
top: 0,
left: 0
};
return !event;
}
});
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
$('#ratingBar').droppable({
tolerance: 'touch',
drop: findPosition,
over: function(e, ui) {
$("#text1").addClass("hover");
findPosition("in", ui.offset);
},
out: function(event, ui) {
$("#text1").removeClass("hover");
findPosition("out", ui.offset);
$("#text1").val($(".item1 .slider-value").html());
}
});
$(".slider-value").html(sliderDiv.slider('value'));
}
This allows an intercept upon touch. Also, over only triggers once and does not continue to update throughout the drag. So I set a flag to indicate when over is true and when it is and drag is happening, we want to update the values. Once dropped, we can determine what to do. If the drag is out, we revert the value to 0.

Dragging elements on a scaled div

I've tried using jquery's built in draggable and I've tried using custom drag functions with no avail. Both have their respected issues and I will try to highlight both of them.
Basically, I am trying to allow the dragging of an element that is on a scaled div container. The following methods work okay on a scaled element that is less than around 2. But if you go any higher than that, we see some issues.
Any help would be appreciated. Thank you for your time.
HTML
<div id="container">
<div id="dragme">Hi</div>
</div>
Method 1 (Jquery draggable function)
I've tried the jquery draggable function as you can see in this jsfiddle example.
The problems I found in this example are the following:
Biggest concern: The droppable container does not change when it is scaled up. So if the element is being dragged over part of the scaled container that isn't a part of it's original size, it will fail.
When you click to drag a div, it teleports a little bit away from the mouse and is not a seamless drag.
JS
var percent = 2.5;
$("#dragme").draggable({
zIndex: 3000,
appendTo: 'body',
helper: function (e, ui) {
var draggable_element = $(this),
width = draggable_element.css('width'),
height = draggable_element.css('height'),
text = draggable_element.text(),
fontsize = draggable_element.css('font-size'),
textalign = draggable_element.css('font-size');
return $('<div id="' + draggable_element.id + '" name="' + draggable_element.attr('name') + '" class="text">' + text + '</div>').css({
'position': 'absolute',
'text-align': textalign,
'background-color': "red",
'font-size': fontsize,
'line-height': height,
'width': width,
'height': height,
'transform': 'scale(' + percent + ')',
'-moz-transform': 'scale(' + percent + ')',
'-webkit-transform': 'scale(' + percent + ')',
'-ms-transform': 'scale(' + percent + ')'
});
},
start: function (e, ui) {
$(this).hide();
},
stop: function (e, ui) {
$(this).show();
}
});
$("#container").droppable({
drop: function (event, ui) {
var formBg = $(this),
x = ui.offset.left,
y = ui.offset.top,
drag_type = ui.draggable.attr('id');
var element_top = (y - formBg.offset().top - $(ui.draggable).height() * (percent - 1) / 2) / percent,
element_left = (x - formBg.offset().left - $(ui.draggable).width() * (percent - 1) / 2) / percent;
$(ui.draggable).css({
'top': element_top,
'left': element_left
});
}
});
Method 2 - Custom drag function
I've tried using a custom drag function but it unusable after around a 2 scale.
jsfiddle on a scale(2) - Looks like the draggable div is having a seizure.
jsfiddle on a scale(2.5) - The draggable div flys away when you try to drag it.
JS
(function ($) {
$.fn.drags = function (opt) {
opt = $.extend({
handle: "",
cursor: "move"
}, opt);
if (opt.handle === "") {
var $el = this;
} else {
var $parent = this;
var $el = this.find(opt.handle);
}
return $el.css('cursor', opt.cursor).on("mousedown", function (e) {
if (opt.handle === "") {
var $drag = $(this).addClass('draggable');
} else {
$(this).addClass('active-handle')
var $drag = $parent.addClass('draggable');
}
var
drg_h = $drag.outerHeight(),
drg_w = $drag.outerWidth(),
pos_y = $drag.offset().top + drg_h - e.pageY,
pos_x = $drag.offset().left + drg_w - e.pageX;
follow = function (e) {
$drag.offset({
top: e.pageY + pos_y - drg_h,
left: e.pageX + pos_x - drg_w
})
};
$(window).on("mousemove", follow).on("mouseup", function () {
$drag.removeClass('draggable');
$(window).off("mousemove", follow);
});
e.preventDefault(); // disable selection
}).on("mouseup", function () {
if (opt.handle === "") {
$(this).removeClass('draggable');
} else {
$(this).removeClass('active-handle');
$parent.removeClass('draggable');
}
});
}
})(jQuery);
$("#dragme").drags({}, function (e) {});
Here are a few of my findings to make sure dragging on a scaled container works for method one. The only caveat is to make sure you have var percent as the scaled percentage declared before any of these actions happen.
First, use this code at the top of your javascript. This wil help making sure that the droppable area works with a sacled container.
$.ui.ddmanager.prepareOffsets = function( t, event ) { var i, j, m = $.ui.ddmanager.droppables[ t.options.scope ] || [], type = event ? event.type : null, list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); droppablesLoop: for ( i = 0; i < m.length; i++ ) { if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { continue; } for ( j = 0; j < list.length; j++ ) { if ( list[ j ] === m[ i ].element[ 0 ] ) { m[ i ].proportions().height = 0; continue droppablesLoop; }  } m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; if ( !m[ i ].visible ) { continue; } if ( type === "mousedown" ) { m[ i ]._activate.call( m[ i ], event ); } m[ i ].offset = m[ i ].element.offset(); m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth * percent, height: m[ i ].element[ 0 ].offsetHeight * percent }); } };
Here are a few functions that are necessary to fix the drag so it works on a scaled container.
function dragFix(event, ui) { var changeLeft = ui.position.left - ui.originalPosition.left, newLeft = ui.originalPosition.left + changeLeft / percent, changeTop = ui.position.top - ui.originalPosition.top, newTop = ui.originalPosition.top + changeTop / percent; ui.position.left = newLeft; ui.position.top = newTop; }
function startFix(event, ui) { ui.position.left = 0; ui.position.top = 0;  var element = $(this); }
You will want this if you want to enable the element to be resizable on a scaled container.
function resizeFix(event, ui) { var changeWidth = ui.size.width - ui.originalSize.width, newWidth = ui.originalSize.width + changeWidth / percent, changeHeight = ui.size.height - ui.originalSize.height, newHeight = ui.originalSize.height + changeHeight / percent;  ui.size.width = newWidth; ui.size.height = newHeight; }
To make an element draggable, I use the following function.
$("ELEMENT").resizable({ minWidth: - ($(this).width()) * 10, minHeight: - ($(this).height()) * 10, resize: resizeFix, start: startFix });
$("ELEMENT").draggable({ cursor: "move", start: startFix, drag: dragFix }); }
A similar problem is mentioned here: jquery - css "transform:scale" affects '.offset()' of jquery
It seems the problem arises from the fact that jQuery fails to return exact size for scaled elements and therefore failing setting right offset values to the element.
To solve this, he is suggesting first setting scale to 1 and setting offset and then again resetting scale value.
But this alone does not solve the problem here. Since mouse position is taken while it is scaled, position values should also be divided by scale value.
Here is an edited version of code:
var scl = 2.5;
var
drg_h = $drag.outerHeight(),
drg_w = $drag.outerWidth(),
pos_y = $drag.offset().top/scl + drg_h - e.pageY/scl,
pos_x = $drag.offset().left/scl + drg_w - e.pageX/scl;
follow = function(e) {
var size = {
top:e.pageY/scl + pos_y - drg_h+scl*2,
left:e.pageX/scl + pos_x - drg_w+scl*2
};
$drag.parent().css("transform","scale(1)");
$drag.offset(size);
$drag.parent().css("transform","scale("+scl+")");
};
Note: I only replaced scale value for transform tag, since I am using chrome. You can also replace all instances or instead you can use a different class with 1 scale value.
JSFiddle is also here.
Here is an example of simple drag with scaling, however, in prue dom.
<style>
#dragme {
position:absolute;
border:1px solid red;
background:pink;
left:10px;
top:20px;
width:100px;
height:200px;
}
#container {
transform: scale(2,2) translate(100px,100px);
position:relative;
border:1px solid green;
background:grey;
width:200px;
height:300px;
}
</style>
<body>
<div id="container">
<div id="dragme">Hi</div>
</div>
<script>
var dragme=document.getElementById("dragme");
var container=document.getElementById("container");
dragme.onmousedown=function Drag(e){
this.ini_X = this.offsetLeft-e.clientX/2;
this.ini_Y = this.offsetTop-e.clientY/2;
container.onmousemove = move;
container.onmouseup = release;
return false;
}
function move(e){
e.target.style.left = e.clientX/2 + e.target.ini_X + 'px';
e.target.style.top = e.clientY/2 + e.target.ini_Y + 'px';
}
function release(){
container.onmousemove=container.onmouseup=null;
}
</script>
</body>

jQuery on click scroll not working

The white block to the right of the image once clicked should slide across to the wonder-diner page but it doesn't seem to do anything.
http://www.wondercafe.co.uk/test/
I'm getting the following error message in element inspector:
Failed to load resource: the server responded with a status of 404 (Not Found)
<script type="text/javascript">
$.getDocHeight = function(){
return Math.max(
$(document).height(),
$(window).height(),
/* For opera: */
document.documentElement.clientHeight
);
};
$(document).ready(function() {
$('#wonder-diner #ajax-wrapper').load('/node/10 #wonder-diner', function() {
$('#wonder-diner #wonder-diner #clicker').remove();
$('#wonder-diner #ajax-wrapper #scroll').jScrollPane();
var centerwidth = $(window).width() - $('#sidebar-left').width() - $('#clicker').width() - $('#center').width() - 15;
$('#wonder-diner #center').css({ 'left' : centerwidth / 2 + $('#clicker').width() + 2.5, 'margin' : '0', 'position' : 'absolute' });
if ($(window).width() < 937) {
$('#wonder-diner #center').css({ 'right' : '230px' });
}
var contentHeight = $.getDocHeight() - ($('#footer').height() + 15) - (26 + 15) - 80; // Height of window - (footer height + padding bottom) - (margin top of #aqueeze + padding top) - padding on .inside
$('#wonder-diner #wrapper #container #center .inside').css({'height' : contentHeight});
$('#wonder-diner #scroll').css({'height' : contentHeight});
$('#wonder-diner #scroll').not($('.page-food-drink #scroll, .page-roastery-coffees #scroll')).jScrollPane({ verticalDragMaxHeight: 100 });
$(window).bind('resize', function () {
var contentHeight = $.getDocHeight() - ($('#footer').height() + 15) - (26 + 15) - 80; // Height of window - (footer height + padding bottom) - (margin top of #aqueeze + padding top) - padding on .inside
$('#wonder-diner #wrapper #container #center .inside').css({'height' : contentHeight});
var centerwidth = $(window).width() - $('#sidebar-left').width() - $('#clicker').width() - $('#center').width() - 15;
$('#wonder-diner #center').css({ 'left' : centerwidth / 2 + $('#clicker').width() + 2.5, 'margin' : '0', 'position' : 'absolute' });
$('#wonder-diner #scroll').css({'height' : contentHeight});
$('#wonder-diner #scroll').not($('.page-food-drink #scroll, .page-roastery-coffees #scroll')).jScrollPane({ verticalDragMaxHeight: 100 });
if ($(window).width() < 937) {
$('#wonder-diner #center').css({ 'right' : '230px' });
}
});
});
$('.scrollPage').click(function() {
var elementClicked = $(this).attr("href");
var destination = $(elementClicked).offset().left;
$("html:not(:animated),body:not(:animated)").animate({ scrollLeft: destination}, 500, 'linear' );
return false;
});
$('li.menu-2409 a').click(function() {
var elementClicked = $(this).attr("href");
var destination = $(elementClicked).offset().left;
$("#holder").animate({
left: '-100%'
}, 500, 'linear');
return false;
});
$('li.menu-2456 a').live('click', function() {
//var elementClicked = $(this).attr("href");
var destination = $('#restaurant').offset().left;
$("#holder").animate({
left: '0'
}, 500, 'linear');
return false;
});
});
</script>
.load('/node/10 #wonder-diner' is not a correct URL.

How do I add fade in effect when I click expand on this script?

I found this content expand/collapse jQuery plugin. I want to add fade-in effect to this plugin when I click on the EXPAND button.
How do I do this?
$(document).ready(function () {
var maxlines = 15;
var lineheight = 15; // line height in 'px'
var maxheight = (maxlines * lineheight);
var allowedExtraLines = 3;
var showText = "EXPAND";
var hideText = "CLOSE";
$('.ranking').each(function () {
var text = $(this);
if (text.height() > maxheight + allowedExtraLines * lineheight) {
text.css({ 'overflow': 'hidden', 'line-height': lineheight + 'px', 'height': maxheight + 'px' });
var link = $('' + showText + '');
link.click(function (event) {
event.preventDefault();
if (text.css('height') == 'auto') {
$(this).html(showText);
text.css('height', maxheight + 'px');
} else {
//$(this).remove();
$(this).html(hideText);
text.css('height', 'auto');
}
});
var linkDiv = $('<div></div>');
linkDiv.append(link);
$(this).after(linkDiv);
}
});
});
within the link.click function, you can do
text.animate({ opacity: 1.00 }, 600);
i think it'd go after text.css('height', 'auto'); in the else block. you'll probably have to reset the opacity to 0 somehow in the if block too.
for reference: http://api.jquery.com/animate/
edit: better yet, http://api.jquery.com/fadeIn/
so
text.fadeIn();

Categories

Resources