Canvas+Video打造酷炫播放体验
一.简介
直到现在,仍然不存在一项旨在网页上显示视频的标准。
今天,大多数视频是通过插件(比如 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); |
五.在线演示
六.代码下载
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 > |
Canvas+Video打造酷炫播放体验的更多相关文章
- 使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉视差效果并解决各种滑动冲突
使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉视差效果并解决各种冲突 如果你还在为处理滑动冲突而发愁,那么你需要静 ...
- HTML5 Canvas玩转酷炫大波浪进度图
如上图所见,本文就是要实现上面那种效果. 由于最近AlloyTouch要写一个下拉刷新的酷炫loading效果.所以首选大波浪进度图. 首先要封装一下大波浪图片进度组件.基本的原理是利用Canvas绘 ...
- 三分钟学会用 js + css3 打造酷炫3D相册
之前发过该文,后来不知怎么回事不见了,现在重新发一下. 中秋主题的3D旋转相册 如图,这是通过Javascript和css3来实现的.整个案例只有不到80行代码,我希望通过这个案例,让正处于迷茫期的j ...
- MVC中使用SignalR打造酷炫实用的即时通讯功能附源码
前言,现在这世道写篇帖子没个前言真不好意思发出来.本贴的主要内容来自于本人在之前项目中所开发的一个小功能,用于OA中的即时通讯.由于当时走的太急,忘记把代码拿出来.想想这已经是大半年前的事情了,时间过 ...
- MVC中使用SignalR打造酷炫实用的即时通讯功能(轉載)
資料來源:http://www.fangsi.net/1144.html 前言,现在这世道写篇帖子没个前言真不好意思发出来.本贴的主要内容来自于本人在之前项目中所开发的一个小功能,用于OA中的即时通讯 ...
- 学习websocket-SignalR,MVC中使用SignalR打造酷炫实用的即时通讯
http://www.cnblogs.com/Leo_wl/p/4793284.html http://www.fangsi.net/archives/1144.html
- Android 使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉视差效果并解决各种滑动冲突
如果你还在为处理滑动冲突而发愁,那么你需要静下心来看看这边文章,如果你能彻底理解这篇文章中使用的技术,那么,一切滑动冲突的问题解决起来就轻而易举了: 先扔一个最终实现的效果图 先分析下效果图中实现的功 ...
- [刘阳Java]_酷炫视频播放器制作_界面篇
今天开始分享一篇酷炫播放器制作,包括界面+JS.整个案例非常类似腾讯视频,优酷视频,爱奇艺视频.我们先看一下效果图,然后这篇文章主要界面篇 是不是效果比较酷炫,那么我接着来给大家说一下这个界面设计思路 ...
- 2019基于Hexo快速搭建个人博客,打造一个炫酷博客(1)-奥怪的小栈
本文转载于:奥怪的小栈 这篇文章告诉你如何在2019快速上手搭建一个像我一样的博客:基于HEXO+Github搭建.并完成SEO优化,打造一个炫酷博客. 本站基于HEXO+Github搭建.所以你需要 ...
随机推荐
- vue-cli脚手架npm相关文件解读(3)webpack.dev.conf.js
系列文章传送门: 1.build/webpack.base.conf.js 2.build/webpack.prod.conf.js 3.build/webpack.dev.conf.js 4.bui ...
- HTML5无插件多媒体Media——音频audio与视频video
文件日志地址 http://blog.csdn.net/q1056843325/article/details/60336226 音频与视频现在已经变得越来越流行 各个网站为了保证跨浏览器的兼容性 ...
- 关闭Excel提示文件格式和扩展名不匹配的警告框
打开某些excel表时,Excel会提示: "a.xls"的文件格式和扩展名不匹配.文件可能已损坏或不安全.除非您信任其来源,否则请勿打开.是否仍要打开它? 在编辑大量的xls ...
- Java的常用操作符
操作符用于接受一个或多个参数,并生成一个新的值.加号和一元的正号(+).减号和一元的负号(一).乘号(*).除号(/)以及赋值号(=)的用法和大多数编程语言都类似. 操作符作用于操作数,生成一个新值. ...
- B/S 架构中,网络模型的分解与协议解析
前言 如果是C/S专业毕业的或者是学过计算机网络课程的童鞋们,相信大家都知道网络模型的划分,本文首先来聊一聊目前对于B/S结构中,网络模型分解的两种方式. 没错,相信大家看到这个图片的时候就已经明白了 ...
- spring文件上传
Spring文件上传 1,导包: <dependency> <groupId>javax.servlet</groupId> <artifactId>s ...
- 一语惊醒梦中人-《Before I Fall》
I still remembered I turned my attention to the title when I browsed in news by cellphone.I saw the ...
- Ext.Msg.alert添加确定按钮
Ext.Msg.alert('成功','成功!!', function(btn){ if(btn!=null{//btn=='ok'||btn=='cancel' ... } });
- css 找到隐藏元素个数
<form> <input type="hidden" name="email" /> <input type=" ...
- Java 随笔记录
1. java对象转json Message msg = generateMessage();ObjectMapper mapper = new ObjectMapper();String json ...