bbc / peaks.js

JavaScript UI component for interacting with audio waveforms
https://waveform.prototyping.bbc.co.uk
GNU Lesser General Public License v3.0
3.2k stars 279 forks source link

Display text in center of the segment #462

Closed Arjun021 closed 1 year ago

Arjun021 commented 2 years ago

I checked the customized segment demo but in that the text is over the start and end line of the segment. Instead of that, is it possible to display the text in the center of the start and end lines of each segment ? Can someone guide me through it or provide some solution for this?

export class CustomSegmentMarker {
  _options: any;
  _group: any;
  _label: any;
  _tag: any
  _text: any;
  _line: any;
 constructor(options: any) {
   this._options = options;
 }

 init(group: any) {
   this._group = group;
   this._label = new Label({
     x: 0.5,
     y: 0.5
   });

   const color = this._options.segment.color;

   this._tag = new Tag({
     fill:             color,
     stroke:           color,
     strokeWidth:      1,
     pointerDirection: 'down',
     pointerWidth:     10,
     pointerHeight:    10,
     lineJoin:         'round',
     shadowColor:      'black',
     shadowBlur:       10,
     shadowOffsetX:    3,
     shadowOffsetY:    3,
     shadowOpacity:    0.3
   });

   this._label.add(this._tag);

   let labelText = this._options.segment.labelText;

   this._text = new Text({
     text:       labelText,
     fontFamily: 'Calibri',
     fontSize:   14,
     padding:    5,
     fill:       'white'
   });

   this._label.add(this._text);

   // Vertical Line - create with default y and points, the real values
   // are set in fitToView().
   this._line = new Line({
     x:           0,
     y:           0,
     stroke:      color,
     strokeWidth: 1
   });

   group.add(this._label);
   group.add(this._line);

   this.fitToView();

   this.bindEventHandlers();
 }

 bindEventHandlers() {
   this._group.on('mouseenter', function() {
     document.body.style.cursor = 'move';
   });

   this._group.on('mouseleave', function() {
     document.body.style.cursor = 'default';
   });
 }

 fitToView() {
   const height = this._options.layer.getHeight();

   const labelHeight = this._text.height() + 2 * this._text.padding();
   const offsetTop = 14;
   const offsetBottom = 26;

   this._group.y(offsetTop + labelHeight + 0.5);

   this._line.points([0.5, 0, 0.5, height - labelHeight - offsetTop - offsetBottom]);
 }
}
chrisn commented 2 years ago

This is a good question. It's currently not easy (or even possible) to do this using the custom segment marker API.

There is a new feature in development in the segment-drag branch that draws segments as a rectangle overlay over the waveform, rather than as start/end marker handles. I could consider extending that to allow the text to be centered.

Arjun021 commented 2 years ago

@chrisn Thank you for the answer, this is also pretty much helpful. When are you planning to release this feature?

chrisn commented 1 year ago

This is now available in the v3.0.0 beta releases