Showing posts with label html5-draggable. Show all posts
Showing posts with label html5-draggable. Show all posts

Sunday, July 29, 2018

JS HTML5 Drag and Drop: Custom Dock Effect Jumping Around in Chrome

Leave a Comment

Situation: I'm using HTML5 drag-and-drop to place tiles in a game I'm writing. I'd like to add an effect where the two tiles that I'm about to drop a new tile between move slightly apart to indicate that this is where you're dropping (similar to the Mac OS dock).

My Approach: I have a flexbox into which I'm dropping these tiles. I wrote a function that essentially returns one period of a sine wave and I'm using it to update the dropped tiles' right: and top: CSS properties (the tiles are position: relative;) based on their original position relative to the mouse during drag.

  // Update occupant style for desired effect   occupants.forEach(function(occupant, index) {     $(occupant).css({'right' : -10 * nudgeSine(occupantsMouseOffset[index] * 10) + 'px',                      'top' : -10 * Math.abs(nudgeSine(occupantsMouseOffset[index] * 10)) + 'px',                      'opacity' : 1 - Math.abs(nudgeSine(occupantsMouseOffset[index])) });   });    // Function to return 1 period of a sine wave   function nudgeSine(x) {     if (x < -3.14159 || x > 3.14159) {       return 0;     } else {       return Math.sin(x);     }   } 

Problem: In Chrome (but not in Firefox), at some mouse positions, which I can't find a pattern in, the tile is jumping back-and-forth. See the .gif below:

In Chrome (left) and in Firefox (right):

demo in Chrome demo in Firefox

I even console.logged the element's calculated right: property, and while it is shown jumping around on screen, it outputs as a constant value.

What I've Tried/Thought About:

  • Even with the mouse stationary and console.log(event.clientX) outputting a constant value, the tile will jump around.
  • I thought event.clientX might be changing imperceptibly, so I'm basing my calculations on Math.trunc(event.clientX) to no avail.
  • I am using element.getBoundingClientRect() in my calculations, which I'm not very familiar with, and I think it may be the root cause of my problem.

I made this CodePen, but wasn't able to completely replicate the issue. Still, I think someone may be able to spot what's happening.

Edit: I've put this up on a github page to fully replicate. This link may not work for future readers of the question, but I'll keep it up for the foreseeable future. To demonstrate the issue, view in Chrome and Firefox.

Thank you.

1 Answers

Answers 1

Perhaps I can expand my answer later, but for now:

Related questions: How to keep child elements from interfering with HTML5 dragover and drop events? 'dragleave' of parent element fires when dragging over children elements

This is what happens: - you start dragging the operator - operator moves over the box, existing operators move along nicely - you move the operator over one of the existing operators - at this point the browser enters a kind of infinite loop thingy, because each time the elements move the position of the elements have to be updated again (because new events are triggered)

Since you need the click event on the existing operators you can't just set them to pointer-events: none; like in the related question, but you can add a class when you start dragging and apply this style to the operators while you're dragging.

Another solution would be to use a library, in the comments of an answer I found the library https://bensmithett.github.io/dragster/, I use draggable by shopify.

update

I wasn't able to find the exact term of this behavior, perhaps we could go with "cyclic case" or "undefined behaviour". See my examples:

