ranslate移動變形
translate()移動畫布, rotate()旋轉畫布。
canvas中不能只移動某一個對象, 移動的都是整個畫布。
canvas中不能只旋轉某一個對象, 旋轉的都是整個畫布。
但是可以用save()、restore()來巧妙設置, 實現讓某一個元素進行移動和旋轉。
移動變形、移動的是整個畫布、而不是某個元素, 在ctx.translate()之后繪制的語句都將被影響。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style type="text/css">
canvas{
border: 1px solid #000;
background:url(images/bg.png);
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
</body>
<script type="text/javascript">
var canvas = document.querySelector('canvas')
var ctx = canvas.getContext("2d");
ctx.translate(100, 100); //將畫布坐標系移動,坐標系就發生變化了
ctx.fillRect(0, 0, 100, 100); //相對于移動后的坐標系開始畫畫
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style type="text/css">
canvas{
border: 1px solid #000;
background:url(images/bg.png);
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
</body>
<script type="text/javascript">
var canvas = document.querySelector('canvas')
var ctx = canvas.getContext("2d");
ctx.translate(100, 100); //將畫布坐標系移動,坐標系就發生變化了
ctx.fillRect(0, 0, 100, 100); //相對于移動后的坐標系開始畫畫
ctx.beginPath();
ctx.arc(100, 100, 100,0 , 6.28, false);
ctx.fillStyle ="skyblue";
ctx.fill();
</script>
</html>
save()保存和restore()恢復
ctx.save()表示保存上下文的物理性質, ctx.restore()表示恢復最近一次的保存。
save表示保存sava函數之前的狀態, restore表示獲取save保存的狀態。
移動了的元素, 會影響不需要移動圓點坐標的元素, 所以可以使用以上兩個方法保存起來, 可以解決讓某一個元素移動變形不受影響。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style type="text/css">
canvas{
border: 1px solid #000;
background:url(images/bg.png);
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
</body>
<script type="text/javascript">
var canvas = document.querySelector('canvas')
var ctx = canvas.getContext("2d");
ctx.save();
ctx.translate(100, 100); //將畫布坐標系移動,坐標系就發生變化了
ctx.fillRect(0, 0, 100, 100); //相對于移動后的坐標系開始畫畫
ctx.restore()
ctx.beginPath();
ctx.arc(100, 100, 100, 0 , 6.28, false);
ctx.fillStyle ="skyblue";
ctx.fill();
</script>
</html>
rotate()旋轉變形
旋轉的是整個坐標系, 坐標系以0,0點為中心點進行旋轉。
rotate(1)的參數, 是弧度, 旋轉的也不是矩形, 而是畫布。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style type="text/css">
canvas{
border: 1px solid #000;
background:url(images/bg.png);
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
</body>
<script type="text/javascript">
var canvas = document.querySelector('canvas')
var ctx = canvas.getContext("2d");
ctx.save();
ctx.translate(150,150)
ctx.rotate(1); //1表示57.3度(1弧度)
ctx.fillRect(-50, -50, 100, 100); //相對于移動后的坐標系開始旋轉
ctx.restore()
</script>
</html>
旋轉動畫
幾天,朋友要做個上傳圖片后,如何讓圖片旋轉角度,并且不影響容器或者隨著圖片大小改變容器。
先上完整實例效果圖
一開始想到的是給 img 用 css3 的`transform: rotate(90deg);`
結果變成這個樣子:
角度完全偏離中心了。
手動去調整 img 的 left 和 top 也是無用,不同的圖片大小不一樣,很難把控。
如果 js 實時去調整圖片或者容器的寬高,也不現實,麻煩不說代碼一堆。
突然想到用 canvas 可以繪圖,最近剛好在研究。
// 獲取圖片 id
var img = document.getElementById("Img");
// 創建 canvas
var canvas = document.createElement('canvas');
//給 canvas 創建畫板
var cxt = canvas.getContext('2d');
// 給畫板添加寬高
canvas.width = img.width;
canvas.height = img.height;
// 渲染
cxt.drawImage(img, 0, 0);
// 輸出到頁面中
document.body.appendChild(canvas);
圖片繪制了,但是并沒有旋轉角度,怎么旋轉呢?
簡單介紹下`getContext("2d")`對象屬性和方法,可用于在畫布上繪制文本、線條、矩形、圓形等等。
然后再查看下手冊 canvas 提供的方法
根據描述,以下兩個方法完全滿足我們的需求
`translate()` // 重新映射畫布上的 (x,y) 位置
`rotate()` // 旋轉當前繪圖
舉個例子,一張圖片寬高為 w:100,h:300 的時候,旋轉 90° 后,寬高應為: w:300,h:100
為什么要用`translate()`呢,因為旋轉角度是以 x 為起點的,如果不用這個方法,繪制出來后你會看不到圖像的。
x 添加到水平坐標(x)上的值
y 添加到垂直坐標(y)上的值
根據例子,代碼應為:
cxt.translate(300, 0); // 坐標 x, y
cxt.rotate(90 * Math.PI / 180);
怎么`rotate()`里面有個`Math.PI / 180`是什么鬼?
請看參數說明:
`context.rotate(angle);`
angle:
旋轉角度,以弧度計。
如需將角度轉換為弧度,請使用 `degrees*Math.PI/180` 公式進行計算。
舉例:如需旋轉 5 度,可規定下面的公式:`5*Math.PI/180`。
小編總結旋轉 4個角度分別對應的參數應為:
// 0:
canvas.width = img.width;
canvas.height = img.height;
cxt.translate(0, 0);
cxt.rotate(0 * Math.PI / 180);
// ---------------
// 90:
canvas.width = img.height;
canvas.height = img.width;
cxt.translate(img.height, 0);
cxt.rotate(90 * Math.PI / 180);
// ---------------
// 180:
canvas.width = img.width;
canvas.height = img.height;
cxt.translate(img.width, img.height);
cxt.rotate(180 * Math.PI / 180);
// ---------------
// 270:
canvas.width = img.height;
canvas.height = img.width;
cxt.translate(0, img.width);
cxt.rotate(270 * Math.PI / 180);
繪制出來的是 canvas,怎么變成圖片數據呢,我們需要用:`toDataURL()`
canvas.toDataURL 返回的是一串 Base64 編碼的 URL,當然,瀏覽器自己肯定支持
// 指定格式 PNG
canvas.toDataURL("image/png");
// 指定格式 JPEG
canvas.toDataURL("image/jpeg");
// 指定格式 JPEG 壓縮 0.5 質量, 0-1 之間
canvas.toDataURL("image/jpeg", 0.5);
圖片壓縮前后對比,左邊是壓縮前,右邊是壓縮 0.5 后。
圖片壓縮體積前后大小對比,左邊是壓縮前,右邊是壓縮 0.5 后。
簡化版實例代碼
// 獲取圖片 id
var img = document.getElementById("Img");
// 創建 canvas
var canvas = document.createElement('canvas');
var new_img = document.createElement('img');
// 給 canvas 創建畫板
var cxt = canvas.getContext('2d');
new_img.onload = function () {
// 給畫板添加寬高
canvas.width = new_img.height;
canvas.height = new_img.width;
// 渲染
cxt.translate(new_img.height, 0); //坐標
cxt.rotate(90 * Math.PI / 180);
cxt.drawImage(new_img, 0, 0);
var base64 = canvas.toDataURL("image/jpeg");
var base64_s = canvas.toDataURL("image/jpeg", 0.5);
var img_source = new Image;
var img_compression = new Image;
img_source.id = "img-source";
img_source.src = base64;
img_compression.id = "img-compression";
img_compression.src = base64_s;
// 輸出到頁面中
document.body.appendChild(img_source);
document.body.appendChild(img_compression);
}
new_img.src = img.src;
jQuery 插件版
做成了個 jQuery插件,完整代碼太多了,想要下載的可以到 github 上下載:
https://github.com/orzhtml/rotateImg/
本文內容均屬個人原創作品,轉載此文章須附上出處及原文鏈接。
加關注,定時推送,互動精彩多,若你有更好的見解,歡迎留言探討!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。