>  기사  >  웹 프론트엔드  >  캔버스 오프스크린 기술 및 돋보기 구현 코드 예시

캔버스 오프스크린 기술 및 돋보기 구현 코드 예시

青灯夜游
青灯夜游앞으로
2018-10-09 15:43:092361검색

이 글은 주로 캔버스 오프스크린 기술과 돋보기 구현 코드 예제에 대한 정보를 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

캔버스 사용 필터 구현 외에도 오프스크린 기술 돋보기 기능도 사용할 수 있습니다.

설명의 편의를 위해 이 글은 2가지 응용 부분으로 나누어져 있습니다.

  • 워터마크 및 중앙 줌 구현

  • 돋보기 구현

1. 오프스크린 기술이란?

캔버스 학습 및 필터 구현에 drawImage 인터페이스가 도입되었습니다. 이미지를 그리는 것 외에도 이 인터페이스는 다음 작업도 수행할 수 있습니다. drawImage 接口。除了绘制图像,这个接口还可以: 将一个 canvas 对象绘制到另一个 canvas캔버스 개체를 다른 캔버스 개체 위에 그립니다 . 이것이 오프스크린 기술이다.

2. 워터마크 및 중앙 크기 조정 구현

코드에는 캔버스 태그가 두 개 있습니다. 각각 보이는 것과 보이지 않는 것입니다. 보이지 않는 캔버스 객체의 Context 객체는 이미지 워터마크를 배치하는 곳입니다.

자세한 내용은 코드 주석을 참조하세요.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Learn Canvas</title>
  <style>
    canvas {
      display: block;
      margin: 0 auto;
      border: 1px solid #222;
    }

    input {
      display: block;
      margin: 20px auto;
      width: 800px
    }
  </style>
