css 3d transform rotate (x + y) using mouse drag - javascript

i was recently diving into the world of css transform and wanted to rotate a div (x and y axis), i was able to do it with 2 sliders with 0 to 360 degree range but now looking forward to do it with dragging the mouse, i have made a very sloppy effort on that looking for suggestion to fix it:
jsfiddle link to test
"use strict";
let elContainer = $('#container');
let elBox = $('#box');
$(document).ready(function() {
$('.slider-rotate').on('input', function() {
sliderRotate();
});
elContainer.mousedown(function(e) {
initDragRotate(e);
});
elContainer.mousemove(function(e) {
dragRotate(e);
});
elContainer.mouseup(function(e) {
endDragRotate();
});
});
let dragging = false;
let delta = {};
function initDragRotate(e) {
dragging = true;
delta = {
x: e.pageX,
y: e.pageY,
};
}
function dragRotate(e) {
if (!dragging) {
return;
}
delta.x = e.pageX - delta.x;
delta.y = e.pageY - delta.y;
let rotateParam = '';
rotateParam += ' rotate' + 'Y' + '(' + delta.x + 'deg)';
rotateParam += ' rotate' + 'X' + '(' + delta.y + 'deg)';
elBox.css('transform', rotateParam);
}
function endDragRotate() {
if (!dragging) {
return;
}
dragging = false;
}
function sliderRotate() {
let rotateParam = '';
$('.slider-rotate').each(function() {
rotateParam += ' ' + getRotateParamString($(this));
});
elBox.css('transform', rotateParam);
}
function getRotateParamString(elClass) {
let val = elClass.val();
let rotateType = elClass.data('rotateType');
let rotateParam = 'rotate' + rotateType + '(' + val + 'deg)';
return rotateParam;
}
#container {
background: #ccc;
padding: 10vh;
display: flex;
align-items: center;
justify-content: center;
}
#box {
width: 30vh;
height: 30vh;
border: 5px solid #000;
position: relative;
transform-style: preserve-3d;
}
#box>div {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="box">
<div style="background: #f00;"></div>
<div style="background: #0f0;"></div>
</div>
</div>
<div id="control">
<br>
<label>
x
<input type="range" class="slider-rotate" data-rotate-type="X" min="0" max="360" value="0">
</label>
<br>
<label>
y
<input type="range" class="slider-rotate" data-rotate-type="Y" min="0" max="360" value="0">
</label>
</div>
also, there's 2 div on top and bottom (green and red) with transform-style preserve-3d property, hoping that it's show the other color when flipped but no luck! please suggest, thanks!

The calulation for how much to rotate is a little odd.
I believe what you need is to have the amount of rotation dependent on the amount the mouse is placed across and down the screen. To make this proportional to the screen size you need to divide it by the screen size and then multiply it by 360 to get the full range from pageX/Y being 0 to being at the right/bottom of the screen.
"use strict";
let elContainer = $('#container');
let elBox = $('#box');
$(document).ready(function() {
$('.slider-rotate').on('input', function() {
sliderRotate();
});
elContainer.mousedown(function(e) {
initDragRotate(e);
});
elContainer.mousemove(function(e) {
dragRotate(e);
});
elContainer.mouseup(function(e) {
endDragRotate();
});
});
let dragging = false;
let delta = {};
function initDragRotate(e) {
dragging = true;
delta = {
x: e.pageX,
y: e.pageY,
};
}
function dragRotate(e) {
if (!dragging) {
return;
}
// THIS IS THE CALCULATION THAT HAS CHANGED
delta.x = e.pageX / window.innerWidth * 360; //- delta.x;
delta.y = e.pageY / window.innerHeight * 360; // - delta.y;
let rotateParam = '';
rotateParam += ' rotate' + 'Y' + '(' + delta.x + 'deg)';
rotateParam += ' rotate' + 'X' + '(' + delta.y + 'deg)';
elBox.css('transform', rotateParam);
}
function endDragRotate() {
if (!dragging) {
return;
}
dragging = false;
}
function sliderRotate() {
let rotateParam = '';
$('.slider-rotate').each(function() {
rotateParam += ' ' + getRotateParamString($(this));
});
elBox.css('transform', rotateParam);
}
function getRotateParamString(elClass) {
let val = elClass.val();
let rotateType = elClass.data('rotateType');
let rotateParam = 'rotate' + rotateType + '(' + val + 'deg)';
return rotateParam;
}
#container {
background: #ccc;
padding: 10vh;
display: flex;
align-items: center;
justify-content: center;
}
#box {
width: 30vh;
height: 30vh;
border: 5px solid #000;
position: relative;
transform-style: preserve-3d;
}
#box>div {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="box">
<div style="background: #f00;"></div>
<div style="background: #0f0;"></div>
</div>
</div>
<div id="control">
<br>
<label>
x
<input type="range" class="slider-rotate" data-rotate-type="X" min="0" max="360" value="0">
</label>
<br>
<label>
y
<input type="range" class="slider-rotate" data-rotate-type="Y" min="0" max="360" value="0">
</label>
</div>

