p5js drag'n'drop hover not working - why?

Hi, I've been following one of Daniel Shiffman's excellent tutorials on p5js, and I can't figure out why my simple code isn't working.

i'm dragging and dropping a file into the browser. I have a simple paragraph assigned with an id of 'dropzone'. It has a dragOver() which calls a highlight() function to change its background colour.

This works fine until I add the drop() method to the dropzone - it stops highlighting on dragOver. If I comment out the drop() line, the highlight works.

I'm sure it's a simple problem, but I've spent literally hours trying to work it out - please help me before I give up computing altogether!

<!DOCTYPE html>
<html lang="en">
<head>
  <title>p5 starter</title>
  <script src='js/libs/p5.min.js'></script>
  <script src='js/libs/p5.dom.js'></script>
  <style>
    #dropzone {
      background-color: lightblue;
      height: 200px;
    }
  </style>
</head>
<body>

<p id='dropzone'>Drag your data file here</p>

<script>
  var dropzone

  function setup() {
    dropzone = select('#dropzone')
    dropzone.dragOver(highlight)
    dropzone.drop(gotFile)     // comment this line out, and highlight works
  }

  function highlight() {
    dropzone.style('background-color','red')
  }

  function gotFile(file) {
    console.log(file.type)
  }

</script>
</body>
</html>

Answers

  • edited March 2018 Answer ✓

    p5.Element::drop() overrides p5.Element::dragOver(): :-O
    https://GitHub.com/processing/p5.js/blob/master/src/core/p5.Element.js#L970-L977

    Maybe invoking p5.Element::dragOver() after p5.Element::drop() can workaround the issue: :ar!

    dropzone = select('#dropzone').drop(gotFile).dragOver(highlight)

  • thanks for your help GoToLoop - you seem to be a hero on this forum

    unfortunately the suggested workaround does now highlight() on dragOver(), but also breaks drop() :(|)

    there must be some simple way to achieve this highlight before dropping. i don't know what it is though, so i'll guess i'll have to lose this particular bit of interactive user-feedback.

    thanks again

  • edited October 2017

    There must be some simple way to achieve this highlight before dropping.

    Well, if you read the comment about the reason they had to override dragOver() for drop() to work:

    https://GitHub.com/processing/p5.js/blob/4e3a21c9b8e376d7e451e8e715f6ed9e6f0e87bd/src/core/p5.Element.js#L950-L951

    // If you want to be able to drop you've got to turn off
    // a lot of default behavior

    You can notice that overridden dragOver() function invokes Event::preventDefault():

    https://Developer.Mozilla.org/en-US/docs/Web/API/Event/preventDefault

    https://GitHub.com/processing/p5.js/blob/4e3a21c9b8e376d7e451e8e715f6ed9e6f0e87bd/src/core/p5.Element.js#L972

    evt.preventDefault();

    So why don't we do the same for our own dragOver()'s callback function? :>

    I've got a very old online example using drop() as well.
    And I've modified it a little to include dragOver() & dragLeave() now: :-bd

    http://p5js.SketchPad.cc/sp/pad/view/ro.CYTkHWj9smgw8Q/latest

    "index.html":

    <script defer src=http://CDN.JSDelivr.net/npm/p5></script>
    <script defer src=http://CDN.JSDelivr.net/npm/p5/lib/addons/p5.dom.min.js></script>
    <script defer src=sketch.js></script>
    

    "sketch.js":

    /**
     * Image Drop (v3.0.1)
     * GoToLoop (2017-Oct-26) (2015-Nov-25)
     *
     * Forum.Processing.org/two/discussion/24750/
     * p5js-drag-n-drop-hover-not-working-why#Item_3
     *
     * Forum.Processing.org/two/discussion/13650/
     * dropped-image-not-showing-in-the-draw-loop-gotfile-createimg-image#Item_4
     *
     * p5js.SketchPad.cc/sp/pad/view/ro.CYTkHWj9smgw8Q/latest
     */
    
    "use strict";
    
    let img, bg, hover;
    
    function setup() {
      createCanvas(800, 600).drop(gotFile).dragOver(highlight).dragLeave(redraw);
    
      textAlign(CENTER).textSize(32).textStyle(BOLD).noLoop();
      colorMode(RGB).imageMode(CORNER);
      fill('yellow').noStroke();
    
      bg = color(0o200);
      hover = color('red');
    }
    
    function draw() {
      background(bg);
    
      if (img)  image(img, 0, 0, width, height);
      else      text('Drag an image file onto the canvas.', width>>1, height>>1);
    }
    
    function gotFile(f) {
      if (f.type === 'image')  img = loadImage(f.data, redraw);
      else                     print(`"${f.name}" isn't an image file!`);
    }
    
    function highlight(evt) {
      this.background(hover);
      evt.preventDefault();
    }
    
  • it's true - you really are a hero! =D>

    i can't believe i wasted so many hours on this

    thank you, thank you, thank you

Sign In or Register to comment.