当前位置 博文首页 > q1424966670的博客:canvas实现视频播放,带炸裂特效

    q1424966670的博客:canvas实现视频播放,带炸裂特效

    作者:[db:作者] 时间:2021-08-27 18:53

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>HTML5 Video Destruction</title>
        <script type="text/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>
    </head>
    
    <body onload="init()" style="margin:0px;">
        <div style="display:none">
            <video id="sourcevid" autoplay="true" loop="true">
                <source src="cf.mp4" type="video/mp4" />
            </video>
            <canvas id="sourcecopy" width="640" height="360"></canvas>
        </div>
        <div>
            <center>
                <canvas id="output" width="1000" height="600" onmousedown="dropBomb(event, this)" style="border: 0 none"></canvas>
            </center>
        </div>
    </body>
    
    </html>

    ?

    cs