Skip to content

Strange Segment-behavior with two tracks #35

Open

Description

@justinlevi

Unfortunately, I'm noticing some strange issues with the SegmentBehavior code when I have two tracks. Please see the attached animated gif for details.

Problem:
The dragged segment does not stay under the mouse.

What I expect:
the dragged segment to stay under the mouse.

Is this because the time context being used is related to the wrong track?

Although I am using a custom behavior, I can duplicate the issue using the default segment-behavior.js


segmentissue

Activity

  1. justinlevi commented on Nov 13, 2017

    @justinlevi
    Author

    Here's my code for reference:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" />
      <title>Segment Layer</title>
    
      <link rel="stylesheet" type="text/css" href="//wavesjs.github.io/waves-ui/examples/assets/common.css" />
      <link rel="stylesheet" type="text/css" href="//wavesjs.github.io/waves-ui/examples/assets/prism.css" />
    
      <script src="//wavesjs.github.io/waves-ui/waves-ui.umd.js"></script>
      <script src="//wavesjs.github.io/waves-ui/examples/assets/prism.js"></script>
      <script src="//wavesjs.github.io/waves-ui/examples/assets/insert-code.js"></script>
      <script src="//wavesjs.github.io/waves-ui/examples/assets/waves-loaders.min.js"></script>
    
    </head>
    <body>
    
      <!-- ADVANCED USAGE -->
      <h2 id="advanced-use">Advanced Usage</h2>
    
      <div class="track" id="track"></div>
      <script class="example" rel="track">
      (function() {
        var $track = document.querySelector('#track');
        var width = $track.getBoundingClientRect().width;
        var height = 200;
        var duration = 20;
    
        var data = [
          { start: 0, duration: 2, color: 'steelblue' },
          { start: 3, duration: 2, color: 'orange' },
          { start: 5.5, duration: 2, color: 'green' },
        ];
    
        var loader = new wavesLoaders.AudioBufferLoader();
        loader.load('./dream.wav').then(function(buffer) {
    
          var pixelsPerSecond = width / buffer.duration;
          var timeline = new wavesUI.core.Timeline(pixelsPerSecond, width);
    
          var track = new wavesUI.core.Track($track, height);
    
          var segmentLayer = new wavesUI.core.Layer('collection', data, {
            height: height
          });
    
          var timeContext = new wavesUI.core.LayerTimeContext(timeline.timeContext);
    
          segmentLayer.setTimeContext(timeContext);
          segmentLayer.configureShape(wavesUI.shapes.Segment, {
            x: function(d, v) {
              if (v !== undefined) { d.start = v; }
              return d.start;
            },
            width: function(d, v) {
              if (v !== undefined) { d.duration = v; }
              return d.duration;
            }
          });
    
          var cb = new wavesUI.behaviors.SegmentBehavior();
          segmentLayer.setBehavior(cb);
    
          track.add(segmentLayer);
          timeline.add(track);
    
          /* ---------------------------------------------------- */
    
          // create the waveform track
          timeline.createTrack($track, height, 'main');
    
          // create the waveform layer
          var waveformLayer = new wavesUI.helpers.WaveformLayer(buffer, {
            height: height
          });
    
          // insert the layer inside the 'main' track
          timeline.addLayer(waveformLayer, 'main');
    
          let zoomState = new wavesUI.states.CenteredZoomState(timeline);
          let simpleEditionState = new wavesUI.states.SimpleEditionState(timeline);
    
          timeline.on('event', e => {
            const target = e.target;
            if (segmentLayer.hasElement(target)) {
              timeline.state = simpleEditionState;
            } else if (waveformLayer.hasElement(target)) {
              timeline.state = zoomState;
            }
          });
    
          timeline.tracks.render();
          timeline.tracks.update();
    
        }).catch(function(err) {
          console.error(err.stack);
        });
      }());
      </script>
    </body>
    </html>
    
  2. b-ma commented on Nov 14, 2017

    @b-ma
    Contributor

    Hi, I have add this issue before but can't remember the cause, looks like your delta x is twice larger as it should be. Do you have a public repo for your project so I could run it ?

  3. justinlevi commented on Nov 14, 2017

    @justinlevi
    Author

    @b-ma Here you go

    https://bl.ocks.org/justinlevi/9eed1adbb79f30b78eeb464eb3fb04a2
    Might take a sec to load as the wav is pretty big

    Here's the gist as well.
    https://gist.github.com/justinlevi/9eed1adbb79f30b78eeb464eb3fb04a2#file-index-html

    Updated my code example above to reflect this example as well.

  4. justinlevi commented on Nov 15, 2017

    @justinlevi
    Author

    @b-ma Here's an interesting discovery. If I add both layers to the same track, the drag functionality works as expected.

    Working example here.
    https://bl.ocks.org/justinlevi/80349dc50de2b76e58d98bf85a03f3e4

    Not sure what this points to other than the fact that multiple tracks seem to be causing the bug

  5. justinlevi commented on Nov 15, 2017

    @justinlevi
    Author

    Here is one more cleaned up example creating the tracks and layers manually instead of using the timline.addLayer() helper method.

    https://bl.ocks.org/justinlevi/9340df9dbec02a70ba3655b6862d51f2

    Could it be that the drag event is firing twice for some reason?

  6. b-ma commented on Nov 15, 2017

    @b-ma
    Contributor

    Hey,

    that's it, the fact is that you create 2 tracks on the same DOM element, then the timeline instanciate 1 surface for each track and thus each event is triggered twice.
    So, you have 2 options:

    • you put the 2 layers in the same track, using the top parameter for the layout
    • you create two tracks in two different DOM elements

    (actually, looking at your code, I would go for solution 1, as its just a matter of removing one of the tracks)

    This should fix the problem.

  7. b-ma commented on Nov 15, 2017

    @b-ma
    Contributor

    Side question, which tool do you use for creating these animated gifs?

  8. justinlevi commented on Nov 15, 2017

    @justinlevi
    Author

    BINGO! That did the trick.

    https://bl.ocks.org/justinlevi/d2baaf13f2445d29b2d7cd047fca1c29

    I ended up going with two DOM elements as that feels like it is closer to the actual DAW metaphor in this case. Having two layers in the same track doesn't feel as clean.

    I wonder if this is something the library might be able to do automatically though? In my mind, I was dedicating a single DOM element to creating a wavejs interface, probably because I'm thinking more from a React perspective. Either way though, could there be some logic applied here that would create a new DOM element if you try to create two tracks on the root DOM? I haven't thought this all through obviously...

    I use Screenflow for all of my animated gifs. It's incredibly useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions