Maison  >  Article  >  interface Web  >  Le canevas JavaScript+html5 implémente la fragmentation et la réorganisation d'images, les compétences d'effets spéciaux d'animation_javascript

Le canevas JavaScript+html5 implémente la fragmentation et la réorganisation d'images, les compétences d'effets spéciaux d'animation_javascript

WBOY
WBOYoriginal
2016-05-16 15:14:163281parcourir

Peut-être avez-vous vu les effets spéciaux d'animation de rupture d'image HTML5, et le principe de mise en œuvre est assez simple. Mais vous n'avez peut-être jamais vu que les vidéos peuvent être brisées et réorganisées. Cette animation HTML5 utilise les fonctionnalités associées de Canvas pour obtenir l'effet de casser et de réorganiser la vidéo d'un simple clic de souris. Cliquez avec la souris dans la zone vidéo pour interrompre la vidéo dans cette zone. Après un certain temps, la zone brisée peut être réorganisée et restaurée, et l'effet visuel est excellent.

Code 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>

Code 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>

J'espère que cet article sera utile à tout le monde dans l'apprentissage de la programmation javascript.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn