记得在过去的Web前端开发中,如果你需要绘图或者生成相关图形的话,使用Flash可能是你唯一或者说最强大的实现方式,而在近些年的技术热点HTML5标准中,HTML Canvas(画布)能够更加方便的帮助你实现2D绘制图形图像及其各种动画效果功能。
首先我们先来了解一下什么是HTML Canvas?
我们可以在HTML中使用属性width和height来定义Canvas。但是实现Canvas的相关功能主要还依赖于Javascript实现,即HTML5 Canvas API。我们使用javascript来访问和控制Canvas相关的区域,比如调用相关绘图的方法,用来动态的生成需要的动画或者图形。
接下来我们来看看canvas的特性:
互动性:Canvas支持互动,可以很好的响应用户的操作,我们可以通过Javascript来监键盘,鼠标,及其触摸设备相关事件。
动 画:任何被canvas绘制的图形都可以添加动画,简单的弹跳球或者复杂的HTML5游戏都可以实现
灵活性:开发人员可以使用Canvas来绘制任何的内容,比如,直线,图形,文字,图片等,可以包含动画或者不包含。同时你可以添加音频或者视频浏览器支持:几乎所有的现代浏览器都支持,并且被广泛的各种设备支持,例如,桌面,平板,智能手机等等。
流行度:canvas目前很流行,很多的开发人员都使用它来开发类似游戏或者绘图类应用
web标准:只需要有浏览器就可以运行,而非flash或者silverlight,需要安装相关的插件
开发一次,任何浏览器都可以运行(当然,不包括老式浏览器)
可以使用免费拥有大量的开发工具及其类库。
使用HTML5 Canvas我们能开发那些相关产品或者应用呢?
1 可视化数据: 各类统计图表,比如:百度的echart
2 场景秀:用Canvas实现动态的广告效果能够非常融洽的跨平台运行。如:手机中微产品.在移动端兼容性很好。
3 游戏:canvas在基于Web的图像显示方面比Flash更加立体、更加精巧,canvas成为HTML5小游戏开发首选。现阶段h5做游戏,营业方式不是很明确. 25 超棒的 HTML5 Canvas 游戏。
4 其他可嵌入网站的内容 (多用于活动页面、特效):类似图表、音频、视频,还有许多元素能够更好地与Web融合,并且不需要任何插件。
5 趋势=> 模拟器: 无论从视觉效果还是核心功能方面来说,模拟器产品可以完全由JavaScript来实现。模拟真实硬件环境,如移动端各种类型手机.
6 趋势=> 远程计算机控制: Canvas可以让开发者更好地实现基于Web的数据传输,构建一个完美的可视化控制界面。
7 趋势=> 图形编辑器: Photoshop图形编辑器将能够100%基于Web实现。
如何使用HTML5 Canvas?
使用HTML5 canvas其实非常简单, 每一个canvas都拥有一个上下文(context)。使用它你可以来调用相关的画布方法。
<canvas id="mycanvas" width="500" height="400">
<p>您的浏览器不支持HTML5 Canvas</p>
</canvas>
以上代码我们在HTML中添加了一个canvas标签,如果浏览器不支持canvas,会显示<p>标签的内容,当然,如果你需要支持老式浏览器你也可以使用flash或者其它方法来做一个替代的解决方案。
var canvas=document.getElementById('mycanvas'),
context=canvas.getContext(‘2d’);
以上代码我们通过canvas取到2D的context。
在HTML5 Canvas的2D结构中,坐标(0,0)在左上方,这和传统的坐标不太一样。大家需要注意一下,如下图所示:
下面来说一下canvas的API:
canvas的主要属性和方法:
save():保存当前环境的状态
restore():返回之前保存过的路径状态和属性
createEvent()
getContext():返回一个对象,指出访问绘图功能必要的API
toDateURL():返回canvas图像的URL
颜色、样式和阴影属性和方法:
fillStyle:设置或返回用于填充绘画的颜色、渐变或模式
strokeStyle:设置或返回用于笔触的颜色、渐变或模式
shadowColor:设置或返回用于阴影的颜色
shadowBlur:设置或返回用于阴影的模糊级别
shadowOffsetX:设置或返回阴影距形状的水平距离
shadowOffsetY:设置或返回阴影距形状的垂直距离
createLinearGradient():创建线性渐变(用在画布内容上)
createPattern():在指定的方向上重复指定的元素
createRadialGradient():创建放射状/环形的渐变(用在画布内容上)
addColorStop():规定渐变对象中的颜色和停止位置
线条样式属性和方法
lineCap:设置或返回线条的结束端点样式
lineJoin:设置或返回两条线相交时,所创建的拐角类型
lineWidth:设置或返回当前的线段宽度
miterLimit:设置或返回最大斜接长度
Canvas的API-路径方法
fill():填充当前绘图(路径)
stroke():绘制已定义的路径
beginPath():起始一条路径,或重置当前路径
moveTo():把路径移动到画布中的指定点,不创建线条
closePath():创建从当前点回到起始点的路径
lineTo():添加一个新点,创建从该点到最后指定点的线条
clip():从原始画布剪切任意形状和尺寸的区域
quadraticCurveTo():创建二次贝塞尔曲线
bezierCurveTo():创建三次贝塞尔曲线
arc():创建弧/曲线(用于创建圆形或部分圆)
arcTo():创建两切线之间的弧/曲线
isPointInPath():如果指定的点位于当前路径中,返回布尔值
Canvas的API-转换方法
scale():缩放当前绘图至更大或更小
rotate():旋转当前绘图
translate():重新映射画布上的(0,0)位置
transform():替换绘图的当前转换矩阵
setTransform():将当前转换重置为单位矩阵,然后运行transform()
Canvas的API-文本属性和方法
font:设置或返回文本内容的当前字体属性
textAlign:设置或返回文本内容的当前对齐方式
textBaseline:设置或返回在绘制文本时使用的的当前文本基线
fillText():在画布上绘制“被填充的”文本
strokeText():在画布上绘制文本(无填充)
measureText():返回包含指定文本宽度的对象
Canvas的API-图像绘制方法
drawImage():向画布上绘制图像、画布或视频
Canvas的API-像素操作方法和属性
width:返回ImageData对象的宽度
height:返回ImageData对象的高度
data:返回一个对象,其包含指定的ImageData对象的图像数据
createImageData():创建新的、空白的I马哥Data对象
getImageData():返回ImageData对象,该对象为画布上指定的矩形复制像素数据
putImageData():把图像数据(从指定的ImageData对象)放回画布上
Canvas的API-图像合成属性
globalAlpha:设置或返回绘图的当前alpha或透明值
globalCompositeOperation:设置或返回新图像如何绘制到已有的图像上
直接使用Canvas来绘制图形相对来说比较乏味并且麻烦,所以在现代的HTML5 Canvas中我们使用一些现成的第三方类库帮助我们多快好省的实现图形绘制的功能:
KineticJS
Paper.js
EaselJS
Fabric.js
oCanvas
Echart.js
做web大概有八年的时间,今天主要给新手想要做HTML5开发的新手简单说下HTML5能做为什么以及未来的发展和一个系统的学习规划,目前HTML5有多火,不用我说大家都清楚,很多其他行业想转行做HTML5开发,想要在以后有一个好的发展前景,HTML5技术的不断的成熟,各大浏览器不断兼容HTML5最新技术,HTML5被称为可以改变人们生活的东西。而现在HTML5的竞争也是非常的大,所以说我想要做HTML5开发一定要先把技术学好才能去找工作。
HTML5都能做什么?
第一:刚出现不久的小程序,很流行,在开发的过程,HTML5技术就会应用的很多。
第二:移动端是HTML5不可缺少的技术,现在都是移动端的市场,人们手机的一些功能,缓存,音乐,视频,地位,Canvas绘图还有大量的特效,好看的效果,都是不可能离开HTML5技术。
第三:现手游的火爆程度,PC端游戏受到了冲击,比如LOL被王者荣耀冲击,这是时代的变化,HTML5可以做手机游戏,前景光明。
第四:互联网的各种应用,在如今变化多端的互联网,好像任何东西都仿佛离不开了HTML5的技术。
下面我说下HTML5的学习路线:
第一阶段:HTML+CSS+JS
第一阶段要学习基础的静态布局,HTML+CSS,特别提出一定要下功夫攻破JS,JS是最难的,也是前端开发的工资标准,见过很多人学不懂JS,因为JS的逻辑非常强,要跟着大量的案例进行学习,学习JS方法非常重要,很多在学的时候感觉没有效率是没有良好的学习方案
第二阶段:HTML5+CSS3+JQ
了解HTML5新特性,CSS3新属性,换句话说HTML5就是另一个,我上面说的,如果JS学不好,HTML5也很难,本HTML5要和JS完美的配合,而JQ是JS框架,只要原生JS掌握的不错,学习JQ不是难事。
第三阶段:主流框架
前端框架是我们必须要学习的,每一个公司都会用到,但是框架学起来不容易,这些框架都是用原生JS封装的,再一次强调一下JS的重要性,只要一直做前端永远都不会离开JS,就是需要JavaScript,所以一定要学好JavaScript,一个好的学习方法非常重要。
刚接触HTML5的新伙伴多了解这些行情才是学习HTML5开发的关键,找到一个有效率的学习方式才是最重要的,方法不对在努力也是白费,少走弯路就是学习HTML5开发的捷径,前端我做开发将近十年,这些懂得还是很多,有不懂的问题随时可以请教我,下面有我的HTML5新手学习裙,对于学习方法,学习效率,以后行业发展的都可以问我,群里也有很多比较精品的HTML5学习视频免费分享给新人,希望新手少走弯路。
tml5文件分割上传解决方案
html5提供的文件API中可以轻松的对文件进行分割切片, 然后通过javascript异步处理向服务器传输数据, 突破对大文件上传的限制, 同时异步处理在一定程度上也提高了文件上传的效率。用户体验上也优于前述方案。
index.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>大文件上传实例</title>
<script type="text/javascript">
const BYTES_PER_CHUNK=1024 * 1024; // 每个文件切片大小定为1MB .
var slices;
var totalSlices;
//发送请求
function sendRequest() {
var blob=document.getElementById('file').files[0];
var start=0;
var end;
var index=0;
// 计算文件切片总数
slices=Math.ceil(blob.size / BYTES_PER_CHUNK);
totalSlices=slices;
while(start < blob.size) {
end=start + BYTES_PER_CHUNK;
if(end > blob.size) {
end=blob.size;
}
uploadFile(blob, index, start, end);
start=end;
index++;
}
}
//上传文件
function uploadFile(blob, index, start, end) {
var xhr;
var fd;
var chunk;
xhr=new XMLHttpRequest();
xhr.onreadystatechange=function() {
if(xhr.readyState==4) {
if(xhr.responseText) {
alert(xhr.responseText);
}
slices--;
// 如果所有文件切片都成功发送,发送文件合并请求。
if(slices==0) {
mergeFile(blob);
alert('文件上传完毕');
}
}
};
chunk=blob.slice(start,end);//切割文件
//构造form数据
fd=new FormData();
fd.append("file", chunk);
fd.append("name", blob.name);
fd.append("index", index);
xhr.open("POST", "upload.php", true);
//设置二进制文边界件头
xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
xhr.send(fd);
}
function mergeFile(blob) {
var xhr;
var fd;
xhr=new XMLHttpRequest();
fd=new FormData();
fd.append("name", blob.name);
fd.append("index", totalSlices);
xhr.open("POST", "merge.php", true);
xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
xhr.send(fd);
}
</script>
</head>
<body>
<input type="file" id="file"/>
<button onclick="sendRequest()">上传</button>
</body>
</html>
upload.php
<?php
//省略了文件接收判断isset部分
//当前目录下建立一个uploads文件夹
//接收文件名时进行转码,防止中文乱码。
$target="uploads/" .iconv("utf-8","gbk",$_POST["name"]) . '-' . $_POST['index'];
move_uploaded_file($_FILES['file']['tmp_name'], $target);
// Might execute too quickly.
sleep(1);
?>
merge.php
<?php
//文件合并
$target="uploads/" .iconv("utf-8","gbk",$_POST["name"]);
$dst=fopen($target, 'wb');
for($i=0; $i < $_POST['index']; $i++) {
$slice=$target . '-' . $i;
$src=fopen($slice, 'rb');
stream_copy_to_stream($src, $dst);
fclose($src);
unlink($slice);
}
fclose($dst);
关键函数stream_copy_to_stream()
int stream_copy_to_stream ( resource $source , resource $dest [, int $maxlength=-1 [, int $offset=0 ]] )
<?php
$src=fopen('http://www.example.com', 'r');
$dest1=fopen('first1k.txt', 'w');
$dest2=fopen('remainder.txt', 'w');
echo stream_copy_to_stream($src, $dest1, 1024) . " bytes copied to first1k.txt\n";
echo stream_copy_to_stream($src, $dest2) . " bytes copied to remainder.txt\n";
?>
var blob=document.getElementById('file').files[0];
console.dir(blob);
相关的属性如下:
lastModified: 1511081596000
lastModifiedDate: Sun Nov 19 2017 16:53:16 GMT+0800 (中国标准时间) {}
name: "IMG_20171119_165316.jpg"
size: 4383101
type: "image/jpeg"
slice: ? slice() 用于切割文件
*请认真填写需求信息,我们会在24小时内与您取得联系。