HTML5 Drag and Drop with Coordinates - javascript

i'm new in Javascript and i got a task which i can't even solve..
I have to get a HTML 5 Drag and Drop, which can add Elements as much as i want, and if i want to edit one of the new elements or change the Position it has to be easy.
This is what it look like now:
http://picul.de/view/HRO
at the moment this don't work as i need..
who can help me?
var dragok = false;
var pos;
function allowDrop(e)
{
e.preventDefault();
}
function get_pos(e)
{
pos = [e.pageX , e.pageY];
}
function drag(e)
{
e.dataTransfer.setData("Text",e.target.id);
}
function drop(e)
{
e.preventDefault();
var canvas = document.getElementById("graphCanvas");
var ctx = canvas.getContext("2d");
var offset = e.dataTransfer.getData("text/plain").split(',');
var data=e.dataTransfer.getData("Text");
var img = canvas = document.getElementById(data);
var dx = pos[0] - img.offsetLeft;
var dy = pos[1] - img.offsetTop;
ctx.drawImage(document.getElementById(data), e.pageX - dx-170, e.pageY - dy-100);
}
function getCoordinates(e)
{
var canvas = document.getElementById("graphCanvas");
var ctx = canvas.getContext("2d");
x=ctx.clientX;
y=ctx.clientY;
document.getElementById("footerCoord").innerHTML="Coordinates: (" + x + "," + y + ")";
}
body {
background:#eee;
}
#DnDBox {
margin:0 auto;
margin-top:7vh;
width:80vw;
height:80vh;
padding:1vmax;
background:#f5f5f5;
/* Erstmal nur zur Übersicht */
border:1px solid #111;
}
#DnDBox #canvasBox {
border:1px solid #111;
}
#DnDBox .leftBox {
float:right;
width:25%;
height: 90%;
}
#DnDBox .leftBox select{
width:100%;
padding:5px;
margin-bottom:5px;
}
#DnDBox .leftBox .dragBox{
float:right;
width:100%;
height: 90%;
/* Erstmal nur zur Übersicht */
border:1px solid #111;
}
#DnDBox .leftBox .dragBox ul{
list-style-type: none;
margin: 0;
padding: 0;
}
#DnDBox .leftBox .dragBox ul > li{
float:left;
padding:20px;
text-align:center;
background:#eee;
}
#DnDBox .leftBox .dragBox ul > li:hover{
padding:20px;
text-align:center;
background:#ddd;
}
#DnDBox .leftBox img{
cursor:move;
}
#DnDBox .leftBox img:active{
cursor:move;
}
#DnDBox footer {
float:left;
margin-top:5px;
padding:5px;
width:100%;
border:1px solid #111;
}
<div id="DnDBox">
<canvas id="graphCanvas" onmousemove="getCoordinates(event)" ondrop="drop(event)" ondragover="allowDrop(event)" height=400 width=700 style="border:1px solid #000000;"></canvas>
<div class="leftBox">
<select name="plh1">
<option>Test</option>
<option>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>
<select name="plh2"></select>
<div class="dragBox">
<ul>
<li><img id="img1" src="https://cdn3.iconfinder.com/data/icons/free-social-icons/67/facebook_circle_color-128.png" draggable="true" onmousedown="get_pos(event)" ondragstart="drag(event)"/></li>
<li><img id="img2" src="https://cdn3.iconfinder.com/data/icons/free-social-icons/67/twitter_circle_color-128.png" draggable="true" onmousedown="get_pos(event)" ondragstart="drag(event)"/></li>
<li><img id="img3" src="https://cdn3.iconfinder.com/data/icons/free-social-icons/67/linkedin_circle_color-128.png" draggable="true" onmousedown="get_pos(event)" ondragstart="drag(event)"/></li>
</ul>
</div>
</div>
<footer id="footerCoord">asd</footer>
</div>
greets,
daniel

