Canvas学习系列二:Canvas的坐标系统
上一章内容中我们对canvas元素有了一个初步的认识,在接下来的章节中我们会慢慢学习canvas中图形的绘制;但是在绘制之前我们先来看看canvas中的坐标系统,因为这样我们才能知道绘制的图形放在什么位置。
比如:我们要在canvas画布的(100,100)这个位置绘制一个圆

看到这个要求顿时就懵逼了,(100, 100)在什么地方!!!

至于为什么会懵逼呢?是因为我们不知道canvas的坐标系统,那么我们就赶紧来了解Canvas中的坐标系统吧
在了解canvas坐标系统之前,我们先来看看其他的坐标系统
窗口坐标系统
窗口坐标是我们在Web页面中用到的坐标系统,与我们数学中的直角坐标系统有所不同;
通常窗口坐标系统的原点在屏幕(一般指浏览器)的左上角
直角坐标系统: 直角坐标系统中原点沿x轴向右方向为正值,反之为负值;原点沿y轴向上方向为正值,反之为负值。

窗口坐标系统: 窗口坐标系统与直角坐标系统都含有x轴,y轴,两轴的交点为坐标原点(0,0),原点沿x轴向右方向为正值,不同的是原点沿y轴方向向下为正值。
当然窗口坐标系统也是负值的,只是有些时候会跑到屏幕范围之外,另我们没有看到。

Canvas坐标系统
在canvas绘图环境对象中有一个与2d绘图环境对应的3d绘图环境,叫做WebGL,所以canvas坐标系统中包含3D绘图环境,不过我们现在只说2D绘图环境。
在2D绘图环境中的坐标系统,默认情况下是与窗口坐标系统相同,它以canvas的左上角为坐标原点,沿x轴向右为正值,沿y轴向下为正值。其中canvas坐标的单位都是 "px"。

然而Canvas的坐标系并不是固定的,我们可以对坐标系统进行评议放缩及旋转,我们成为坐标变换
- 平移:(translate)
- 缩放:(scale)
- 旋转:(rotate)
- 自定义变换方式
坐标系统的变换是Canvas中非常基本的功能,在这里我们不做过多的阐述,后面我们会详细讲解坐标系统的变换。