</head>
<body>
  <p id="app">
    <canvas id="my-canvas"></canvas>
    <input type="range" value="1.0" min="0.5" max="3.0" step="0.1">
    <canvas id="watermark-canvas" style="display: none;"></canvas>
  </p>
  <script type="text/javascript">
    window.onload = function () {
      var canvas = document.querySelector("#my-canvas")
      var watermarkCanvas = document.querySelector("#watermark-canvas")
      var slider = document.querySelector("input")

      var scale = slider.value

      var ctx = canvas.getContext(&#39;2d&#39;)
      var watermarkCtx = watermarkCanvas.getContext("2d")

      /* 给第二个canvas获取的Context对象添加水印 */
      watermarkCanvas.width = 300
      watermarkCanvas.height = 100
      watermarkCtx.font = "bold 20px Arial"
      watermarkCtx.lineWidth = "1"
      watermarkCtx.fillStyle = "rgba(255 , 255 , 255, 0.5)"
      watermarkCtx.fillText("=== yuanxin.me ===", 50, 50)
      /****************************************/

      var img = new Image()
      img.src = "./img/photo.jpg"

      /* 加载图片后执行操作 */
      img.onload = function () {
        canvas.width = img.width;
        canvas.height = img.height;
        drawImageByScale(canvas, ctx, img, scale, watermarkCanvas);
        // 监听input标签的mousemove事件
        // 注意:mousemove实时监听值的变化,内存消耗较大
        slider.onmousemove = function () {
          scale = slider.value
          drawImageByScale(canvas, ctx, img, scale, watermarkCanvas);
        }
      }
      /******************/
    }
    /**
    *
    * @param {Object} canvas 画布对象
    * @param {Object} ctx
    * @param {Object} img
    * @param {Number} scale 缩放比例
    * @param {Object} watermark 水印对象
    */
    function drawImageByScale(canvas, ctx, img, scale, watermark) {
      // 图像按照比例进行缩放
      var width = img.width * scale,
        height = img.height * scale
      // (dx, dy): 画布上绘制img的起始坐标
      var dx = canvas.width / 2 - width / 2,
        dy = canvas.height / 2 - height / 2
      ctx.clearRect(0, 0, canvas.width, canvas.height) // No1 清空画布
      ctx.drawImage(img, dx, dy, width, height) // No2 重新绘制图像
      if (watermark) {
        // No3 判断是否有水印: 有, 绘制水印
        ctx.drawImage(watermark, canvas.width - watermark.width, canvas.height - watermark.height)
      }
    }
  </script>
</body>
</html>

효과는 아래 그림과 같습니다.

슬라이더를 드래그하여 이미지를 확대하거나 축소하세요. 그런 다음 마우스 오른쪽 버튼을 클릭하여 이미지를 저장합니다. 저장된 이미지에는 아래 그림과 같이 이미 워터마크가 있습니다.

3. 돋보기 구현

위의 중앙 확대/축소를 기준으로 돋보기 소유자는 주의가 필요합니다.

  • 캔버스 마우스 반응 이벤트 처리 개선: 슬라이드 인, 슬라이드 아웃, 클릭 및 해제

  • 오프스크린 좌표 다시 계산(자세한 수식 계산 아이디어는 코드 주석 참조)

  • 마우스 상대 재계산 캔버스 라벨의 좌표(자세한 수식 계산 아이디어는 코드 주석을 참조하세요)

코드는 다음과 같습니다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    canvas {
      display: block;
      margin: 0 auto;
      border: 1px solid #222;
    }
  </style>
</head>
<body>
  <canvas id="my-canvas"></canvas>
  <canvas id="off-canvas" style="display: none;"></canvas>
  <script>
    var isMouseDown = false,
      scale = 1.0
    var canvas = document.querySelector("#my-canvas")
    var offCanvas = document.querySelector("#off-canvas") // 离屏 canvas
    var ctx = canvas.getContext("2d")
    var offCtx = offCanvas.getContext("2d") // 离屏 canvas 的 Context对象
    var img = new Image()

    window.onload = function () {
      img.src = "./img/photo.jpg"

      img.onload = function () {
        canvas.width = img.width
        canvas.height = img.height

        offCanvas.width = img.width
        offCanvas.height = img.height

        // 计算缩放比例
        scale = offCanvas.width / canvas.width

        // 初识状态下, 两个canvas均绘制Image
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
        offCtx.drawImage(img, 0, 0, canvas.width, canvas.height)

      }

      // 鼠标按下
      canvas.onmousedown = function (event) {
        event.preventDefault() // 禁用默认事件
        var point = windowToCanvas(event.clientX, event.clientY) // 获取鼠标相对于 canvas 标签的坐标
        isMouseDown = true
        drawCanvasWithMagnifier(true, point) // 绘制在离屏canvas上绘制放大后的图像
      }

      // 鼠标移动
      canvas.onmousemove = function (event) {
        event.preventDefault() // 禁用默认事件
        if (isMouseDown === true) {
          var point = windowToCanvas(event.clientX, event.clientY)
          drawCanvasWithMagnifier(true, point)
        }
      }

      // 鼠标松开
      canvas.onmouseup = function (event) {
        event.preventDefault() // 禁用默认事件
        isMouseDown = false
        drawCanvasWithMagnifier(false) // 不绘制离屏放大镜
      }

      // 鼠标移出canvas标签
      canvas.onmouseout = function (event) {
        event.preventDefault() // 禁用默认事件
        isMouseDown = false
        drawCanvasWithMagnifier(false) // 不绘制离屏放大镜
      }
    }

    /**
    * 返回鼠标相对于canvas左上角的坐标
    * @param {Number} x 鼠标的屏幕坐标x
    * @param {Number} y 鼠标的屏幕坐标y
    */
    function windowToCanvas(x, y) {
      var bbox = canvas.getBoundingClientRect() // bbox中存储的是canvas相对于屏幕的坐标
      return {
        x: x - bbox.x,
        y: y - bbox.y
      }
    }

    function drawCanvasWithMagnifier(isShow, point) {
      ctx.clearRect(0, 0, canvas.width, canvas.height) // 清空画布
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height) // 在画布上绘制图像

      /* 利用离屏,绘制放大镜 */
      if (isShow) {
        var { x, y } = point

        var mr = 50 // 正方形放大镜边长

        // (sx, sy): 待放大图像的开始坐标
        var sx = x - mr / 2,
          sy = y - mr / 2

        // (dx, dy): 已放大图像的开始坐标
        var dx = x - mr,
          dy = y - mr

        // 将offCanvas上的(sx,sy)开始的长宽均为mr的正方形区域
        // 放大到
        // canvas上的(dx,dy)开始的长宽均为 2 * mr 的正方形可视区域
        // 由此实现放大效果
        ctx.drawImage(offCanvas, sx, sy, mr, mr, dx, dy, 2 * mr, 2 * mr)
      }
      /*********************/
    }
  </script>
</body>
</html>

돋보기 효과는 아래와 같습니다(빨간색 펜으로 표시된 영역) 는 정사각형 돋보기입니다):

요약: 위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부에 도움이 되길 바랍니다. 더 많은 관련 튜토리얼을 보려면 Html5 비디오 튜토리얼을 방문하세요!

관련 권장 사항:

php 공공 복지 교육 비디오 튜토리얼

HTML5 그래픽 튜토리얼

HTML5 온라인 매뉴얼

위 내용은 캔버스 오프스크린 기술 및 돋보기 구현 코드 예시의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 jb51.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제