• Canvas+Video打造酷炫播放体验


    image

    一.简介

    直到现在,仍然不存在一项旨在网页上显示视频的标准。

    今天,大多数视频是通过插件(比如 Flash)来显示的。然而,并非所有浏览器都拥有同样的插件。

    HTML5 规定了一种通过 video 元素来包含视频的标准方法。如:

    1
    2
    <video src="movie.ogg" controls="controls">
    </video>

    二.Canvas+Video

    HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。

    drawImage函数有三种函数原型:

    drawImage(image, dx, dy) 
    drawImage(image, dx, dy, dw, dh) 
    drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

    第一个参数image可以用HTMLImageElement,HTMLCanvasElement或者HTMLVideoElement作为参数

    dx和dy是image在canvas中定位的坐标值;dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值;

    sx和sy是image所要绘制的起始位置,sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值。

    所以这使酷炫播放体验有了实现的可能。

    三.理解canvas.translate和canvas.scale

    很多人对于canvas.translate(x,y)的理解有的错误,之前一直以原点(0,0)为基准点,作用就是移动原点,默认的原点(0,0)是在屏幕左上角的,你可以通过translate(x,y)把点(x,y)作为原点,就一直以为这个(x,y)就是新的坐标原点。但看一下API就会知道,这种理解是不对的,

    不过API确实容易误导大家:

    1
    2
    3
    4
    5
    6
    7
    view plain
    public void translate (float dx, float dy) 
     Since: API Level 1 
    Preconcat the current matrix with the specified translation 
    Parameters 
    dx  The distance to translate in X 
    dy  The distance to translate in Y


    其实是原来的原点分别在x轴和y轴偏移多远的距离,然后以偏移后的位置作为坐标原点。也就是说原来在(100,100),然后translate(1,1)新的坐标原点在(101,101)而不是(1,1)

    canvas.scale:

    canvas.scale提供了放大缩小倒置等功能。比如Y倒置:canvas.scale(1,-1)

    四.核心代码

    1
    2
    3
    4
    5
    6
    7
    canvas.setAttribute('height', Math.floor(video.height));
          canvas.setAttribute('width', Math.floor(video.width));
     
          ctx.translate(0, canvas.height );
          ctx.scale(1, -1);
          ctx.globalAlpha = 0.3;
          ctx.drawImage(video, 0, 0, video.width, video.height, 0, -canvas.height/2, canvas.width, canvas.height);

    五.在线演示

     
     00:00 /

    六.代码下载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    <html >
    <head>
    <meta charset="utf-8" />
    <title></title>
     
    </head>
    <body>
       <div>
       <video  width="640" height="264">
      </video> <br/>
      <canvas style="position:absolute; top:143px;"></canvas>
    </div>
    <div  style="position:absolute; top:400px;">
      <p>
        <input type="button" id="play" value="play">
        <span id="position">00:00</span> / <span id="duration"></span>
      </p>
      </div>
    <script >
     
        var addEvent = (function () {
            if (document.addEventListener) {
                return function (el, type, fn) {
                    if (el && el.nodeName || el === window) {
                        el.addEventListener(type, fn, false);
                    } else if (el && el.length) {
                        for (var i = 0; i < el.length; i++) {
                            addEvent(el[i], type, fn);
                        }
                    }
                };
            } else {
                return function (el, type, fn) {
                    if (el && el.nodeName || el === window) {
                        el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
                    } else if (el && el.length) {
                        for (var i = 0; i < el.length; i++) {
                            addEvent(el[i], type, fn);
                        }
                    }
                };
            }
        })();
        
    </script>
    <script>
        var video = document.querySelector('video');
        var togglePlay = document.querySelector('#play');
        var position = document.querySelector('#position');
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');
     
        addEvent(togglePlay, 'click', function () {
            video.playbackRate = 0.5;
            if (video.paused) {
                if (video.ended) video.currentTime = 0;
                video.play();
                this.value = "pause";
            } else {
                video.pause();
                this.value = "play";
            }
        });
     
        setInterval(function () {
            position.innerHTML = asTime(video.currentTime);
            ctx.drawImage(video, 0, 0, video.width, video.height, 0, -canvas.height / 2, canvas.width, canvas.height);
        }, 1000 / 15);
     
        addEvent(video, 'ended', function () {
            togglePlay.value = "play";
        });
     
        addEvent(video, 'canplay', function () {
            video.muted = true;
            document.querySelector('#duration').innerHTML = asTime(this.duration);
            startCanvas();
        });
     
     
        function startCanvas() {
            canvas.setAttribute('height', Math.floor(video.height));
            canvas.setAttribute('width', Math.floor(video.width));
     
            ctx.translate(0, canvas.height );
            ctx.scale(1, -1);
            ctx.globalAlpha = 0.3;
            ctx.drawImage(video, 0, 0, video.width, video.height, 0, -canvas.height/2, canvas.width, canvas.height);
     
           
        }
     
        function asTime(t) {
            t = Math.round(t);
            var s = t % 60;
            var m = Math.round(t / 60);
     
            return two(m) + ':' + two(s);
        }
     
        function two(s) {
            s += "";
            if (s.length < 2) s = "0" + s;
            return s;
        }
    </script>
    </body>
     
    </html>
  • 相关阅读:
    Directx11 HelloWorld之DirectCompute
    TortoiseSVN使用简介
    图形学的坐标转换问题(局部到世界坐标系,世界到观察坐标系)
    Directx11中获取HLSL中变量一些问题
    Mathematics for Computer Graphics
    Nvidia给力 Android游戏革命来临 有能力超iPhone
    D3d10和D3d11中Map()函数用法一点心得总结
    GPU开始无处不在,加速火狐浏览器4.0
    Delphi多媒体设计之TMediaPlayer组件(四)
    Delphi多媒体设计之TMediaPlayer组件(一)
  • 原文地址:https://www.cnblogs.com/yulei126/p/6756242.html
Copyright © 2020-2023  润新知