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

Waveform with rounded bars #953

Closed
mattpilott opened this issue Feb 1, 2017 · 21 comments · Fixed by #1760
Closed

Waveform with rounded bars #953

mattpilott opened this issue Feb 1, 2017 · 21 comments · Fixed by #1760
Assignees

Comments

@mattpilott
Copy link

mattpilott commented Feb 1, 2017

screen shot 2017-02-01 at 13 47 44

Hey, I'm working on a project and the design for the waveform is fairly custom, each bar having border-radius/rounded ends and the gaps being larger than that of the demo's.

How would I go about doing this?

Thanks,

@mspae mspae added the question label Feb 1, 2017
@entonbiba
Copy link
Contributor

@matt3224 something like this?

I'll have to implement this enhancement code with the current WaveSurfer library.

Preview:
http://codepen.io/entonbiba/pen/vgRZwa

Current:
image

With barRadius parameter (to be added via pull request)
image

@mattpilott
Copy link
Author

Hey @entonbiba thanks for that. I had a little play, http://codepen.io/matt3224/pen/RKMJdp

It looks as though the barWidth property is not behaving correctly now, also is the radius making it truly rounded? It's hard to tell.

Looks good so far though, really appreciate the help!

@entonbiba
Copy link
Contributor

@matt3224 I'll see what else can be done to be make look smoother when the barWidth is larger. However if you make it 7 it should be fine.

http://codepen.io/anon/pen/BprqMm

@mattpilott
Copy link
Author

Do you find that setting the bar width makes the gap bigger but not the bar?

@entonbiba
Copy link
Contributor

@matt3224 if I set it to 3 it looks nice, you want the bar a bit bigger when using the radius though right?
http://codepen.io/anon/pen/BprqMm

@mattpilott
Copy link
Author

Yeah, I mean I would imagine you could control it much like you would in css, using width, margin and border-radius. That way I could have any width bar with any gap size with either a rounded or flat ends. That would make it very versatile indeed.

Thanks again!

@entonbiba
Copy link
Contributor

entonbiba commented Feb 4, 2017

@matt3224 yea I've made it so if the barRadius parameter is not set, it would result in flat ends. Also you can do something like barRadius: 6 which would set the radius manually.

http://codepen.io/entonbiba/pen/xgzOqx
image

@entonbiba entonbiba self-assigned this Mar 6, 2017
@Agshealth-Raj
Copy link

Agshealth-Raj commented Apr 12, 2017

"Uncaught ReferenceError: wavesurfer is not defined
at HTMLButtonElement.onclick"
i got this issue while click play button in my code.. please help me..

@entonbiba
Copy link
Contributor

@Agshealth-Raj is the click button within a wavesufer ready event?

@mspae mspae changed the title How to create a waveform like the attached Waveform with rounded bars Sep 18, 2017
@mattpilott
Copy link
Author

Hey, its been a whole year since I first queried this enhancement. The project I needed this for did go to development and i've been working on it for a few months. With v2 and all I wondered if this was implemented. I really could do with having this functionality. Thanks!

@bradley-varol
Copy link

I'd also really like this as a feature.

@mattpilott
Copy link
Author

I still also need this feature

@mattpilott
Copy link
Author

@entonbiba is there anything you can do/suggest or perhaps could you let me know what you did to achieve this before?

@delgiudices
Copy link

Yeah this would be super useful

@thijstriemstra
Copy link
Contributor

if you copy/paste the roundRect method below in src/drawer.canvasentry.js:

/**
 * Draws a rounded rectangle using the current state of the canvas.
 * If you omit the last three params, it will draw a rectangle
 * outline with a 5 pixel border radius
 * @param {CanvasRenderingContext2D} ctx
 * @param {Number} x The top left x coordinate
 * @param {Number} y The top left y coordinate
 * @param {Number} width The width of the rectangle
 * @param {Number} height The height of the rectangle
 * @param {Number} [radius = 5] The corner radius; It can also be an object 
 *                 to specify different radii for corners
 * @param {Number} [radius.tl = 0] Top left
 * @param {Number} [radius.tr = 0] Top right
 * @param {Number} [radius.br = 0] Bottom right
 * @param {Number} [radius.bl = 0] Bottom left
 * @param {Boolean} [fill = false] Whether to fill the rectangle.
 * @param {Boolean} [stroke = true] Whether to stroke the rectangle.
 */
const roundRect = function(ctx, x, y, width, height, radius, fill, stroke) {
  if (typeof stroke == 'undefined') {
    stroke = true;
  }
  if (typeof radius === 'undefined') {
    radius = 5;
  }
  if (typeof radius === 'number') {
    radius = {tl: radius, tr: radius, br: radius, bl: radius};
  } else {
    var defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
    for (var side in defaultRadius) {
      radius[side] = radius[side] || defaultRadius[side];
    }
  }
  ctx.beginPath();
  ctx.moveTo(x + radius.tl, y);
  ctx.lineTo(x + width - radius.tr, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
  ctx.lineTo(x + width, y + height - radius.br);
  ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
  ctx.lineTo(x + radius.bl, y + height);
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
  ctx.lineTo(x, y + radius.tl);
  ctx.quadraticCurveTo(x, y, x + radius.tl, y);
  ctx.closePath();
  if (fill) {
    ctx.fill();
  }
  if (stroke) {
    ctx.stroke();
  }

}

And in the fillRectToContext method of CanvasEntry change:

ctx.fillRect(x, y, width, height);

to

let radius = 3;
roundRect(ctx, x, y, width, height, radius, true, false);

it will render with rounded corners but for some reason only the first half is correct as shown in screenshot below. Anybody an idea?

Screenshot from 2019-07-10 23-11-00

@kubk
Copy link

kubk commented Aug 1, 2019

@thijstriemstra Hi, thank you. I found a workaround for the problem:

    fillRectToContext(ctx, x, y, width, height) {
        if (!ctx) {
            return;
        }
+        if (height < 0) {
+            height = Math.abs(height);
+            y -= height;
+        }
        const cornerRadius = 5;
        this.roundRect(ctx, x, y, width, height, cornerRadius, true, false);
    }

It is strange, but in some cases height is negative which affects calculating of border radius. Here is the result:
image

@katspaugh Hi, what do you think about this hacky solution? Do you have an idea how to improve it? Can create a PR which adds optional boder radius option.

@thijstriemstra
Copy link
Contributor

awesome, sounds good @kubk!

@rijk
Copy link

rijk commented Sep 30, 2019

Can this be merged in the library?

@thijstriemstra
Copy link
Contributor

@rijk can you make a pull request so it can be merged?

@rijk
Copy link

rijk commented Sep 30, 2019

Sorry, thought this was an open PR.

@kubk
Copy link

kubk commented Sep 30, 2019

@rijk @thijstriemstra Will create a PR in the next few days with these changes: #953 (comment)

thijstriemstra pushed a commit that referenced this issue Oct 6, 2019
* Waveform with rounded bars (Close #953)

* Rename drawRoundedRectangle to drawRoundedRect

* clarify absolute height values

* add changelog entry

* fix lint error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants