欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript+html5 canvas實現(xiàn)圖片破碎重組動畫特效

 更新時間:2016年02月22日 12:03:05   投稿:lijiao  
這篇文章主要介紹了JavaScript+html5 canvas實現(xiàn)破碎重組的視頻特效,感興趣的小伙伴們可以參考一下

也許你見過HTML5圖片破碎動畫特效,實現(xiàn)的原理也挺簡單的。但是你應(yīng)該沒有見過視頻也可以破碎重組,這個HTML5動畫就是利用Canvas的相關(guān)特性,實現(xiàn)了點擊鼠標(biāo)讓視頻破碎重組的效果。在視頻區(qū)域點擊鼠標(biāo),即可讓該區(qū)域的視頻破碎,讓后經(jīng)過一段時間后,破碎的區(qū)域又可以重組還原,視覺效果非常棒。

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>

希望本文所述對大家學(xué)習(xí)javascript程序設(shè)計有所幫助。

相關(guān)文章

  • js循環(huán)中使用正則失效異常的踩坑實戰(zhàn)

    js循環(huán)中使用正則失效異常的踩坑實戰(zhàn)

    這篇文章主要給大家介紹了關(guān)于js循環(huán)中使用正則失效異常的踩坑實戰(zhàn),文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-05-05
  • 微信小程序?qū)崿F(xiàn)圖片處理小工具的示例代碼

    微信小程序?qū)崿F(xiàn)圖片處理小工具的示例代碼

    本文將利用微信小程序制作一個簡易的圖片處理小工具(自制低配版美圖秀秀),有濾鏡、效果圖和動態(tài)濾鏡三個功能,快跟隨小編一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • MvcPager分頁控件 適用于Bootstrap

    MvcPager分頁控件 適用于Bootstrap

    這篇文章主要為大家詳細(xì)介紹了MvcPager分頁控件,修改后適用于Bootstrap,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • JS打印gridview實現(xiàn)原理及代碼

    JS打印gridview實現(xiàn)原理及代碼

    打印gridview對于一些童鞋們真的是很陌生啊,不過沒有關(guān)系,因為本文的出現(xiàn),或讓你茅塞頓開,好了話不多說,感興趣的朋友可以了解下,或許對你學(xué)習(xí)js高級知識有所幫助
    2013-02-02
  • javascript動態(tài)獲取登錄時間和在線時長

    javascript動態(tài)獲取登錄時間和在線時長

    這篇文章主要為大家詳細(xì)介紹了javascript動態(tài)獲取登錄時間和在線時長的相關(guān)資料,獲得登錄時候的時間,用來和動態(tài)的時間做差來求時長,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 返回上一個url并刷新界面的js代碼

    返回上一個url并刷新界面的js代碼

    要返回上一頁再刷新頁面我們用到最多的是在像php,asp,jsp,asp.net中,下面我來給大家先介紹js 返回前一頁并刷新頁面,然后再把這些代碼放在php中實現(xiàn)刪除后返回當(dāng)前頁面并刷新頁面
    2020-09-09
  • 使用JavaScript判斷變量類型的方法詳解

    使用JavaScript判斷變量類型的方法詳解

    在 JavaScript 中,變量的類型是動態(tài)的,這幾天我在做項目時,遇到了一個從方法返回的值問題,為了避免這種問題,我需要先判斷一下返回值的類型,那么,你知道哪些判斷變量類型的方法呢,本文給大家介紹了使用 JavaScript 如何判斷變量類型,需要的朋友可以參考下
    2024-06-06
  • js鼠標(biāo)點擊圖片切換效果代碼分享

    js鼠標(biāo)點擊圖片切換效果代碼分享

    這篇文章主要為大家詳細(xì)介紹了js鼠標(biāo)點擊圖片切換效果,很實用的代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2015-08-08
  • javascript檢測是否聯(lián)網(wǎng)的實現(xiàn)代碼

    javascript檢測是否聯(lián)網(wǎng)的實現(xiàn)代碼

    這篇文章主要介紹了javascript檢測是否聯(lián)網(wǎng)的實現(xiàn)代碼,需要的朋友可以參考下
    2014-09-09
  • vscode錄音及語音實時轉(zhuǎn)寫插件開發(fā)并在工作區(qū)生成本地mp3文件附踩坑日記!

    vscode錄音及語音實時轉(zhuǎn)寫插件開發(fā)并在工作區(qū)生成本地mp3文件附踩坑日記!

    以目前的vscode版本來說,作者并沒有開放訪問本地媒體權(quán)限,所以插件市場里面的所有語音相關(guān)插件也并沒有直接獲取vscode的媒體權(quán)限,這篇文章主要介紹了vscode錄音及語音實時轉(zhuǎn)寫插件開發(fā)并在工作區(qū)生成本地mp3文件?踩坑日記!,需要的朋友可以參考下
    2023-05-05

最新評論