【JS】928- 用 Canvas 編輯你的圖片

寫在前面

最近接到一個需求:線下質檢時根據上傳的圖片和實物進行對比檢測,需要在圖片上的動態標記出有瑕疵或污點等位置,便於後續流程檢測和記錄。

想到了之前用過的 canvas 可以實現這個功能,話不多說,讓我們一起認識一下 canvas

canvas 自我介紹

大家好,我是 canvas ,我能讓大家通過 canvas 標籤,用JavaScript來繪製圖形。除此之外,動畫,遊戲圖形,數據可視化,照片處理和實時視頻處理都難不倒我噢~

一、我的兼容性(心有多大,舞臺就有多大)

大家使用前端技術前可以在Can I Use上查詢一下兼容性噢~ 我就在裏面找到了自己呢:

canvas兼容性
二、我能做什麼**(能力越大,責任越大)

我來告訴大家我是怎麼工作的,從簡單的開始噢(hello world~)

1、拿起紙和筆

// .html
<canvas id="tutorial" width="150" height="150"></canvas>

/
/ .js
const canvas = document.getElementById('tutorial');
/
/ ctx就是我的紙了
const ctx = canvas.getContext('2d');
/
/ 準備一下我的筆(就拿個紅色吧~)
ctx.strokeStyle = 'red';
/
/ 填充顏色
ctx.fillStyle = 'red';

2、基本用法

我自己總結了一些方法,大家用起來就快多了

  • 畫線
line
ctx.beginPath();
ctx.lineWidth="5";
ctx.strokeStyle="red"// 紅色路徑
ctx.moveTo(0,75);
ctx.lineTo(250,75);
ctx.stroke(); // 進行繪製

ctx.beginPath();
ctx.strokeStyle="blue"// 藍色路徑
ctx.moveTo(50,0);
ctx.lineTo(150,130);
ctx.stroke(); // 進行繪製
  • 畫個圈圈
arc
ctx.beginPath();
// ctx.arc(x,y,r,sAngle,eAngle,counterclockwise);
// x: 圓的中心的 x 座標。
// y: 圓的中心的 y 座標。
// r: 圓的半徑。
// sAngle: 起始角,以弧度計。(弧的圓形的三點鐘位置是 0 度)。
// eAngle: 結束角,以弧度計。
// counterclockwise: 可選。規定應該逆時針還是順時針繪圖。False = 順時針,true = 逆時針。
ctx.arc(100,75,50,0,2*Math.PI);
ctx.stroke();
  • 畫個框框
    arc
// x: 矩形左上角的 x 座標
// y: 矩形左上角的 y 座標
// width: 矩形的寬度,以像素計
// height: 矩形的高度,以像素計
// 填充矩形
ctx.fillRect(x: 20, y: 20, width: 150, height: 100);
// 無填充矩形
ctx.strokeRect(20,20,150,100);

好啦,以上是我的基本技能,有興趣的話可以在MDN WEB上查看我的全部技能噢~

迴歸到需求上,我們開發者應該如何使用 canvas 完成需求功能呢?

實踐

結合 canvas 技能,方案設計思路如下:

  • 獲取適配的圖片
  • 轉換圖片:按照圖片 1:1 繪製畫布
  • 動態編輯:在畫布上標記操作,可進行增刪改
  • 生成圖片:畫布轉換爲圖片
1、獲取並轉換圖片 drawImage
<img
  style={{ width: 100px, height: 100px }}
  src="https://test.jpg"
  onLoad={onLoad}
/>
<canvas></canvas>

function onLoad({
  // 設置canvas爲圖片大小
  canvas.height = img.height;
  canvas.width = img.width;
  // 繪製圖片 (0,0)開始1:1繪製img
  // ctx.drawImage(img,x,y,width,height);
  ctx.drawImage(img, 00, img.width, img.height);
}
2、編輯功能 (此處主要實現框選功能)
canvas.addEventListener("mousedown", onMouseDown);
canvas.addEventListener("mousemove", onMouseMove);

function getPointOnCanvas({
  // canvas相對於視窗的位置集合
  const rect = canvas.getBoundingClientRect();
  return {
    x: x - rect.left * (canvas.width / rect.width),
    y: y - rect.top * (canvas.height / rect.height)
  }
}

function onMouseDown(event{
  var x = event.pageX;
  var y = event.pageY;
  // 獲取起點
  startPoint = getPointOnCanvas(canvas, x, y);

  ctx.beginPath();
  ctx.moveTo(startPoint.x, startPoint.y);
}

function getRectParam(curPoint) => {
  const _w = curPoint.x - startPoint.x;
  const _h = curPoint.y - startPoint.y;
  const _startPoint = _w < 0 || _h < 0 ? curPoint : startPoint;
  return {
    _startPoint,
    _w,
    _h
  };
};

function drawRect({
  // 獲取繪製矩形需要的參數
  const newRect = getRectParam(curPoint)
  // 繪製矩形
  ctx.beginPath();
  ctx.rect(
    newRect._startPoint.x,
    newRect._startPoint.y,
    Math.abs(newRect._w),
    Math.abs(newRect._h)
  );
  ctx.stroke();
}

function mousemove(event{
  const x = event.pageX;
  const y = event.pageY;
  // 獲取
  const curPoint = getPointOnCanvas(canvas, x, y);
  drawRect();
};
3、canvas 轉圖片
const dataURL = canvas.toDataURL('image/png')

以上是部分代碼,來看看編輯效果:


目前需求已順利上線,質檢師的使用反饋很不錯。

寫在後面

希望通過本文給大家帶來一種前端處理圖片的思路,有興趣的同學可以嘗試一下 canvas 的其他功能,如:添加文字,編輯的撤回等等。

接下來,會陸續推出三無項目重構的踩坑之旅、跨應用的拖拽能力實踐等。每天進步一點點,質變從關注 大轉轉 FE 開始!


1. JavaScript 重溫系列(22篇全)
2. ECMAScript 重溫系列(10篇全)
3. JavaScript設計模式 重溫系列(9篇全)
4.  正則 / 框架 / 算法等 重溫系列(16篇全)
5.  Webpack4 入門(上) ||  Webpack4 入門(下)
6.  MobX 入門(上)  ||   MobX 入門(下)
7. 120 +篇原創系列彙總

回覆“加羣”與大佬們一起交流學習~

點擊“閱讀原文”查看 120+ 篇原創文章

本文分享自微信公衆號 - 前端自習課(FE-study)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章