窗口坐标换为canvas坐标
HTML5应用程序是以事件来驱动的,浏览器通过事件对象传递给监听器的坐标是窗口坐标,开发者需要知道发生事件的点相对于canvas的位置,而不是相对于浏览器中的位置,所以必须进行转换
转换方法1:
//坐标转换
function windowToCanvas(canvas, x, y){
var canvasBox = canvas.getBoundingClientRect(); //获取canvas元素的边界框
return {
x: (x - canvasBox.left)*(canvas.width/canvasBox.width), //对canvas元素大小与绘图表面大小不一致时进行缩放
y: (y - canvasBox.top)*(canvas.height/canvasBox.height)
}
}
转换方法2:利用 scrollLeft, clientLeft, offsetLeft属性
function windowToCanvas2(canvas, x, y){
return {
x: x + document.body.scrollLeft - document.body.clientLeft - canvas.offsetLeft,
y: y + document.body.scrollTop - document.body.clientTop - canvas.offsetTop
}
}
利用上述所说窗口坐标转换canvas坐标的方法,我们可以绘制一个鼠标辅助线的例子;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
width: %;
height: %;
display: flex;
justify-content: center;
align-items: flex-start;
}
#canvas {
border: 1px solid darkorange;
}
</style>
</head>
<body>
<canvas id="canvas" width="" height=""></canvas>
<script type="text/javascript">
window.addEventListener('load', loadCanvas);
function loadCanvas(){
var canvas = document.getElementById('canvas');
if(!canvas.getContext){
return;
}
var context = canvas.getContext('2d');
//添加鼠标移动事件
canvas.addEventListener('mousemove', MouseMove); function MouseMove(e){
var location = windowToCanvas2(canvas, e.clientX, e.clientY);
drawLines(location.x, location.y);
} //绘制辅助线
function drawLines(x, y){
context.clearRect(, , context.canvas.width, context.canvas.height);
context.beginPath();
context.moveTo(x, );
context.lineTo(x, context.canvas.height);
context.stroke();
context.beginPath();
context.moveTo(, y);
context.lineTo(context.canvas.width, y);
context.stroke();
context.font = '20pt Arial';
context.fillStyle = 'green';
var text = '(' + parseInt(x)+','+parseInt(y) + ')';
context.fillText(text, , );
}
} //坐标转换
function windowToCanvas(canvas, x, y){
var canvasBox = canvas.getBoundingClientRect(); //获取canvas元素的边界框
return {
x: (x - canvasBox.left)*(canvas.width/canvasBox.width), //对canvas元素大小与绘图表面大小不一致时进行缩放
y: (y - canvasBox.top)*(canvas.height/canvasBox.height)
}
}
//方法2
function windowToCanvas2(canvas, x, y){
return {
x: x + document.body.scrollLeft - document.body.clientLeft - canvas.offsetLeft,
y: y + document.body.scrollTop - document.body.clientTop - canvas.offsetTop
}
}
</script>
</body>
</html>
canvas绘制一个简单的坐标轴
虽然我们还没有学习canvas中图行的绘制,这里只是简单的展示一个例子。后面我们会慢慢学习canvas中图形的绘制,你就觉得绘制会如此的简单。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>坐标轴</title>
<style>
html, body {
margin: ;
padding: ;
}
#canvas {
margin: 100px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
window.onload = function(){
var canvas = document.getElementById('canvas');
canvas.width = '';
canvas.height = '';
if(!canvas.getContext){
alert('当前浏览器不支持canvas');
return;
}
var context = canvas.getContext('2d');
context.translate(,);
//绘制坐标轴的方法
function drawAxis(cxt){
var dx = ,
dy = ,
x = ,
y = ,
w = canvas.width,
h = canvas.height;
cxt.lineWidth = ;
cxt.strokeStyle = "green"; var textX = ;
var textY = ;
//绘制x轴
cxt.moveTo(x, y);
cxt.lineTo(w, y);
cxt.stroke();
//绘制数字
while (dx < w) {
cxt.font = '12pt Arial';
cxt.fillStyle = 'red';
cxt.fillText(textY, dx, );
textY+= ;
dx+=;
} //绘制y轴
cxt.moveTo(x, y);
cxt.lineTo(x, h);
cxt.stroke(); //绘制数字
while (dy < h) {
cxt.font = '12pt Arial';
cxt.fillStyle = 'red';
cxt.fillText(textX, -, dy);
textX+= ;
dy+=;
} }
drawAxis(context);
};
</script>
</body>
</html>
总结:
在我们绘制图形之前,必须要搞清楚canvas的坐标系统,这样才能知道我们具体要在哪里绘制图形。
canvas的2D环境绘图坐标系统,原点(0,0)位于canvas元素的左上角顶点处,沿x轴向右为正值,沿y轴向下为正值,与我们数学中的直角坐标系是不同的,但是与我们的窗口坐标系(web页面的坐标)是相同的
canvas的坐标系统不是一直不变的,我们可以通过坐标变换来改变,后面章节我们会单独说到。
对canvas绘制图形感兴趣的同学,请持续关注后续更新,如有不对的地方也请指出并多多交流。
Canvas学习系列二:Canvas的坐标系统的更多相关文章
- canvas学习(二):渐变与曲线的绘制
canvas学习(二):渐变与曲线的绘制 一:createLinearGradient()线性渐变: 二:createLinearGradient() 放射状/圆形渐变: 三:createPatter ...
- Canvas学习:封装Canvas绘制基本图形API
Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方 ...
- MyBatis学习系列二——增删改查
目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring 数据库的经典操作:增删改查. 在这一章我们主要说明一下简单的查询和增删改, ...
- Maven学习系列二(1-5)
Maven学习系列二(1-5) 本文转自 QuantSeven 博客,讲解精炼易懂,适合入门,链接及截图如下 http://www.cnblogs.com/quanyongan/category/47 ...
- scrapy爬虫学习系列二:scrapy简单爬虫样例学习
系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...
- DocX开源WORD操作组件的学习系列二
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参
[转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...
- RabbitMQ学习系列二-C#代码发送消息
RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...
- .net reactor 学习系列(二)---.net reactor界面各功能说明
原文:.net reactor 学习系列(二)---.net reactor界面各功能说明 安装了.net reactor之后,可以在安装目录下找到帮助文档REACTOR_HELP.c ...
随机推荐
- 【NIO】Java NIO之选择器
一.前言 前面已经学习了缓冲和通道,接着学习选择器. 二.选择器 2.1 选择器基础 选择器管理一个被注册的通道集合的信息和它们的就绪状态,通道和选择器一起被注册,并且选择器可更新通道的就绪状态,也可 ...
- selenium操作拖拽实现无效果的替代方案
如果碰到这种情况,无论你是直接通过draganddrop()还是分步执行clickandhold(),dragtoelement(),或通过by_offset位移都无法实现元素拖拽.只能物理模拟了 w ...
- HTML5 WebGL 实现逼真的云朵效果
使用 HTML5 WebGL 实现超逼真的云朵效果.WebGL 是一项在网页浏览器呈现3D画面的技术,有别于过去需要安装浏览器插件,通过 WebGL 的技术,只需要编写网页代码即可实现3D图像的展示. ...
- 对于Bootstrap的介绍以及如何使用
Bootstrap是HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB 项目. 可以自动适配任何设备,解决了响应式实现的繁琐问题,可以修改其中的各种样式,同样,其内部功能的强 ...
- Nginx 常用配置整理
#定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...
- 如何将网站升级为HTTPS协议?
基本概念: HTTP: 是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准,用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少. HT ...
- [刷题]算法竞赛入门经典(第2版) 5-4/UVa10763 - Foreign Exchange
题意:有若干交换生.若干学校,有人希望从A校到B校,有的想从B到C.C到A等等等等.如果有人想从A到B也刚好有人想从B到A,那么可以交换(不允许一对多.多对一).看作后如果有人找不到人交换,那么整个交 ...
- [大数据]-Elasticsearch5.3.1 IK分词,同义词/联想搜索设置
--题外话:最近发现了一些问题,一些高搜索量的东西相当一部分没有价值.发现大部分是一些问题的错误日志.而我是个比较爱贴图的.搜索引擎的检索会将我们的博文文本分词.所以图片内容一般是检索不到的,也就是说 ...
- git使用命令总结
直接安装git.exegit -- version 查看当前git版本进入要创建库的文件夹 shift+右键 弹出 powerShell 弹出命令窗口 git init 初始化git管理仓库 出现一个 ...
- 【企业级框架整合】Springmvc+mybatis+restful+bootstrap框架整合
1. 使用阿里巴巴Druid连接池(高效.功能强大.可扩展性好的数据库连接池.监控数据库访问性能.支持Common-Logging.Log4j和JdkLog,监控数据库访问)2. 提供高并发JMS消息 ...