You can't drag an image painted onto a canvas around without additional support - the painted image is just a set of pixels that are part of the canvas's image data.
You may be interested in a canvas library called Fabric.js (tag and homepage). I'm not "recommending" it as such - I haven't used it - but you can certainly drag canvas objects created by the library on the homepage.
A simpler solution might be to use JavaScript/HTML without the canvas. Replace the canvas with, say, a relative DIV element (so it can act as a container for absolutely positioned elements). Then dropping an image on the DIV creates a new Image object (say a clone of the image dragged) and absolutely positions it within the container according to where it was dropped. The new copy of the image can have it's own drag handlers to move it around the container and program options could be added to delete a (cloned) dropped image as necessary.
You could also calculate the position of the mouse relative to the image element when starting a drag operation. This would allow dropping it under the mouse in the same relative position to the mouse cursor as at the start of the drag operation. This question on retrieving the X Y position of an element may be of help. (At the moment the dropped image does not appear under the cursor.)

You need to keep track of the elements. The canvas is just a bitmap image with no understanding of what a circle or square is.
Ideas:
(1) Create a separate canvas with a transparent background for each shape that you make and overlay them. When clicking on or touching a point of the canvas repeatedly, cycle through the potential target elements below that event, highlighting them in some way. When the correct element is selected, define an event (a gesture) that will allow the user to select that target for editing. Stop the selection function and initiate the editing function.
(2) Forget the canvas thing, and do it all with SVG

Related

