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

Canvas 绘制带圆角的矩形图 #26

Open
maomao1996 opened this issue Jan 13, 2022 · 0 comments
Open

Canvas 绘制带圆角的矩形图 #26

maomao1996 opened this issue Jan 13, 2022 · 0 comments
Labels
Canvas Canvas 相关

Comments

@maomao1996
Copy link
Owner

maomao1996 commented Jan 13, 2022

Canvas 绘制带圆角的矩形图

实现步骤:

  1. 绘制一个圆角矩形 (打开冰箱)
  2. 对圆角矩形进行剪切(把 🐘 放进去)
  3. 将图片绘制到矩形内(关上冰箱)

绘制圆角矩形

arcTo 方案

arcTo 可以根据控制点和半径绘制圆弧路径

// 绘制圆角矩形(使用 arcTo)
function drawRoundedRect(ctx, x, y, width, height, radius) {
  // 重置当前路径
  ctx.beginPath()

  // 移动到左上角
  ctx.moveTo(x + radius, y)
  // 绘制右上角
  ctx.arcTo(x + width, y, x + width, y + radius, radius)
  // 绘制右下角
  ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius)
  // 绘制左下角
  ctx.arcTo(x, height, x, height - radius, radius)
  // 绘制左上角
  ctx.arcTo(x, y, x + radius, y, radius)

  // 填充当前路径
  ctx.fill()
}

quadraticCurveTo 二次贝塞尔曲线方案

quadraticCurveTo 用于创建二次贝塞尔曲线

// 绘制圆角矩形(使用二次贝塞尔曲线 quadraticCurveTo)
function drawRoundedRect(ctx, x, y, width, height, radius) {
  // 重置当前路径
  ctx.beginPath()

  // 移动到右上角
  ctx.moveTo(x + width - radius, y)
  // 绘制右上角曲线
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
  // 绘制右边线
  ctx.lineTo(x + width, y + height - radius)
  // 绘制右下角曲线
  ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
  // 绘制下边线
  ctx.lineTo(x + radius, y + height)
  // 绘制左下角曲线
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
  // 绘制左边线
  ctx.lineTo(x, y + radius)
  // 绘制左上角曲线
  ctx.quadraticCurveTo(x, y, x + radius, y)
  // 绘制上边线(创建从当前点回到起始点的路径)
  ctx.closePath()

  // 填充当前路径
  ctx.fill()
}

不得不说贝塞尔曲线真烦人,圆角矩形还是 arcTo

绘制图片

clip 方案

clip 可以从原始画布剪切任意形状和尺寸的区域。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas 绘制带圆角的矩形图 — clip</title>
  </head>
  <body>
    <div>
      <img
        id="img"
        src="https://mms1.baidu.com/it/u=181635795,1817021705&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=284"
        alt=""
      />
    </div>
    <canvas id="canvas" width="500" height="284"></canvas>
    <script>
      // 绘制圆角矩形(使用 arcTo)
      function drawRoundedRect(ctx, x, y, width, height, radius) {
        // 保存当前环境的状态
        ctx.save()
        // 重置当前路径
        ctx.beginPath()

        // 移动到左上角
        ctx.moveTo(x + radius, y)
        // 绘制右上角
        ctx.arcTo(x + width, y, x + width, y + radius, radius)
        // 绘制右下角
        ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius)
        // 绘制左下角
        ctx.arcTo(x, height, x, height - radius, radius)
        // 绘制左上角
        ctx.arcTo(x, y, x + radius, y, radius)

        // 填充当前路径
        ctx.fill()
      }

      const img = document.getElementById('img')
      const canvas = document.getElementById('canvas')
      const ctx = canvas.getContext('2d')
      window.onload = function () {
        const x = 0
        const y = 0
        const width = canvas.width
        const height = canvas.height

        let radius = 50

        // 处理圆角边界值
        radius = Math.min(radius, Math.min(width, height) / 2)

        // 绘制圆角矩形
        drawRoundedRect(ctx, x, y, width, height, radius)

        // 对矩形进行剪切
        ctx.clip()
        // 绘制图片
        ctx.drawImage(img, x, y, width, height)
      }
    </script>
  </body>
</html>

CodeSandbox: Canvas 绘制带圆角的矩形图 — clip

globalCompositeOperation 方案

globalCompositeOperation 可以设置要在绘制新形状时应用的合成操作的类型

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas 绘制带圆角的矩形图 — globalCompositeOperation</title>
  </head>
  <body>
    <div>
      <img
        id="img"
        src="https://mms1.baidu.com/it/u=181635795,1817021705&fm=253&app=138&f=JPEG&fmt=auto&q=75?w=500&h=284"
        alt=""
      />
    </div>
    <canvas id="canvas" width="500" height="284"></canvas>
    <script>
      // 绘制圆角矩形(使用 arcTo)
      function drawRoundedRect(ctx, x, y, width, height, radius) {
        // 保存当前环境的状态
        ctx.save()
        // 重置当前路径
        ctx.beginPath()

        // 移动到左上角
        ctx.moveTo(x + radius, y)
        // 绘制右上角
        ctx.arcTo(x + width, y, x + width, y + radius, radius)
        // 绘制右下角
        ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius)
        // 绘制左下角
        ctx.arcTo(x, height, x, height - radius, radius)
        // 绘制左上角
        ctx.arcTo(x, y, x + radius, y, radius)

        // 填充当前路径
        ctx.fill()
      }

      const img = document.getElementById('img')
      const canvas = document.getElementById('canvas')
      const ctx = canvas.getContext('2d')
      window.onload = function () {
        const x = 0
        const y = 0
        const width = canvas.width
        const height = canvas.height

        let radius = 600

        // 处理圆角边界值
        radius = Math.min(radius, Math.min(width, height) / 2)

        // 绘制圆角矩形
        drawRoundedRect(ctx, x, y, width, height, radius)
        // 只在新图形和目标画布重叠的地方绘制图形
        ctx.globalCompositeOperation = 'source-in'
        // 绘制图片
        ctx.drawImage(img, x, y, width, height)
      }
    </script>
  </body>
</html>

CodeSandbox: Canvas 绘制带圆角的矩形图 — globalCompositeOperation

这是李总教我的方案,再次膜拜一下大佬

相关资料

@maomao1996 maomao1996 added the Canvas Canvas 相关 label Jan 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Canvas Canvas 相关
Projects
None yet
Development

No branches or pull requests

1 participant