Canvas简介:
是HTML5提供的一种新标签, ie9才开始支持的,Canvas是一个矩形区域的画布,可以用JS控制每一个像素在上面绘画。canvas 标签使用 JavaScript 在网页上绘制图像,本身不具备绘图功能。canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
Canvas主要的使用:
1.游戏:canvas在基于Web的图像显示方面比Flash更加立体、更加精巧,canvas游戏在流畅度和跨平台方面更牛。
2.可视化数据.数据图表话,
3.banner广告:Flash曾经辉煌的时代,智能手机还未曾出现。现在以及未来的智能机时代,HTML5技术能够在banner广告上发挥巨大作用,用Canvas实现动态的广告效果再合适不过。
4.未来=>模拟器:无论从视觉效果还是核心功能方面来说,模拟器产品可以完全由JavaScript来实现。
5.未来=>远程计算机控制:Canvas可以让开发者更好地实现基于Web的数据传输,构建一个完美的可视化控制界面。
6.未来=>图形编辑器:Photoshop图形编辑器将能够100%基于Web实现。
7.其他可嵌入网站的内容(多用于活动页面、特效):类似图表、音频、视频,还有许多元素能够更好地与Web融合,并且不需要任何插件。
8.完整的canvas移动化应用
使用:
第一步:获得上下文=>canvasElem.getContext('2d');
第二步:开始路径规划=>ctx.beginPath()
第三步:移动起始点=>ctx.moveTo(x, y)
第四步:绘制线(矩形、圆形、图片...) =>ctx.lineTo(x, y)
第五步:闭合路径=>ctx.closePath();
第六步:绘制描边=>ctx.stroke();
案例:
说明:需要根据画框坐标(x,y,w,h)在图片中画出矩形,框出异常物品。
js的使用:输入图片地址,画框坐标,展示图片及画框。
测试:
<!DOCTYPE html>
<html>
<head>
<title>画布canvas测试</title>
<style>
body{
text-align: center;
}
#view{
/* height: 500px;
width: 500px; */
/* canvas的宽度和高度设置在标签内,否则线条会变粗颜色变淡 */
/* background-color: antiquewhite; */
border: 1px red solid;
}
#canvasDiv{
background-color:aqua;
width: 50%;
height: 200px;
}
#canvasDiv2{
background-color:aqua;
width: 50%;
height: 200px;
margin-top: 20px;
margin-left: 50%;
}
</style>
</head>
<body>
<div id="canvasDiv"></div>
<div id="canvasDiv2"></div>
</body>
<script type="text/javascript" src="canvas.js"></script>
<script type="text/javascript">
var localBox = [];
localBox.push({src:"http://images.cnblogs.com/cnblogs_com/html5test/359114/r_test.jpg",
rects:[{x:300,y:180,w:100,h:50},{x:100,y:30,w:100,h:50}]});
var localBox2 = [];
localBox2.push({src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp0.qhimg.com%2Ft018be05be3045a6e22.jpg&refer=http%3A%2F%2Fp0.qhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1616853256&t=02be9936cbb0105d7104f3bb22338032",
rects:[{x:600,y:90,w:400,h:500},{x:200,y:60,w:100,h:50}]});
localBox.push({src:"http://oss.straituav.com/nodeUpload/nest_81_foreignbody.jpg",
rects:[{x:400,y:600,w:400,h:400},{x:1200,y:800,w:500,h:500}]});
var config = {
lineWidth:3, // 画框线粗细
strokeStyle:"rgb(121, 245, 57)" // 画框线颜色
}
var config2 = {
lineWidth:3, // 画框线粗细
strokeStyle:"red" // 画框线颜色
}
foundCanvas.prepareCanvas(localBox,"canvasDiv");
foundCanvas.prepareCanvas(localBox2,"canvasDiv2",config2);
</script>
</html>
canvas.js
var foundCanvas = (function(){
var localBox = [];
// 创建画布
function _createCanvas(boxList, id, config){
// 判断标签容器是否存在
if(!document.getElementById(id)) {
console.log(`标签id:${id},不存在`);
return
}
var div = document.getElementById(id);
var list = JSON.parse(JSON.stringify(boxList));
var divSize = {
w: div.offsetWidth/list.length, // 返回元素的总宽度
h: div.offsetHeight/(list.length)// 返回元素的总高度
}
// 创建canvas标签
for(var i=0;i<list.length;i++){
var canvas = document.createElement('canvas');
var canvasId = "canvas" + i+"_"+id;
canvas.id= canvasId;
div.appendChild(canvas);
var img = document.getElementById(canvasId);
img.style.padding = "2px 2px";
_initCanvas(divSize,list[i],canvasId,config);
}
};
// 初始化 显示画布
function _initCanvas(divSize, localBox, id, config){
const pointArray = [];
const history = [];
let mousedown = null;
let dragging = false;
var boxList = Object.assign({}, localBox);
var conv=document.getElementById(id);
var ctx=conv.getContext("2d");
var imgwidth; // 图片宽度
var imgheight; // 图片高度
var imgObj = new Image(); // 创建image对象
imgObj.src = boxList.src;
imgObj.onload = function(){
// 设置画布大小
imgwidth = imgObj.width;
imgheight = imgObj.height;
document.getElementById(id).width = divSize.w;
document.getElementById(id).height = divSize.h;
// this即是imgObj
ctx.drawImage(this, 0, 0, divSize.w, divSize.h);
boxList = _calculateSize(divSize, boxList, imgwidth, imgheight);
_drawOldRecs(boxList.rects, config);
};
// 计算比例尺寸显示适配
function _calculateSize(divSize, boxList, imgwidth, imgheight){
var widthImgCanvasPercentage; // 宽度比例
var heightImgCanvasPercentage; // 高度比例
let subWidth = divSize.w / imgwidth;// 算出显示比例
let subHeight = divSize.h / imgheight
widthImgCanvasPercentage = subWidth.toString();
heightImgCanvasPercentage = subHeight.toString();
boxList.rects.forEach(function (element) { // 计算显示尺寸并适配显示
element.x = Math.round(element.x * widthImgCanvasPercentage);
element.y = Math.round(element.y * heightImgCanvasPercentage);
element.w = Math.round(element.w * widthImgCanvasPercentage);
element.h = Math.round(element.h * heightImgCanvasPercentage);
});
return boxList;
};
// 画框
function _drawOldRecs(rects, config) {
if (rects.length == 0) {
return;
}
for (var i = 0; i < rects.length; i++) {
ctx.beginPath();
ctx.lineWidth = config.lineWidth;
ctx.strokeStyle = config.strokeStyle;
ctx.strokeRect(rects[i].x, rects[i].y, rects[i].w, rects[i].h);
// ctx.fillText("异物01", rects[i].x, rects[i].y); // 画框上加文字
}
};
};
// js入口,监听屏幕
function _prepareCanvas(boxList, id, config){
localBox = JSON.parse(JSON.stringify(boxList));
_delCanvas(boxList, id);
var conf = _isConfig(config);
_createCanvas(boxList, id, conf);
// 执行一次
window.addEventListener('load', function() {
// 窗口改变执行
window.addEventListener('resize', function() {
localBox = JSON.parse(JSON.stringify(boxList));
_delCanvas(boxList, id);
// 重新创建画布
_createCanvas(localBox, id, conf);
})
})
};
// 判断是否配置
function _isConfig(config){
var conf = {};
// 配置判断
if(config && config != ""){
conf = Object.assign({}, config);
}else{
conf = {
lineWidth:3, // 画框线粗细
strokeStyle:"rgb(121, 245, 57)" // 画框线颜色
}
}
return conf;
};
// 删除画布canvas标签
function _delCanvas(boxList,id){
localBox = JSON.parse(JSON.stringify(boxList));
// 判断标签容器是否存在
if(!document.getElementById(id)) {
console.log(`标签id:${id},不存在`);
return;
}
// 删除画布
var div = document.getElementById(id);
var canvasCount = div.getElementsByTagName("canvas");
if(canvasCount.length>0){
for(var i=0; i<localBox.length; i++){
document.getElementById("canvas"+i+"_"+id).remove();
}
}
};
return {
prepareCanvas:_prepareCanvas
};
})();
export default foundCanvas;