Positioning of element with JS transform properties (CSS get's overwritten by JS)

I'm trying to position two images on top of eachother, and having one of them rotate on scroll while the other one is not rotating - which works, except i'm unable to position and scale my elements in my CSS. As soon as i start scrolling, the image with the JS jumps into the corner while the other one remains where it is. I believe it's because my JS overwrites my CSS properties, but is there any way of working around this? Can i position my two elements while maintaining my JS?
var elem = document.getElementById("rotatelogo");
window.addEventListener('scroll', function() {
var value = window.scrollY * 0.25;
elem.style.transform = `translatex(-50%) translatey(-50%) rotate(${value}deg)`;
});
body {
height: 200vh;
background: darkblue;
}
.guide {
width:150px;
height:150px;
margin-top:50px;
margin-bottom:-300px;
margin-left:50px;
}
<div class="guide" style="position:relative">
<img src="http://jakobnatorp.com/wp-content/uploads/2021/10/ARROW.png" style="position:fixed;"/>
<img class="portfolio" id="rotatelogo" src="http://jakobnatorp.com/wp-content/uploads/2021/10/SELECTED-WORK-BEIGE.png" style="position:fixed"/>
</div>
Remove translate from your code.
var elem = document.getElementById("rotatelogo");
window.addEventListener('scroll', function() {
var value = window.scrollY * 0.25;
elem.style.transform = `rotate(${value}deg)`;
});
body {
height: 200vh;
background: darkblue;
}
.guide {
width:150px;
height:150px;
margin-top:50px;
margin-bottom:-300px;
margin-left:50px;
}
<div class="guide" style="position:relative">
<img src="http://jakobnatorp.com/wp-content/uploads/2021/10/ARROW.png" style="position:fixed;"/>
<img class="portfolio" id="rotatelogo" src="http://jakobnatorp.com/wp-content/uploads/2021/10/SELECTED-WORK-BEIGE.png" style="position:fixed"/>
</div>
I am not sure what you want to achieve by usingtranslatex(-50%) translatey(-50%), but this is causing the images center to be positioned on the top left corner of the parent element.
If you just use elem.style.transform = `rotate(${value}deg)`; it will rotate in place.

smooth horizontal scroll like k2.pl

I am trying to build a website with a horizontal scroll like this website k2.pl
Desc
i have made this code so far jquery animate and scroll to
// i am getting y and x axis and moving the whole page agains it
$('.scroll').animate( { scrollLeft: '+='+newScroll }
but what i made is that my script gets page X axis of website and move againts it but what i want is that when i hover on an element on the site it should scroll to the center like on this site k2.pl
can you guys suggest me some jquery plugin or that tell me how can improve it
If you check the website and move the mouse, you'll see that the element that you hover on doesn't really go to the center, the movement of the scroll is associated to the horizontal movement of the mouse and has nothing to do with hovering over the different list elements.
The idea is simple:
Have a container that occupies the whole width of the window and that has a overflow:hidden.
Inside that container have a second container with the same width as the list of elements.
Inside that container have a list of elements (or a series of inline elements) that occupy more than the width of the window.
When the mouse moves over the container, calculate the position of the mouse within the window, and scroll the container horizontally accordingly.
A basic version of it would be like this:
$(document).ready(function() {
$(".scroll").on("mousemove", function(e) {
var ww = $(window).width(); // window width
var uw = $(".scroll ul").width(); // ul width
var mp = e.clientX; // mouse position
var ms = uw - ww; // max scroll
var sc = - ms * mp / ww; // amount to be scrolled
$(".scroll > div").stop().animate({ left: sc +"px" }, 600, "easeOutCirc");
});
});
html, body {
margin:0;
padding:0;
border:0;
}
div.scroll {
width:100%;
height:400px;
overflow:hidden;
background:#f0f0f0;
position:relative;
}
div.scroll > div {
width:1400px;
position:absolute;
top:0;
left:0;
}
div.scroll > div > ul {
width:1400px;
margin:0;
padding:0;
}
div.scroll > div > ul > li {
display:inline-block;
float:left;
width:200px;
height:400px;
opacity:0.7;
transition:all 0.5s;
}
div.scroll > div > ul > li:hover {
opacity:1;
background:#6699cc;
}
div.scroll > div > ul > li:hover > span {
color:white;
background:black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<div class="scroll">
<div>
<ul>
<li><span>AAA</span></li>
<li><span>BBB</span></li>
<li><span>CCC</span></li>
<li><span>DDD</span></li>
<li><span>EEE</span></li>
<li><span>FFF</span></li>
<li><span>GGG</span></li>
</ul>
</div>
</div>
(Note: the code above may not work if the width of the window is larger than 1400px)
If you check the source code for k2.pl you'll see that they are using jQuery, jQuery UI, and Ariel Flesler's scrollTo plugin. You can see the code that controls the scrolling (in a different way to what I explained above) in the script.min.js file (search for mousemove.sapp).
As promised, here's my working solution. Alvaro's is great, but it uses the jQuery animate function which is a big no-no (it's about 10x slower than CSS transitions / the GSAP JavaScript animation library, for example), so I thought you might benefit from another implementation.
I personally like GSAP, which is super easy to pick up; that's why I've used it here. The rest is in native JS so you don't need all that library bloat:
var wrapper = document.getElementById("wrapper");
var tiles = document.getElementsByClassName("tile");
var tileWidth = tiles[0].getBoundingClientRect().width;
var containingWidth = tileWidth * tiles.length;
wrapper.addEventListener("mousemove", function(e){
var pos = (e.clientX / (wrapper.getBoundingClientRect().width)) * containingWidth - (tileWidth / 1.5);
TweenLite.to(wrapper, 1, { scrollLeft: pos, ease: Circ.easeOut })
});
html, body {
height: 100%;
overflow: hidden;
white-space: nowrap;
}
#wrapper {
height: 100%;
overflow-y: hidden;
overflow-x: auto;
}
.tile {
display: inline-block;
height: 100%;
width: 400px;
transition: background 0.2s ease-in-out;
}
.tile:hover {
background: transparent !important;
}
<div id="wrapper">
<div style="background: #6d8745" class="tile"></div>
<div style="background: #aa715a" class="tile"></div>
<div style="background: #a25fe3" class="tile"></div>
<div style="background: #8e84f5" class="tile"></div>
<div style="background: #259a5c" class="tile"></div>
<div style="background: #d5b67a" class="tile"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>
The principles are essentially the same as Alvaro's. What you have to understand is that the width of the viewport will be a certain percentage of the width of the div / element which contains all of the "tiles" so, taking this into consideration, you have to calculate how to make them map at a 1:1 ratio. That calculation is represented by this line of code (the subtraction at the end is an offset):
var pos = (e.clientX / (wrapper.getBoundingClientRect().width)) * containingWidth - (tileWidth / 1.5);
Hope this helps!
Original codepen

Postion wont be editable by javascript if it is inherited

When the position of my div called player is styled to position:absolute; I can move its position with JavaScript but if it's inherited or fixed so its position is fixed to the parent div I cannot control it with JavaScript anymore.
html of the divs that.
<div id="game">
<div id="player"></div>
<div id="scores"><h1 id="playersScore"> 0</h1><h1 id="pcScore"> 0</h1></div>
</div>
javascript that updates the top position of the div
function readMouseMove(e){
if(e.clientY < 500){
var player = document.getElementById('player');
player.style.top = e.clientY + "px";
}
document.onmousemove = readMouseMove;
the css of the player is
#player{
border:1px solid black;
position:absolute;
left:50px;
top:50px;
background-color:#00FF00;
width:8px;
height:50px;
}
the parent div css is
#game{
margin:150px auto;
border:3px solid black;
background-color:black;
width:1000px;
height:500px;
}
Now this player div is been controlled by the javascript but if I change the position to positon:inherit I cannnot control the div with javascript anymore. I need to have the player divs positon to relate to its parent div.

why changing source of image , execute my inline javascript

Hi guys i just created a webpage , that use pagemethods
like this
function get_frame() {
//send a request to change image named "1.jpeg" in path of "src/frames/1.jpeg"
PageMethods.GrabFrame(imgw, imgh, t, f);
}
function t() {
//refresh image source to new image and set timer
document.getElementById('dImg').src = "src/frames/1.jpeg?" +
new Date().getTime();
setTimeout(function () { get_desktop(); }, Main.IMGrefresh.value);
}
function f() {
//do nothing
var x = 0;
}
And also used an inline javascript with jquery like this
<script>
$("#cover").mousemove(function (e) {
var parentOffset = $(this).parent().offset();
var relX = e.pageX - parentOffset.left;
var relY = e.pageY - parentOffset.top;
move_mouse(relX, relY);
});
</script>
And some asp.net clientside code like this
<div id="dDiv">
<img id="dImg" alt="" src="" />
<div id="cover">
</div>
</div>
That the inline javascript is at the end of that html code
So move_mouse() method must run only when user move his mouse, it moves correctly but it moves even when mouse didn't have movement when image refreshes, i mean when image refreshed by javascript, it runs move_mouse method, too.
Css for these elements
#cover {
position:absolute;
top:0px;
left:0px;
text-align:center;
background-color:Black;
height:200px;
width:300px;
border:0px none black;
margin:0px auto 0px auto;
filter: alpha(opacity=1);
-moz-opacity: 0.01;
-khtml-opacity: 0.01;
opacity: 0.01;
}
#dDiv {
position:relative;
text-align:center;
background-color:Black;
height:200px;
width:300px;
border:0px none black;
margin:0px auto 0px auto;
}
#dImg {
background-color:Black;
height:200px;
width:300px;
border:0px none black;
margin:0px 0px 0px 0px;
}
And also they are changing in javascript
function resize() {
imgh = Main.IMGheight.value;
imgw = Main.IMGwidth.value;
$("#dDiv").css("height", imgh);
$("#dDiv").css("width", imgw);
$("#dImg").css("height", imgh);
$("#dImg").css("width", imgw);
$("#cover").css("height", imgh);
$("#cover").css("width", imgw);
}
Ahh i just found it myself AGAIN , just move the mouse event to js function and put it in body onload , because inline javascript methods are saved in catch and this command => "new Date().getTime();" make it to refresh and get the new method , so this triggers the event .

