Рисование прямоугольника с закругленными углами на холсте апплета Wechat

внешний интерфейс GitHub Апплет WeChat Canvas

Апплет WeChat позволяет передавать общие элементыborder-radiusнастройка для рисования закругленных углов, но иногда с использованиемcanvasПри рисовании также необходимы закругленные углы.Например, когда вам нужно экспортировать область на странице в виде изображения и загрузить его локально, обычно используетсяcanvasНарисуйте эту область и, наконец, экспортируйтеcanvasДа, ноcanvasРендеринг закругленных углов не предоставляется напрямуюapi, так нужно曲线救国


Отличие прямоугольника со скругленными углами от обычного прямоугольника в том, что четыре угла первого являются дугами, поэтому вам нужно только отрезать четыре угла общего прямоугольника и заменить их дугами.Угол выглядит так:

Очевидно, что прямоугольник с четырьмя углами отрезан, а остальные четыре.line, в этом случае можно пропустить шаг рисования прямоугольника и последующего вырезания угла, потому что результат вырезания угла - четыре стороны (line), вы можете напрямую рисовать четыре стороны. Затем нарисуйте радианы в недостающих углах каждых двух сторон, как0.5 * Math.PIДуга и, наконец, фигура, окруженная этими четырьмя сторонами и четырьмя дугами, представляет собой прямоугольник со скругленными углами:

Принцип известен, а код написать легко, вот лишь несколько замечаний:

  • закрытая графикаfillStyleЦвет установлен наtransparent

Если вы хотите нарисовать графику замкнутого пути, вам нужно вызватьstrokeилиfillметод, по умолчаниюstrokeилиfillцветblack, но здесь есть проблема, Рисунок дуги может выглядеть неровным или размытым, еслиstrokeилиfillЦвет цвета не соответствует тону края прямоугольника со скругленными углами, который вам нужно нарисовать.Такой вид размытого края будет более очевидным, чем цвет двух. На первом изображении ниже показан один и тот же цветовой тон, а на втором — случай, когда цветовой тон непостоянен:

Однако, по моему наблюдению, пока вы не увеличиваете масштаб и не смотрите внимательно, независимо от того, одинаковый цветовой тон или нет, обычным людям на самом деле трудно заметить размытие.

  • clip

После рисования округленного выделения также необходимо вызватьctx.clipметод выбора урожая

  • saveа такжеrestore

Если этот прямоугольный выбор простоcanvasчасть полотна, во избежание последующего воздействия лучше всегоbeginPathраньше, переместить предыдущее действиеsave, а потом после покраскиrestore

один осуществуетcanvasНарисуйте закругленное изображение сверху и загрузите его локальноИсполняемый пример кода был помещен вgithubНа, аннотации тоже более подробные, можете сами взять если надо

Код ключа следующий:

/**
  * 
  * @param {CanvasContext} ctx canvas上下文
  * @param {number} x 圆角矩形选区的左上角 x坐标
  * @param {number} y 圆角矩形选区的左上角 y坐标
  * @param {number} w 圆角矩形选区的宽度
  * @param {number} h 圆角矩形选区的高度
  * @param {number} r 圆角的半径
  */
function roundRect(ctx, x, y, w, h, r) {
  // 开始绘制
  ctx.beginPath()
  // 因为边缘描边存在锯齿,最好指定使用 transparent 填充
  // 这里是使用 fill 还是 stroke都可以,二选一即可
  ctx.setFillStyle('transparent')
  // ctx.setStrokeStyle('transparent')
  // 左上角
  ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)

  // border-top
  ctx.moveTo(x + r, y)
  ctx.lineTo(x + w - r, y)
  ctx.lineTo(x + w, y + r)
  // 右上角
  ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)

  // border-right
  ctx.lineTo(x + w, y + h - r)
  ctx.lineTo(x + w - r, y + h)
  // 右下角
  ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)

  // border-bottom
  ctx.lineTo(x + r, y + h)
  ctx.lineTo(x, y + h - r)
  // 左下角
  ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)

  // border-left
  ctx.lineTo(x, y + r)
  ctx.lineTo(x + r, y)

  // 这里是使用 fill 还是 stroke都可以,二选一即可,但是需要与上面对应
  ctx.fill()
  // ctx.stroke()
  ctx.closePath()
  // 剪切
  ctx.clip()
}