:root {    /*colors by clrs.cc*/    --navy: #001f3f;    --blue: #0074D9;    --red: #FF4136;    font-family: sans-serif;  }    .animated {    transition: all .5s;  }    h2 {    color: var(--red);  }    div {    height: 160px;    width: 160px;    padding: 20px;    background: var(--blue);    margin-bottom: 20px;  }    .box1 {    border-right: 20px solid var(--navy);  }    .box1:hover {    border-right: 0px solid var(--navy);  }    .box2:hover {    border-radius: 100px;  }
<div class="box1 animated">hover your mouse over my border on the right →</div>  <div class="box2 animated">hover your mouse over an edge of this box</div>  <h2>Warning, the following boxes have no animations, flashes are expected:</h2>  <div class="box1">hover your mouse over my border on the right →</div>  <div class="box2">hover your mouse over an edge of this box</div>

When the user moves the mouse onto the border the following happens in a loop:

  1. box1 is being hovered
  2. hover styles apply, the border is removed
  3. box1 isn't being hovered
  4. hover styles stop applying, the border is readded

basically for the moment the CSS doesn't really evaluate, because as soon as it evaluates the evaluation is invalid. This is exactly what happens in your example. I don't know whether the CSS standard has rules that define how browsers should handle this. If the expected behavior is defined, either FF or Chrome is wrong and you can file a bug after you find out which browser's behavior is wrong. If no expected behavior is defined and the implementation is left open to browsers then both browsers are right.

Read More

Friday, April 22, 2016

javascript drag and drop page builder

Leave a Comment

I'm in the process of building an A4 size drag and drop page builder. The elements this builder can contain are images and text boxes.

I am after for some advice on what frameworks are available that can be used to build this type of front-end functionality.

Example of what I'm after, see here canva.com

The two frameworks I tried are so far are fabric js and greensock draggable, which didn’t meet my needs or are pretty difficult to create a complete page builder.

ideally i don't want to use canvas for this.

edit: Basic Feature:

  • cropping
  • rotation
  • re-sizing
  • change font style/color/size for textboxes
  • add backgrounds
  • frames/ masking images (square image can become star shape with a overlay)

3 Answers

Answers 1

As of my understanding you want to create dashboard which can be configurable. I would suggest use a table structure Table merge and split in which each cell should have a dropable component like

<table id="mainTable">                     <tbody>                         <tr>                             <td class="set-as-droppable"></td>                             <td class="set-as-droppable"></td>                             <td class="set-as-droppable"></td>                             <td class="set-as-droppable"></td>                         </tr>                         <tr>                             <td class="set-as-droppable"></td>                             <td class="set-as-droppable"></td>                             <td class="set-as-droppable"></td>                             <td class="set-as-droppable"></td>                         </tr>                     </tbody>                 </table> 

Like

Then on drop write your own logic

$( ".set-as-droppable" ).droppable({         accept: "div.Dragable",         drop: function( event, ui ) {  } });  

And dragable component can be TEXT or IMAGE and on drop you can give any operation

Answers 2

There is a useful jquery plugin for rotation.. Your code:

<div id="product">  <img src="images/01.jpg" />  <img src="images/02.jpg" />  <img src="images/03.jpg" />  <img src="images/04.jpg" />  <img src="images/05.jpg" />  </div> <script type="text/javascript">  jQuery(document).ready(function() {      jQuery('#product').j360();  });  </script> 

This should work.

Answers 3

Well, most of your goals can be achieved by css 2/3 + some pure js

clipping/masking

http://www.html5rocks.com/en/tutorials/masking/adobe/

re-sizing, change font style/color/size for textboxes, add backgrounds

pure js/css2

rotation

css3 transform property http://www.w3schools.com/cssref/css3_pr_transform.asp

dragging

Can be pretty easily done, using pure js or you can try some open-source plugins, or something like jquery draggable.

As for your current list, I don't actually see, why do you want some framework for this, when most of it can be achieved by pure js/css with a little effort/googling.

In my humble opininon, jquery or something similar is all you really need. Just check jquery's "interactions" section here https://jqueryui.com/draggable/ to see if it can help you with building your builder interface. There are various examples for each interaction (right sidebar).

UPD: Here is some dirty code example for you (using jquery UI) http://jsfiddle.net/tbpxnxrm/2/. Doubleclick in #main to create additional elements. No collision/overlapping checks implemented, forked from http://jsfiddle.net/4Vfm5/1095/

drag_defaults = {grid: [50,50], containment: "parent"}; resize_defaults = {     aspectRatio: true,     handles: 'ne, se, sw, nw',     grid: [50,50],     minHeight: 50,     minWidth: 50 }  $('.draggable').draggable(drag_defaults); $('.resizable').resizable(resize_defaults); 
Read More