It won't hover or let me click on images in my gallery

Since I've added this cropping effect (http://jsfiddle.net/BPEhD/2/) to the images in my gallery, there is no hover state on the images and it won't let click on them either. The pointer cursor appears when I hover over them, but it won't bring up the panel when I click on it. How can I solve this?
HTML:
<div id="thumbsWrapper">
<div id="content">
<p class="crop">
<img src="image1.jpg" alt="image1.jpg"/></p>
<p class="crop">
<img src="image2.jpg" alt="image2.jpg"/></p>
<p class="crop">
<img src="image1.jpg" alt="image1.jpg"/></p>
<div class="placeholder"></div>
</div>
</div>
<div id="panel">
<div id="wrapper">
<a id="prev"></a>
<a id="next"></a>
</div>
</div>
CSS:
#thumbsWrapper{
position:relative;
height:100%;
width:100%;
left:0px;
right:0px;
}
#content{
position:relative;
height:100%;
width:100%;
left:0px;
display:none;
}
.crop{
float:left;
margin:.5em 10px .5em 0;
overflow:hidden; /* this is important */
position:relative; /* this is important too */
border:1px solid #ccc;
width:200px;
height:200px;
}
.crop img{
position:absolute;
top:-50px;
left:-50px;
}
#content img{
float:left;
margin:5px 0px 5px 5px;
cursor:pointer;
opacity:0.4;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=40);
}
#panel{
background-color:#ddd;
width:100%;
position:fixed;
bottom:0px;
left:0px;
right:0px;
height:0px;
text-align:center;
z-index:999;
}
#panel img{
cursor:pointer;
position:relative;
border:1px solid #000;
-moz-box-shadow:0px 0px 10px #111;
-webkit-box-shadow:0px 0px 10px #111;
box-shadow:0px 0px 10px #111;
display:none;
}
Relevant JS:
$(function() {
/* this is the index of the last clicked picture */
var current = -1;
/* number of pictures */
var totalpictures = $('#content img').size();
/* speed to animate the panel and the thumbs wrapper */
var speed = 500;
/* show the content */
$('#content').show();
/*
when the user resizes the browser window,
the size of the picture being viewed is recalculated;
*/
$(window).bind('resize', function() {
var $picture = $('#wrapper').find('img');
resize($picture);
});
/*
when hovering a thumb, animate it's opacity
for a cool effect;
when clicking on it, we load the corresponding large image;
the source of the large image is stored as
the "alt" attribute of the thumb image
*/
$('#content > img').hover(function () {
var $this = $(this);
$this.stop().animate({'opacity':'1.0'},200);
},function () {
var $this = $(this);
$this.stop().animate({'opacity':'0.4'},200);
}).bind('click',function(){
var $this = $(this);
/* shows the loading icon */
$('#loading').show();
$('<img alt="">').load(function(){
$('#loading').hide();
if($('#wrapper').find('img').length) return;
current = $this.index();
var $theImage = $(this);
/*
After it's loaded we hide the loading icon
and resize the image, given the window size;
then we append the image to the wrapper
*/
resize($theImage);
$('#wrapper').append($theImage);
/* make its opacity animate */
$theImage.fadeIn(800);
/* and finally slide up the panel */
$('#panel').animate({'height':'100%'},speed,function(){
/*
I think the problem is with the selector you're using to match your image tags. You're using the child selector which only selects direct children of the selected element (see documentation). Since (I'm guessing) you've added p tags around your images to apply the cropping effect, the selector is no longer returning the images.
Try updating your code as follows:
$('#content img').hover(function () {
var $this = $(this);
$this.stop().animate({'opacity':'1.0'},200);
}
Note that this will select all elements that are descendants of the content div (see documentation) so, depending on what you're doing, you may want to consider a more specific selector.
Just a friendly hint, but a fully functioning fiddle demonstrating the issue would make it easier to help.

Categories