本次的分享是一個基於canvas的更新圖片特效實現。其中主要涉及canvas中getImageData()、putImageData()、toDataURL()
方法的使用。效果請看下面。
歡迎關注個人博客,不按期更新中——css
PS:請在本地服務器中打開頁面,因谷歌瀏覽器中會有跨域問題,如需node靜態服務器能夠參照這個地址node
點我查看源碼倉庫git
//當點擊按鈕時傳遞底圖的寬高
var img = new Image()
img.src = 'xxx'
img.onload = function() {
$('.btn').click(function() {
...
var that = this
var imgSize = {
realHeight: that.height,
realWidth: that.width
}
changeImg(imgSize, img)
})
}複製代碼
var changeImg = function(imgSize, oldImg) {
var img = $(oldImg),
offset = img.offset(),
imgLeft = offset.left,
imgTop = offset.top,
canvasId = 'canvas'
$('body').append('<canvas id='+ canvasId +' width='+ imgSize.realWidth+' height='+ imgSize.realHeight +'></canvas>')
$('#'+ canvasId).css({
'position': 'absolute',
'left': imgLeft,
'top': imgTop,
'z-index': 1
})
...
}複製代碼
首先來介紹下getImageData()、putImageData()
這兩個方法github
CanvasRenderingContext2D.getImageData() 返回一個ImageData對象,用來描述canvas區域隱含的像素數據,這個區域經過矩形表示,起始點爲(sx, sy)、寬爲sw、高爲sh。canvas
CanvasRenderingContext2D.putImageData() 是 Canvas 2D API 將數據從已有的 ImageData 對象繪製到位圖的方法。跨域
這其中的重點則是ImageData對象是什麼。不妨咱們打印一下看看:
數組
能夠看出一個2乘2的畫布佔4個像素,其中打印了一個長度爲16的一維數組,結合文檔中的講解咱們能夠知道,其中每個像素均有4位分別爲rgba,故經過getImageData()咱們能夠獲得一個拍平了的rgba數組,那麼當咱們動態的去改變一些東西的時候整個圖像的色值透明度就會引發相應的變化,想一想還有些小激動呢。同時putImageData()就很好理解了。當咱們改變完像素數值後經過這個方法再反饋到畫布上。瀏覽器
//核心代碼
//經過sin函數畫出曲線
var imgData = content.getImageData(0, 0, width, height)
for(var i = 0; i < width / 10; i+=0.1 ) {
x=Math.round(i*10)
y=Math.round(Math.sin(i - t) * scale + initY)
//scale爲曲線幅度,initY爲初始位置
for(var k = 0; k < y; k++) {
var sym = x * 4 + k * width * 4
//每一個像素4位,sym表示當前爲第幾個像素的第一位
imgData.data[sym + 3] = 0 //令該像素點變透明
//imgData.data[sym + 3]會到達該像素點的透明度位即第四位
}
}
content.putImageData(imgData, 0, 0, 0, 0, width, height)複製代碼
其中initY爲sin曲線的縱座標位置,那麼當動態減少這個iniY時圖像渲染的曲線會一點點向上,同時透明的區域便一點點變小,同時改變t值會另曲線橫向移動,以此來造成最後的波浪形並緩緩向上的效果。bash
oldImg.src = oCanvas.toDataURL('image/png')
$(oCanvas).remove()複製代碼
經過toDataURL()方法,能夠使畫布轉換成base64形式的img圖片,將其替換到舊圖片的url中即可以實現圖片的更新特效。服務器
慣例po做者的博客,不定時更新中——有問題歡迎在issues下交流,捂臉求star=。=