之前就說了canvas設置大小的時候用的就是設置實打實的像素值,像圖像一樣設置百分比然后根據瀏覽器大小自己適應大小是不可能的——當然一般也不會想要cavans改變大小。不過項目之前有用到過,既然去了解了,就記下來防止忘記。
不能自己適應,就只能每次外部容器發生改變的時候給它重新設置大小了。
1、 $(selector).resize()—布局調整大小的時候觸發
查了查jquery好像有resize函數,頓時很驚喜,然而發現並沒有什么用,它只支持$(window).resize(function(){});在某些情況這個就夠用了,但是之前我明顯用不了。
剛好查到了一個自定義的resize()函數,但是由於過去有點久,又沒有留下記錄,不知道是誰的代碼了,是基於jq的代碼。如下:

//監聽div大小變化 (function($, h, c) { var a = $([]), e = $.resize = $.extend($.resize, {}), i, k = "setTimeout", j = "resize", d = j + "-special-event", b = "delay", f = "throttleWindow"; e[b] = 250; e[f] = true; $.event.special[j] = { setup: function() { if (!e[f] && this[k]) { return false; } var l = $(this); a = a.add(l); $.data(this, d, { w: l.width(), h: l.height() }); if (a.length === 1) { g(); } }, teardown: function() { if (!e[f] && this[k]) { return false; } var l = $(this); a = a.not(l); l.removeData(d); if (!a.length) { clearTimeout(i); } }, add: function(l) { if (!e[f] && this[k]) { return false; } var n; function m(s, o, p) { var q = $(this), r = $.data(this, d); r.w = o !== c ? o: q.width(); r.h = p !== c ? p: q.height(); n.apply(this, arguments); } if ($.isFunction(l)) { n = l; return m; } else { n = l.handler; l.handler = m; } } }; function g() { i = h[k](function() { a.each(function() { var n = $(this), m = n.width(), l = n.height(), o = $.data(this, d); if (m !== o.w || l !== o.h) { n.trigger(j, [o.w = m, o.h = l]); } }); g(); }, e[b]); } })(jQuery, this);
2、 更改canvas的大小
canvas.width和canvas.height是canvas本身的屬性,可以直接賦值修改。但是修改canvas的大小的同時會導致canvas內容的丟失,你需要保存原本的canvas的信息,然后再將信息放到已經改變好大小的canvas上,有下面兩種方法。
<1>toDataURL() + new Image() + drawImage()
獲取圖像的base64信息,然后利用構造新的圖像對象和ctx.drawImage(img, 0, 0, newwidth, newheight)進行縮放,也支持scale()縮放。
a)不使用scale()
var base64 = c.toDataURL(); c.width=contain.offsetWidth;//父元素的大小 c.height=contain.offsetHeight; var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0,c.width,c.height);//進行縮放 } img.src = base64;
b)使用scale()
var base64 = c.toDataURL(); c.width=contain.offsetWidth; c.height=contain.offsetHeight; ctx.scale(c.width/width,c.height/height);//進行縮放,width/height是原canvas的大小 var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0,width,height); } img.src = base64;
這個方法比較好,但是受同源限制,單單跑html的時候如果想要對加載了圖片的canvas進行操作可不行,需要跑到http上。
2、getImageData() + putImageData()
保存像素矩陣,然后把像素矩陣放到新畫布上,不會縮放,也不受scale()影響。如果要等比例縮放,需要自己對像素矩陣進行操作。同樣受同源限制。
var data=ctx.getImageData(0,0,width,height); var base64 = c.toDataURL(); c.width=contain.offsetWidth; c.height=contain.offsetHeight; ctx.putImageData(data,0,0);
完整代碼:

<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"/> <script src='js/jquery-3.3.1.min.js'></script> <script src='js/resize.js'></script> <style> body{ //background:black; text-align:center; } #myCanvas{ background:white; border:1px solid black; } #contain{ margin:0 auto; width:30%; height:40px; } #scream{ width:100%; } img{ margin-top:10px; border:1px solid red; } </style> </head> <body> <div id="contain"> <canvas id="myCanvas"></canvas> </div> <script type="text/javascript"> $(document).ready(function(){ var contain = document.getElementById('contain'); var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); c.width=contain.offsetWidth; c.height=contain.offsetHeight;//***根據容器大小設置寬和高 /****如果是本地圖片繪制的img受同源限制,報錯 var img= new Image(); img.onload=function(){ ctx.drawImage(img,0,0); var data = ctx.getImageData(0,0,2,2);//獲取像素點 console.log(data); } img.src="img/6.png"; //*/ //****不能用圖片展示,畫個對角線試試 ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(c.width,c.height); ctx.stroke(); ctx.closePath(); //容器大小發生改變觸發 $('#contain').resize(function(){ var width = c.width; var height = c.height; var data=ctx.getImageData(0,0,width,height);//獲取像素點 var base64 = c.toDataURL();//獲取base64 c.width=contain.offsetWidth; c.height=contain.offsetHeight; //ctx.scale(c.width/width,c.height/height); //ctx.putImageData(data,0,0);//放置像素矩陣,不會縮放,超出部分會丟失 var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0,c.width,c.height);//利用base64圖像進行縮放 //ctx.drawImage(img,0,0,width,height); } img.src = base64; }); }); </script> </body> </html>
參考:
同源限制:
https://blog.csdn.net/u013040887/article/details/78986598