Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange Segment-behavior with two tracks #35

Open
justinlevi opened this issue Nov 13, 2017 · 8 comments
Open

Strange Segment-behavior with two tracks #35

justinlevi opened this issue Nov 13, 2017 · 8 comments

Comments

@justinlevi
Copy link

justinlevi commented Nov 13, 2017

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

@justinlevi
Copy link
Author

justinlevi commented Nov 13, 2017

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>

@b-ma
Copy link
Contributor

b-ma commented Nov 14, 2017

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 ?

@justinlevi
Copy link
Author

justinlevi commented Nov 14, 2017

@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.

@justinlevi
Copy link
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

@justinlevi
Copy link
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?

@b-ma
Copy link
Contributor

b-ma commented Nov 15, 2017

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.

@b-ma
Copy link
Contributor

b-ma commented Nov 15, 2017

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

@justinlevi
Copy link
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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants