HTML5 Canvas 破碎重組的視訊特效
本文由碼農網 – 小峰原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
也許你見過HTML5圖片破碎動畫特效,實現的原理也挺簡單的。但是你應該沒有見過視訊也可以破碎重組,這個HTML5動畫就是利用Canvas的相關特性,實現了點選滑鼠讓視訊破碎重組的效果。在視訊區域點選滑鼠,即可讓該區域的視訊破碎,讓後經過一段時間後,破碎的區域又可以重組還原,視覺效果非常棒。
HTML程式碼
<div style="display:none"> <video id="sourcevid" autoplay="true" loop="true"> <source src="BigBuckBunny_640x360.mp4" type="video/mp4"/> <source src="BigBuckBunny_640x360.ogv" type="video/ogg"/> </video> <canvas id="sourcecopy" width="640" height="360"></canvas> </div> <div> <center> <div style="z-index:1;position:relative;text-align:center;font-size:16px;font-weight:bold;width:1000px;top:60px;">Click video to blow it up!</div> <canvas id="output" width="1000" height="600" onmousedown="dropBomb(event, this)" style="border: 0 none"> </canvas> </center> </div>
JavaScript程式碼
var video; var copy; var copycanvas; var draw; var TILE_WIDTH = 32; var TILE_HEIGHT = 24; var TILE_CENTER_WIDTH = 16; var TILE_CENTER_HEIGHT = 12; var SOURCERECT = {x:0, y:0, width:0, height:0}; var PAINTRECT = {x:0, y:0, width:1000, height:600}; function init(){ video = document.getElementById('sourcevid'); copycanvas = document.getElementById('sourcecopy'); copy = copycanvas.getContext('2d'); var outputcanvas = document.getElementById('output'); draw = outputcanvas.getContext('2d'); setInterval("processFrame()", 33); } function createTiles(){ var offsetX = TILE_CENTER_WIDTH+(PAINTRECT.width-SOURCERECT.width)/2; var offsetY = TILE_CENTER_HEIGHT+(PAINTRECT.height-SOURCERECT.height)/2; var y=0; while(y < SOURCERECT.height){ var x=0; while(x < SOURCERECT.width){ var tile = new Tile(); tile.videoX = x; tile.videoY = y; tile.originX = offsetX+x; tile.originY = offsetY+y; tile.currentX = tile.originX; tile.currentY = tile.originY; tiles.push(tile); x+=TILE_WIDTH; } y+=TILE_HEIGHT; } } var RAD = Math.PI/180; var randomJump = false; var tiles = []; var debug = false; function processFrame(){ if(!isNaN(video.duration)){ if(SOURCERECT.width == 0){ SOURCERECT = {x:0,y:0,width:video.videoWidth,height:video.videoHeight}; createTiles(); } //this is to keep my sanity while developing if(randomJump){ randomJump = false; video.currentTime = Math.random()*video.duration; } //loop if(video.currentTime == video.duration){ video.currentTime = 0; } } var debugStr = ""; //copy tiles copy.drawImage(video, 0, 0); draw.clearRect(PAINTRECT.x, PAINTRECT.y,PAINTRECT.width,PAINTRECT.height); for(var i=0; i<tiles.length; i++){ var tile = tiles[i]; if(tile.force > 0.0001){ //expand tile.moveX *= tile.force; tile.moveY *= tile.force; tile.moveRotation *= tile.force; tile.currentX += tile.moveX; tile.currentY += tile.moveY; tile.rotation += tile.moveRotation; tile.rotation %= 360; tile.force *= 0.9; if(tile.currentX <= 0 || tile.currentX >= PAINTRECT.width){ tile.moveX *= -1; } if(tile.currentY <= 0 || tile.currentY >= PAINTRECT.height){ tile.moveY *= -1; } }else if(tile.rotation != 0 || tile.currentX != tile.originX || tile.currentY != tile.originY){ //contract var diffx = (tile.originX-tile.currentX)*0.2; var diffy = (tile.originY-tile.currentY)*0.2; var diffRot = (0-tile.rotation)*0.2; if(Math.abs(diffx) < 0.5){ tile.currentX = tile.originX; }else{ tile.currentX += diffx; } if(Math.abs(diffy) < 0.5){ tile.currentY = tile.originY; }else{ tile.currentY += diffy; } if(Math.abs(diffRot) < 0.5){ tile.rotation = 0; }else{ tile.rotation += diffRot; } }else{ tile.force = 0; } draw.save(); draw.translate(tile.currentX, tile.currentY); draw.rotate(tile.rotation*RAD); draw.drawImage(copycanvas, tile.videoX, tile.videoY, TILE_WIDTH, TILE_HEIGHT, -TILE_CENTER_WIDTH, -TILE_CENTER_HEIGHT, TILE_WIDTH, TILE_HEIGHT); draw.restore(); } if(debug){ debug = false; document.getElementById('trace').innerHTML = debugStr; } } function explode(x, y){ for(var i=0; i<tiles.length; i++){ var tile = tiles[i]; var xdiff = tile.currentX-x; var ydiff = tile.currentY-y; var dist = Math.sqrt(xdiff*xdiff + ydiff*ydiff); var randRange = 220+(Math.random()*30); var range = randRange-dist; var force = 3*(range/randRange); if(force > tile.force){ tile.force = force; var radians = Math.atan2(ydiff, xdiff); tile.moveX = Math.cos(radians); tile.moveY = Math.sin(radians); tile.moveRotation = 0.5-Math.random(); } } tiles.sort(zindexSort); processFrame(); } function zindexSort(a, b){ return (a.force-b.force); } function dropBomb(evt, obj){ var posx = 0; var posy = 0; var e = evt || window.event; if (e.pageX || e.pageY){ posx = e.pageX; posy = e.pageY; }else if (e.clientX || e.clientY) { posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } var canvasX = posx-obj.offsetLeft; var canvasY = posy-obj.offsetTop; explode(canvasX, canvasY); } function Tile(){ this.originX = 0; this.originY = 0; this.currentX = 0; this.currentY = 0; this.rotation = 0; this.force = 0; this.z = 0; this.moveX= 0; this.moveY= 0; this.moveRotation = 0; this.videoX = 0; this.videoY = 0; } /* getPixel return pixel object {r,g,b,a} */ function getPixel(imageData, x, y){ var data = imageData.data; var pos = (x + y * imageData.width) * 4; return {r:data[pos], g:data[pos+1], b:data[pos+2], a:data[pos+3]} } /* setPixel set pixel object {r,g,b,a} */ function setPixel(imageData, x, y, pixel){ var data = imageData.data; var pos = (x + y * imageData.width) * 4; data[pos] = pixel.r; data[pos+1] = pixel.g; data[pos+2] = pixel.b; data[pos+3] = pixel.a; } /* copyPixel faster then using getPixel/setPixel combo */ function copyPixel(sImageData, sx, sy, dImageData, dx, dy){ var spos = (sx + sy * sImageData.width) * 4; var dpos = (dx + dy * dImageData.width) * 4; dImageData.data[dpos] = sImageData.data[spos]; //R dImageData.data[dpos+1] = sImageData.data[spos+1]; //G dImageData.data[dpos+2] = sImageData.data[spos+2]; //B dImageData.data[dpos+3] = sImageData.data[spos+3]; //A } </script>
本文連結:http://www.codeceo.com/article/html5-broken-video.html
本文作者:碼農網 – 小峰
[ 原創作品,轉載必須在正文中標註並保留原文連結和作者等資訊。]
相關文章
- Html5 canvas創意特效合集HTMLCanvas特效
- HTML5 canvas圖片爆炸特效HTMLCanvas特效
- 基於 Canvas 的 HTML5 文字動畫特效CanvasHTML動畫特效
- 7款炫酷的HTML5 Canvas動畫特效HTMLCanvas動畫特效
- 基於 HTML5 Canvas 實現的文字動畫特效HTMLCanvas動畫特效
- “破碎-重組-破碎” CSS3實現Lowpoly風格變形動畫終極篇CSSS3動畫
- 非常逼真的玻璃破碎特效android特效Android
- 基於 HTML5 Canvas 實現文字動畫特效HTMLCanvas動畫特效
- 16個非常有趣的HTML5 Canvas動畫特效集合HTMLCanvas動畫特效
- 如何使用AE製作破碎文字特效特效
- 使用canvas檢測HTML5視訊解碼錯誤CanvasHTML
- html5 canvas實現高併發視訊彈幕功能HTMLCanvas
- html5視訊HTML
- HTML5的CanvasHTMLCanvas
- canvas動畫特效 之 星空Canvas動畫特效
- HTML5 音訊和視訊HTML音訊
- 基於canvas的視訊遮罩外掛Canvas遮罩
- 可以隨心所欲的canvas粒子特效Canvas特效
- 用canvas實現流星特效Canvas特效
- HTML5 -- CanvasHTMLCanvas
- HTML5的視訊格式之爭HTML
- Red Giant Universe for Mac(AE視訊特效)Mac特效
- HTML5視訊videoHTMLIDE
- HTML5 SVG 特效示例HTMLSVG特效
- HTML5的canvas標籤HTMLCanvas
- js實現視訊截圖,視訊批量截圖,canvas實現JSCanvas
- 淺析HTML5的Canvas——1HTMLCanvas
- WebView播放HTML5視訊,黑屏的問題。WebViewHTML
- 「Premiere中文新手教程」萬花筒視訊特效小技巧REM特效
- 想給視訊新增特效初學者怎麼辦?特效
- HTML5的SVG和Canvas的使用HTMLSVGCanvas
- HTML5(五)——Canvas APIHTMLCanvasAPI
- HTML5 Canvas 詳解HTMLCanvas
- html5畫布canvasHTMLCanvas
- html5 canvas分層HTMLCanvas
- HTML5學習筆記 視訊HTML筆記
- 嵌入視訊到html5頁面HTML
- 你知道微視背後的視訊特效技術是怎樣做出來的嗎?特效