Related

jQuery If Statement Message

I have the code set up so that when the user inputs a negative number or an invalid value for the thickness of the pipe (greater than 1/3rd of the diameter), an error message pops up. However, when I enter a valid input, the error message does not go away, and only goes away when updating the value of the outer diameter for the circle. How do I make it so that the moment I enter a valid input for the thickness, the error message goes away, or the moment I delete the invalid input, the error message goes away.
Additionally, I am using this program on an actual webpage with a formidable forms calculator. The size of the circle is taken from the inputs for the calculator as I am trying to create a graphic visual for the user. However, after hitting the "calculate" button, the inputs in the form no longer dynamically change the size of the circle and I have to completely refresh the page to fix the issue. Why is this happening and how do I fix this?
$(function() {
$('.circle').hide();
$('#outer_diameter').on('change', function() {
var $outer_diameter = parseFloat($("#outer_diameter").val()).toFixed(3);
var $converted = ($outer_diameter * 3.75).toFixed(3);
if ($outer_diameter > 85) {
$("#error").text($outer_diameter + " is too big").show();
return false;
}
if ($outer_diameter < 0) {
$('#error').text('Please input positive integers').show();
return false;
}
console.log($outer_diameter, $converted);
$('.circle').css({
height: (2 * $converted),
width: (2 * $converted),
top: "calc(50% - " + ($converted) + "px)",
left: "calc(50% - " + ($converted) + "px)"
});
$('.circle').fadeIn(300);
$('.circles').css({
height: (2 * $converted) + 10,
width: (2 * $converted) + 10
})
$('#error').hide();
})
$('.circle2').hide();
$('#inner_diameter').on('change', function() {
var $outer_diameter = parseFloat($("#outer_diameter").val()).toFixed(3);
var $inner_diameter = parseFloat($("#inner_diameter").val()).toFixed(3);
var $converted_2 = (($outer_diameter * 3.75) - (2 * ($inner_diameter * 3.75))).toFixed(3);
if ($outer_diameter > 85) {
$("#error")
return false;
}
if ($inner_diameter < 0) {
$('#error').text('Please input positive integers').show();
return false;
}
if ($inner_diameter >= 0.33 * $outer_diameter) {
$('#error').text('Wall Thickness invalid').show();
return false;
}
console.log($inner_diameter, $converted_2);
$('.circle2').css({
height: (2 * $converted_2),
width: (2 * $converted_2),
top: "calc(50% - " + ($converted_2) + "px)",
left: "calc(50% - " + ($converted_2) + "px)"
});
$('.circle2').fadeIn(300);
})
$('#error').hide();
});
body {
margin: 0 auto;
font-family: Helvetica, sans-serif;
}
.wrapper {
height: 400px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.circles {
margin-top: 50px;
position: relative;
}
.circle {
display: inline-block;
border-radius: 50%;
border-style: solid;
border-width: 2px;
border-color: blue;
background-color: rgba(0, 0, 0, 0);
z-index: -1;
left: 50%;
top: 50%;
position: absolute;
}
.circle2 {
display: inline-block;
position: absolute;
border-radius: 50%;
border-style: solid;
border-width: 2px;
border-color: red;
background-color: rgba(0, 0, 0, 0);
z-index: -1;
left: 50%;
top: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="title">
<h1>
Cutter Calculator
</h1>
</div>
<div class="Calculations">
<input type="number" id="outer_diameter" placeholder="Enter Outer Diameter"> <br>
<input type="number" id="inner_diameter" placeholder="Enter Thickness"> <br>
<input type="button" id="bttn" name="calculate" value="Calculate">
</div>
<div class="circles">
<span class="circle"></span>
<span class="circle2"></span>
</div>
<p id="error">
</p>
</div>
jsFiddle: https://jsfiddle.net/Kaevonz/6rc9jbo3/105/
The problem is that you have $('#error').hide(); outside the $('#inner_diameter').on('change', function() { so, if you change the function like this:
$('#inner_diameter').on('change', function() {
var $outer_diameter = parseFloat($("#outer_diameter").val()).toFixed(3);
var $inner_diameter = parseFloat($("#inner_diameter").val()).toFixed(3);
var $converted_2 = (($outer_diameter * 3.75) - (2 * ($inner_diameter * 3.75))).toFixed(3);
if ($outer_diameter > 85) {
$("#error")
return false;
}
if ($inner_diameter < 0) {
$('#error').text('Please input positive integers').show();
return false;
}
if ($inner_diameter >= 0.33 * $outer_diameter) {
$('#error').text('Wall Thickness invalid').show();
return false;
}
console.log($inner_diameter, $converted_2);
$('.circle2').css({
height: (2 * $converted_2),
width: (2 * $converted_2),
top: "calc(50% - " + ($converted_2) + "px)",
left: "calc(50% - " + ($converted_2) + "px)"
});
$('.circle2').fadeIn(300);
$('#error').hide();
})
works like you desire
For the second question, you don't have a onclick event binding the Calculate button...
Something like that:
$('#bttn').on('click', function() {
var $outer_diameter = parseFloat($("#outer_diameter").val()).toFixed(3);
var $inner_diameter = parseFloat($("#inner_diameter").val()).toFixed(3);
var $converted = ($outer_diameter * 3.75).toFixed(3);
var $converted_2 = (($outer_diameter * 3.75) - (2 * ($inner_diameter * 3.75))).toFixed(3);
if ($outer_diameter > 85) {
$("#error").text($outer_diameter + " is too big").show();
return false;
}
if ($outer_diameter < 0) {
$('#error').text('Please input positive integers').show();
return false;
}
console.log($outer_diameter, $converted);
$('.circle').css({
height: (2 * $converted),
width: (2 * $converted),
top: "calc(50% - " + ($converted) + "px)",
left: "calc(50% - " + ($converted) + "px)"
});
$('.circle').fadeIn(300);
$('.circles').css({
height: (2 * $converted) + 10,
width: (2 * $converted) + 10
})
console.log($inner_diameter, $converted_2);
$('.circle2').css({
height: (2 * $converted_2),
width: (2 * $converted_2),
top: "calc(50% - " + ($converted_2) + "px)",
left: "calc(50% - " + ($converted_2) + "px)"
});
$('.circle2').fadeIn(300);
$('#error').hide();
});
You can extract some methods for avoiding duplication

Target a selector to do a drag & drop

When I click I create a point in a div.
I would like to be able to move this point in a drag and drop way.
In my code I have created an orange item that I can move but I can't do it with the points I create, I can't target it.
Moreover I would like that when I move the point, once set, that the new coordinates are saved instead of the old ones and that when the point is set, it opens an url (no matter say google) but I don't know if it's possible.
$(document).ready(function() {
let count = 0;
let resultArray = [];
let addPoint = false;
let url;
$(".button").on('click', function() {
addPoint = !addPoint
});
$(".div1").click(function(ev) {
if (addPoint == true) {
$(".div1").append(
$(`<div>${count + 1}</div>`).css({
position: 'absolute',
top: ev.pageY + 'px',
left: ev.pageX + 'px',
width: '16px',
borderRadius: '12px',
background: 'blue',
color: 'white',
textAlign: 'center',
fontSize: '14px',
padding: '3px'
})
);
count = count + 1
url = "<a href='https://www.google.fr' target='blank'>url</a>"
$("#myTBody").append(
"<tr><td>" + count + "</td><td>" + ev.pageX + "</td><td>" + ev.pageY +
"</td><td>" + url + "</td></tr>"
)
let point = {
id: count,
x: ev.pageX,
y: ev.pageY,
url: url
}
resultArray.push(point);
// $("tr").on('click', function () {
// console.log($(this).children(":first").text())
// });
}
});
const el = document.querySelector(".item");
el.addEventListener('mousedown', mousedown);
function mousedown(e) {
window.addEventListener('mousemove', mousemove);
window.addEventListener('mouseup', mouseup);
let prevX = e.clientX;
let prevY = e.clientY;
function mousemove(e) {
let newX = prevX - e.clientX;
let newY = prevY - e.clientY;
const rect = el.getBoundingClientRect();
el.style.left = rect.left - newX + "px";
el.style.top = rect.top - newY + "px";
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup(e) {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
}
}
});
.button {
padding: 10px;
}
.item {
height: 40px;
width: 40px;
position: absolute;
background: orange;
}
.div1 {
width: 400px;
height: 200px;
background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="button">Add a point</button>
<div class="item"></div>
<div class="div1">
</div>
<table>
<thead id="myTHead">
<tr>
<th>PointID</th>
<th>PointX</th>
<th>PointY</th>
<th>URL</th>
</tr>
</thead>
<tbody id="myTBody">
</tbody>
</table>
This might be above and beyond what you're looking to do. Consider using the jQuery UI library so you can make use of Draggable. Consider the following example.
$(function() {
let count = 0;
let resultArray = [];
let url;
function makePoint(trg, cnt, ev) {
var p = $("<div>", {
class: "point"
}).css({
top: ev.pageY + 'px',
left: ev.pageX + 'px'
}).html(cnt).appendTo(trg);
p.draggable({
containment: "parent",
stop: function(e, ui) {
var i = parseInt($(this).text());
updatePoint(i, e);
}
});
return {
id: cnt,
x: ev.pageX,
y: ev.pageY
};
}
function updatePoint(id, ev) {
$.each(resultArray, function(k, o) {
if (id == o.id) {
o.x = ev.pageX;
o.y = ev.pageY;
$("#myTBody tr:eq(" + k + ") td:eq(1)").html(ev.pageX);
$("#myTBody tr:eq(" + k + ") td:eq(2)").html(ev.pageY);
};
});
}
$(".button").click(function() {
$("input", this).prop("checked", !$("input", this).prop("checked"));
if ($("input", this).is(":checked")) {
$(".ui-draggable").draggable("disable");
} else {
$(".ui-draggable").draggable("enable");
}
$(this).toggleClass("clicked");
});
$(".div1").click(function(e) {
if ($(".button input").is(":checked")) {
let point = makePoint($(".div1"), ++count, e);
point.url = "<a href='https://www.google.fr' target='blank'>url</a>";
resultArray.push(point);
$("#myTBody").append(
"<tr><td>" + count + "</td><td>" + point.x + "</td><td>" + point.y +
"</td><td>" + point.url + "</td></tr>"
)
}
});
$(".item").draggable({
containment: ".div1"
});
});
.button {
padding: .2em .4em;
border: 1px solid #6c6c6c;
border-radius: 3px;
background-color: #eee;
width: auto;
max-width: 100px;
cursor: pointer;
}
.button input {
display: none;
}
.item {
height: 40px;
width: 40px;
position: absolute;
background: orange;
}
.div1 {
width: 400px;
height: 200px;
background-color: grey;
}
.point {
position: absolute;
width: 16px;
border-radius: 12px;
background: blue;
color: white;
text-align: center;
font-size: 14px;
padding: 3px;
cursor: default;
}
.clicked {
background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="button"><input type="checkbox"><span class="label">Add a Point</span></div>
<div class="item"></div>
<div class="div1">
</div>
<table>
<thead id="myTHead">
<tr>
<th>PointID</th>
<th>PointX</th>
<th>PointY</th>
<th>URL</th>
</tr>
</thead>
<tbody id="myTBody">
</tbody>
</table>
You can see I made a few small changes. Using a checkbox allows for a failover in a sense. This also gives a toggled look / style so the user knows when they are able to add a point.
Using jQuery Draggable, this just makes managing the draggable elements a lot easier. The Item is draggable from the start. When Adding a Point, no dragging allowed. Once toggled off, all items can be dragged. Moving a point updates the Array and the Table.

Correct way of zooming into pseudo space with objects using an input slider

I am trying to zoom into those objects using a slider. Unfortunately, the bigger the distance from the nearest to deepest object, the faster the slide happens. How can control this behaviour so that the slide appears smooth?
What I tried: debouncing the handler and giving the circles a transition.
Here is a snippet:
const input = document.querySelector("input");
const circles = document.querySelectorAll(".circle");
let firstDepth = 9300;
let secondDepth = 100;
let thirdDepth = 2;
const initialSize = 0.0001;
circles[0].style.transform = "scale(" + (firstDepth * initialSize) + ")";
circles[1].style.transform = "scale(" + (secondDepth * initialSize) + ")";
circles[2].style.transform = "scale(" + (thirdDepth * initialSize) + ")";
input.addEventListener("input", function() {
//console.log(1)
circles[0].style.transform = "scale(" + firstDepth * input.value + ")";
circles[1].style.transform = "scale(" + secondDepth * input.value + ")";
circles[2].style.transform = "scale(" + thirdDepth * input.value + ")";
})
.circle {
width: 100px;
height: 100px;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
border-radius: 100%;
}
.first:nth-of-type(1) {
border: 2px solid red;
}
.second:nth-of-type(2) {
border: 2px solid orange;
}
.third:nth-of-type(3) {
border: 2px solid green;
}
<input type="range" value="0.0001" step="any" min="0.0001" max="1">
<div class="circle first"></div>
<div class="circle second"></div>
<div class="circle third"></div>
You would want an effect where an increase of the slide value with d would multiply the scale with some m, so that if you slide with 2d, you get a relative scaling with m2.
So, ... you need a transformation of input.value where that value appears in an exponent. In other words: the scale should increase exponentially in terms of the value of the slider.
Given that you want to see the first circle completely when the slider is at the left (scaling with initialSize) and the third circle completely when the slider is at the right, you can derive the following formula for that transformation:
initialSize * (firstDepth / thirdDepth) ** (input.value - initialSize);
Here is the code adapted to that:
const input = document.querySelector("input");
const circles = document.querySelectorAll(".circle");
let firstDepth = 9300;
let secondDepth = 100;
let thirdDepth = 2;
const initialSize = 0.0001;
circles[0].style.transform = "scale(" + (firstDepth * initialSize) + ")";
circles[1].style.transform = "scale(" + (secondDepth * initialSize) + ")";
circles[2].style.transform = "scale(" + (thirdDepth * initialSize) + ")";
input.addEventListener("input", function() {
let coeff = initialSize * (firstDepth / thirdDepth) ** (input.value - initialSize);
circles[0].style.transform = "scale(" + firstDepth * coeff + ")";
circles[1].style.transform = "scale(" + secondDepth * coeff + ")";
circles[2].style.transform = "scale(" + thirdDepth * coeff + ")";
})
.circle {
width: 100px;
height: 100px;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
border-radius: 100%;
}
.first:nth-of-type(1) {
border: 2px solid red;
}
.second:nth-of-type(2) {
border: 2px solid orange;
}
.third:nth-of-type(3) {
border: 2px solid green;
}
<input type="range" value="0.0001" step="any" min="0.0001" max="1">
<div class="circle first"></div>
<div class="circle second"></div>
<div class="circle third"></div>

Programatically resize the H div and C div along with the resizer

When I click-drag (#cssNav) to the right, it is not moving proportionately along with the #html and #css div.
This might be something very obvious, but still am not able to figure it out, what am I missing here, please help?
Note: I don't want to use display:flex
codepen
$("#htmlNav").on("mousedown", dragStartH);
$("#cssNav").on("mousedown", dragStartH);
$("#jsNav").on("mousedown", dragStartH);
function dragStartH(e) {
e.preventDefault();
dragMeta = {};
dragMeta.pageX0 = e.pageX;
dragMeta.elem = this;
dragMeta.offset0 = $(this).offset();
dragMeta.codeWindow = "#" + $(e.target).attr("id").replace("Nav", "");
function handle_dragging(e) {
var change = e.pageX - dragMeta.pageX0;
var left = dragMeta.offset0.left + change;
$(dragMeta.elem).offset({ left: left });
$("#css").width($("#css").width() - change + "px");
$("#html").width($("#html").width() + change + "px");
}
function handle_mouseup(e) {
$("body")
.off("mousemove", handle_dragging)
.off("mouseup", handle_mouseup);
}
$("body").on("mouseup", handle_mouseup).on("mousemove", handle_dragging);
}
$(document).ready(function() {
var widthPercent = ($(window).width() - 30) / 3;
$("#html").width(widthPercent + "px");
$("#css").width(widthPercent + "px");
$("#js").width(widthPercent + "px");
});
html, body {
height: 100%;
margin: 0;
}
.container{
width:100%;
height: 100%;
background-color:#343;
display: flex;
flex-direction: column;
color: #fff;
margin: 0;
}
#preview, #code{
background-color:#433;
height: 50%;
width: 100%;
margin: 0;
}
#code{
border-bottom: #333 solid 2px;
width: 100%
}
#previewNav, #codeNav{
background-color:#bbb;
height: 10px;
width: 100%;
cursor: row-resize;
}
#html{
background-color: #BFB;
}
#css{
background-color: #FBB;
}
#js{
background-color: #BBF;
}
#html, #css, #js{
float: left;
width: 32%;
height: 100%;
}
#htmlNav, #cssNav, #jsNav{
background-color:#bbb;
float: left;
height:100%;
width: 10px;
cursor: col-resize;
z-index:10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="codeNav"></div>
<div id="code">
<div id="htmlNav"></div>
<div id="html">H</div>
<div id="cssNav"></div>
<div id="css">C</div>
<div id="jsNav"></div>
<div id="js">J</div>
</div>
<div id="previewNav"></div>
<div id="preview">P</div>
</div>
This is how I would do it:
Keep track of which handle you press with navTypeand check if the user is holding its mouse down with dragging.
Then when the user moves the mouse in the document and it is holding its mouse down (dragging) it will move the #html, #css and #js accordingly
Change your javascript into this:
var mouseX, prevMouseX, navType, change;
var dragging = false;
$("#cssNav").mousedown(function () {
dragging = true;
navType = "css";
});
$("#jsNav").mousedown(function () {
dragging = true;
navType = "js";
});
$(document).mousemove(function (e) {
mouseX = e.pageX;
if(dragging){
e.preventDefault();
change = mouseX - prevMouseX;
if(navType == "css" && ($("#css").width() - (change)) > 0 && ($("#html").width() + (change)) > 0){
var hw = $("#html").width();
var cw = $("#css").width();
$("#html").width(hw + change);
$("#css").width(cw - change);
} else if(navType == "js" && ($("#css").width() + (change)) > 0 && ($("#js").width() - (change)) > 0){
var cw = $("#css").width();
var jw = $("#js").width();
$("#css").width(cw + change);
$("#js").width(jw - change);
}
}
prevMouseX = mouseX;
}).mouseup(function () {
dragging = false;
}).mouseleave(function () {
dragging = false;
});

Problems with dragging element in chrome

These are my javascript, css, and html files for simple web page for dragging an element and putting it into the container(div) :
var xContainer;
var yContainer
var insideFirst = false;
$(window).load(
function() {
xContainer = $("#center").offset().left;
yContainer = $("#center").offset().top;
console.log("ready");
$("#center").on("click", function(event) {
console.log(event);
});
$("#center").droppable();
$("#firstID").draggable({
cursor : 'move',
revert: "invalid"
});
$("#firstID").mousedown(function() {
isDragging = false;
}).mousemove(
function() {
isDragging = true;
var x = $("#firstID").offset().left;
var y = $("#firstID").offset().top;
xContainer = $("#center").offset().left;
yContainer = $("#center").offset().top;
var xPosition = (x - xContainer).toFixed(2);
var yPosition = (y - yContainer).toFixed(2);
console.log("center:" + xContainer);
console.log("x:" + x);
console.log("difference: "+(x-xContainer));
/*
* if (x < 750 && y < 750) {
* $("#firstID").css('background','#ffffff') }
*/
if (xPosition >= 0.0 && yPosition >= 0.0
&& xPosition <= 500.0 && yPosition <= 200.0) {
$("#xPosition").val("x:" + xPosition);
$("#yPosition").val("y:" + yPosition);
$("#firstID").css('background', '#e4e4e4')
$('#firstID').draggable({containment : [xContainer,yContainer,xContainer+500,yContainer+200.0] });
} else {
//$("#xPosition").val("GO IN!!!");
//$("#yPosition").val("GO IN!!!");
$("#firstID").css('background', '#d1f1fc')
}
}).mouseup(function() {
var wasDragging = isDragging;
isDragging = false;
if (!wasDragging) {
console.log("clicked");
}
});
$("#secondID").draggable({
cursor : 'move'
});
$("#secondID").mousedown(function() {
isDragging = false;
}).mousemove(function() {
isDragging = true;
var x = $("#secondID").offset().left;
var y = $("#secondID").offset().top;
// $("#text-x").val ("x:"+x);
// $("#text-y").val ("y:"+y);
}).mouseup(function() {
var wasDragging = isDragging;
isDragging = false;
if (!wasDragging) {
console.log("clicked");
}
});
$("#secondID").dblclick(function() {
rotation += 90;
$(this).rotate(rotation);
});
});
jQuery.fn.rotate = function(degrees) {
$(this).css({
'-webkit-transform' : 'rotate(' + degrees + 'deg)',
'-moz-transform' : 'rotate(' + degrees + 'deg)',
'-ms-transform' : 'rotate(' + degrees + 'deg)',
'transform' : 'rotate(' + degrees + 'deg)'
});
return $(this);
};
var rotation = 0;
var isDragging = false;
body {
height: 100%;
background-color: #e4e4e4;
}
#firstID {
width: 100px;
height: 100px;
margin: 0 auto;
border-style: groove;
background-color: #d1f1fc;
color: black;
position: relative;
text-align: center;
z-index: 99;
}
#secondID {
width: 100px;
height: 50px;
margin: 0 auto;
color: black;
border-style: groove;
position: relative;
background-color: #d1f1fc;
text-align: center;
z-index: 99;
}
#center {
width: 600px;
height: 300px;
position: relative;
margin: 0 auto;
border-style: groove;
background-color: #c0c0c0;
}
/* If in mobile screen with maximum width 479px. The iPhone screen resolution is 320x480 px (except iPhone4, 640x960) */
#media only screen and (max-width: 479px) {
#center{
width: 50%;
height : 50%;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<html>
<head>
<link rel="stylesheet" type="text/css" href="drag.css">
</head>
<body>
<input type="text" id="xPosition" value="x:0">
<input type="text" id="yPosition" value="y:0">
<div id="firstID" >MJ</div>
<div id="secondID" >MJ</div>
<div id="center">
</div>
</body>
</html>
The code is not finished, so the logic works with only a square, not rectangle.
What i need is to drag square element into the container on the page and make it stay inside it, with no possibility to leave it. That works fine in Mozilla, but in Chrome, i have problems with dragging the square after entering container. When i click on it and try to drag it, it moves far to the right side of the page. Why is that happening only in Chrome?

Categories