canvas入门,就是这个feel!
钙素
Canvas 是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图。也就是说我们将通过JS完成画图而不是css。
canvas 默认布局为 inline-block
,可以认为是一种特殊的图片。
走起 ~
canvas 划线
<canvas id="can" width="800" height="800"></canvas>
(宽高不能放在style里面,否则比例不对)
canvas里面的
width
和height
相当于图片的原始尺寸,加了外部style的宽高,就相当于对图片进行压缩和拉伸。
// 1、获取原生dom对象
let dom = document.getElementById('can');
// 2、获取绘图对象
let can = dom.getContext('2d'); // 3d是webgl
// 定义线条起点
can.moveTo(0,0);
// 定义线条中点(非终点)
can.lineTo(400,400);
can.lineTo(800,0);
// 对标记范围进行描边
can.stroke()
// 对标记范围进行填充
can.fill();
设置线条属性
线条默认宽度是 1
。
(一定要在绘图之前设置。)
can.lineWidth = 2; //设置线条宽度
can.strokeStyle = '#f00'; // 设置线条颜色
can.fillStyle = '#f00'; // 设置填充区域颜色
折线样式
miter
:尖角(当尖角长度值过长时会自动变成折角,如果强制显示尖角:can.miterLimit = 100
设置尖角长度阈值。round
:圆角bevel
:折角
can.lineJoin = 'miter';
can.moveTo(100, 100);
can.lineTo(300, 100);
can.lineTo(100, 200);
can.stroke()
can.lineJoin = 'round';
can.moveTo(400, 100);
can.lineTo(600, 100);
can.lineTo(400, 200);
can.stroke()
can.lineJoin = 'bevel';
can.moveTo(700, 100);
can.lineTo(900, 100);
can.lineTo(700, 200);
can.stroke()
设置线帽
round
:加圆角线帽square
:加直角线帽butt
:不加线帽
can.lineCap = 'round';
can.moveTo(100, 100);
can.lineTo(300, 100);
can.stroke()
// 新建绘图,使得上一次的绘画样式不会影响下面的绘画样式(代码加在上一次绘画和下一次绘画中间。)
can.beginPath()
can.lineCap = 'square';
can.moveTo(100, 200);
can.lineTo(300, 200);
can.stroke()
can.beginPath()
can.lineCap = 'butt';
can.moveTo(100, 300);
can.lineTo(300, 300);
can.stroke()
画矩形
// 参数:x,y,宽,高
can.rect(100,100,100,100);
can.stroke();
// 画完即填充
can.fillRect(100,100,100,100);
画圆弧
// 参数:圆心x,圆心y,半径,圆弧起点与圆心的夹角度数,圆弧终点与圆心的夹角度数,true(逆时针绘画)
can.arc(500,300,200,0,2*Math.PI/360*90,false);
can.stroke()
示例:
can.moveTo(500,300);
can.lineTo(500 + Math.sqrt(100), 300 + Math.sqrt(100))
can.arc(500, 300, 100, 2 * Math.PI / 360 *startDeg, 2 * Math.PI / 360 *endDeg, false);
can.closePath()//将图形起点和终点用线连接起来使之成为封闭的图形
can.fill()
Tips:
1、can.beginPath() // 新建绘图,使得上一次的绘画样式不会影响下面的绘画样式(代码加在上一次绘画和下一次绘画中间。)
2、can.closePath() //将图形起点和终点用线连接起来使之成为封闭的图形。
旋转画布
can.rotate(2*Math.PI/360*45); // 一定要写在开始绘图之前
can.fillRect(0,0,200, 10);
旋转整个画布的坐标系(参考坐标为画布的(0,0)位置)
缩放画布
can.scale(0.5,2);
can.fillRect(0,0,200, 10);
示例:
整个画布:x方向缩放为原来的0.5,y方向拉伸为原来的2倍。
画布位移
can.translate(100,100)
can.fillRect(0,0,200, 10);
保存与恢复画布状态
can.save() // 存档:保存当前画布坐标系状态
can.restore() // 读档:恢复之前保存的画布坐标系状态
需要正确坐标系绘图的时候,再读档之前的正确坐标系。
can.restore() // 将当前的画布坐标系状态恢复成上一次保存时的状态
can.fillRect(dom.width/2, dom.height/2, 300, 100)
指针时钟(案例)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>clock</title>
<style type="text/css">
#can {
width: 1000px;
height: 600px;
background: linear-gradient(45deg, green, skyblue);
}
</style>
</head>
<body>
<canvas id="can" width="2000" height="1200"></canvas>
</body>
<script type="text/javascript">
let dom = document.getElementById('can');
let can = dom.getContext('2d');
// 把画布的圆心移动到画布的中心
can.translate(dom.width / 2, dom.height / 2);
// 保存当前的画布坐标系
can.save()
run();
function run() {
setInterval(function() {
clearCanvas();
draw();
}, 10);
}
// 绘图
function draw() {
let time = new Date();
let hour = time.getHours();
let min = time.getMinutes();
let sec = time.getSeconds();
let minSec = time.getMilliseconds();
drawPannl();
drawHour(hour, min, sec);
drawMin(min, sec);
drawSec(sec, minSec);
drawPoint();
}
// 最简单的方法:由于canvas每当高度或宽度被重设时,画布内容就会被清空
function clearCanvas() {
dom.height = dom.height;
can.translate(dom.width / 2, dom.height / 2);
can.save()
}
// 画表盘
function drawPannl() {
can.beginPath();
can.restore()
can.save()
can.lineWidth = 10;
can.strokeStyle = 'skyblue';
can.arc(0, 0, 400, 0, 2 * Math.PI);
can.stroke();
for (let i = 0; i < 12; i++) {
can.beginPath();
can.lineWidth = 16;
can.strokeStyle = 'greenyellow';
can.rotate(2 * Math.PI / 12)
can.moveTo(0, -395);
can.lineTo(0, -340);
can.stroke();
}
for (let i = 0; i < 60; i++) {
can.beginPath();
can.lineWidth = 10;
can.strokeStyle = '#fff';
can.rotate(2 * Math.PI / 60)
can.moveTo(0, -395);
can.lineTo(0, -370);
can.stroke();
}
}
// 画时针
function drawHour(h, m, s) {
can.beginPath();
can.restore()
can.save()
can.lineWidth = 24;
can.strokeStyle = 'palevioletred';
can.lineCap = 'round'
can.rotate(2 * Math.PI / (12 * 60 * 60) * (h * 60 * 60 + m * 60 + s))
can.moveTo(0, 0);
can.lineTo(0, -200);
can.stroke();
}
// 画分针
function drawMin(m, s) {
can.beginPath();
can.restore()
can.save()
can.lineWidth = 14;
can.strokeStyle = '#09f';
can.lineCap = 'round'
can.rotate(2 * Math.PI / (60 * 60) * (m * 60 + s))
can.moveTo(0, 0);
can.lineTo(0, -260);
can.stroke();
}
// 画秒针
function drawSec(s, ms) {
can.beginPath();
can.restore()
can.save()
can.lineWidth = 8;
can.strokeStyle = '#f00';
can.lineCap = 'round'
can.rotate(2 * Math.PI / (60 * 1000) * (s * 1000 + ms));
can.moveTo(0, 50);
can.lineTo(0, -320);
can.stroke();
}
// 画中心点
function drawPoint() {
can.beginPath();
can.restore()
can.save()
can.lineWidth = 10;
can.fillStyle = 'red';
can.arc(0, 0, 12, 0, 2 * Math.PI);
can.fill();
}
</script>
</html>
圆弧时钟(案例)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>clock</title>
<style type="text/css">
#can {
width: 1000px;
height: 600px;
background: linear-gradient(45deg, rgb(94, 53, 6), black);
}
</style>
</head>
<body>
<canvas id="can" width="2000" height="1200"></canvas>
</body>
<script type="text/javascript">
let dom = document.getElementById('can');
let can = dom.getContext('2d');
// 把画布的圆心移动到画布的中心
can.translate(dom.width / 2, dom.height / 2);
// 保存当前的画布坐标系
can.save();
// 圆形指针起始角度
let startDeg = 2 * Math.PI / 360 * 270;
run();
// draw();
function run() {
setInterval(function() {
clearCanvas();
draw();
}, 20);
}
// 绘图
function draw() {
let time = new Date();
// let hour = time.getHours();
let hour = time.getHours() > 10 ? time.getHours() - 12 : time.getHours();
let min = time.getMinutes();
let sec = time.getSeconds();
let minSec = time.getMilliseconds();
drawPannl();
drawTime(hour, min, sec, minSec);
drawHour(hour, min, sec);
drawMin(min, sec);
drawSec(sec, minSec);
drawPoint();
}
// 最简单的方法:由于canvas每当高度或宽度被重设时,画布内容就会被清空
function clearCanvas() {
dom.height = dom.height;
can.translate(dom.width / 2, dom.height / 2);
can.save()
}
// 画表盘
function drawPannl() {
can.restore()
can.save()
// 设置时表盘
can.beginPath();
can.lineWidth = 50;
can.strokeStyle = 'rgba(255,23,87,0.2)';
can.arc(0, 0, 400, 0, 2 * Math.PI);
can.stroke();
// 设置分表盘
can.beginPath();
can.strokeStyle = 'rgba(169,242,15,0.2)';
can.arc(0, 0, 345, 0, 2 * Math.PI);
can.stroke();
// 设置秒表盘
can.beginPath();
can.strokeStyle = 'rgba(21,202,230,0.2)';
can.arc(0, 0, 290, 0, 2 * Math.PI);
can.stroke();
// 小时刻度
// for (let i = 0; i < 12; i++) {
// can.beginPath();
// can.lineWidth = 16;
// can.strokeStyle = 'rgba(0,0,0,0.2)';
// can.rotate(2 * Math.PI / 12)
// can.moveTo(0, -375);
// can.lineTo(0, -425);
// can.stroke();
// }
// 分针刻度
// for (let i = 0; i < 60; i++) {
// can.beginPath();
// can.lineWidth = 10;
// can.strokeStyle = '#fff';
// can.rotate(2 * Math.PI / 60)
// can.moveTo(0, -395);
// can.lineTo(0, -370);
// can.stroke();
// }
}
// 画时针
function drawHour(h, m, s) {
let rotateDeg = 2 * Math.PI / (12 * 60 * 60) * (h * 60 * 60 + m * 60 + s);
can.beginPath();
can.restore()
can.save()
// 时针圆弧
can.lineWidth = 50;
can.strokeStyle = 'rgb(255,23,87)';
can.lineCap = 'round';
can.shadowColor = "rgb(255,23,87)"; // 设置阴影颜色
can.shadowBlur = 20; // 设置阴影范围
can.arc(0, 0, 400, startDeg, startDeg + rotateDeg);
can.stroke();
// 时针指针
can.beginPath();
can.lineWidth = 24;
can.strokeStyle = 'rgb(255,23,87)';
can.lineCap = 'round'
can.rotate(rotateDeg)
can.moveTo(0, 0);
can.lineTo(0, -100);
can.stroke();
}
// 画分针
function drawMin(m, s) {
let rotateDeg = 2 * Math.PI / (60 * 60) * (m * 60 + s);
can.beginPath();
can.restore()
can.save()
// 分针圆弧
can.lineWidth = 50;
can.strokeStyle = 'rgb(169,242,15)';
can.lineCap = 'round'
can.shadowColor = "rgb(169,242,15)";
can.shadowBlur = 20;
can.arc(0, 0, 345, startDeg, startDeg + rotateDeg);
can.stroke();
// 分针指针
can.beginPath();
can.lineWidth = 14;
can.strokeStyle = 'rgb(169,242,15)';
can.lineCap = 'round'
can.rotate(rotateDeg)
can.moveTo(0, 0);
can.lineTo(0, -160);
can.stroke();
}
// 画秒针
function drawSec(s, ms) {
let rotateDeg = 2 * Math.PI / (60 * 1000) * (s * 1000 + ms);
can.beginPath();
can.restore()
can.save()
can.lineWidth = 50;
can.strokeStyle = 'rgb(21,202,230)';
can.lineCap = 'round'
can.arc(0, 0, 290, startDeg, startDeg + rotateDeg);
can.stroke();
can.beginPath();
can.lineWidth = 8;
can.strokeStyle = 'rgb(21,202,230)';
can.lineCap = 'round'
can.shadowColor = "rgb(21,202,230)";
can.shadowBlur = 20;
can.rotate(rotateDeg);
can.moveTo(0, 50);
can.lineTo(0, -220);
can.stroke();
}
// 画中心点
function drawPoint() {
can.beginPath();
can.restore()
can.save()
can.lineWidth = 10;
can.fillStyle = 'red';
can.arc(0, 0, 12, 0, 2 * Math.PI);
can.fill();
}
// 显示数字时钟
function drawTime(h, m, s, ms) {
can.font = '60px Calibri';
can.fillStyle = '#0f0'
can.shadowColor = "#fff";
can.shadowBlur = 20;
can.fillText(`${h}:${m}:${s}.${ms}`, -140, -100);
}
</script>
</html>
(啾咪 ^.<)
canvas入门,就是这个feel!的更多相关文章
- Canvas入门(2):图形渐变和图像形变换
来源:http://www.ido321.com/986.html 一.图形渐变(均在最新版Google中测试) 1.绘制线性渐变 1: // 获取canvas 的ID 2: var canvas = ...
- Canvas入门(1):绘制矩形、圆、直线、曲线等基本图形
来源:http://www.ido321.com/968.html 一.Canvas的基础知识 Canvas是HTML 5中新增的元素,专门用于绘制图形.canvas元素就相当于一块“画布”,一块无色 ...
- HTML5 canvas入门
HTML5 Canvas入门 <canvas> 标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形.在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字. ...
- canvas入门之时钟的实现
canvas 入门之作: 三步实现一个时钟: 直接上效果: step 1 : 背景制作首先制作从1-12的数字: var canvas = document.getElementById('ca ...
- Canvas 入门案例
五. Canvas 入门案例 1. canvas 圆形绘制 <!DOCTYPE html> <html lang="en"> <head> ...
- Canvas入门笔记-实现极简画笔
今天学习了Html5 Canvas入门,已经有大神写得很详细了http://www.cnblogs.com/tim-li/archive/2012/08/06/2580252.html#8 在学习过后 ...
- canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)
[下篇] -- 建议学习时间4小时 课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...
- canvas学习笔记(中篇) -- canvas入门教程-- 颜色/透明度/渐变色/线宽/线条样式/虚线/文本/阴影/图片/像素处理
[中篇] -- 建议学习时间4小时 课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...
- canvas学习笔记(上篇)-- canvas入门教程 -- canvas标签/方块/描边/路径/圆形/曲线
[上篇] -- 建议学习时间4小时 课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...
- canvas入门(画圆)
1.想在H5上画一个canvas,必须在页面上你需要的地方添加canvas标签, <canvas id="myCanvas"></canvas> 接着需 ...
随机推荐
- SpringBoot 遇到 No identifier specified for entity
No identifier specified for entity 从字面上不难看出来是没有设置主键 因为没有为标注为@Entity的实体类注明主键 import lombok.Data; impo ...
- Java基于回调的观察者模式详解
本文由“言念小文”原创,转载请说明文章出处 一.前言 什么是回调?回调如何使用?如何优雅的使用?本文将首先详解回调的原理,然后介绍回调的基本使用方法,最后介绍基于回调的“观察者模式”实现,演示如何优化 ...
- bash_history文件怎么删除
Bash shell在“~/.bash_history”(“~/”表示用户目录)文件中保存了500条使用过的命令,这样可以使你输入使用过的长命令变得容易.每个在系统中拥有账号的用户在他的目录下都有一个 ...
- Unity事件系统
# 1.前言Unity中事件/委托有着广泛的应用,本文通过封装一个简易的事件的系统,来统一管理消息的传递.此功能在简易应用或者事件较少的体现不出太好的作用,但是对于事件应用较多时,可以减少脚本之间的耦 ...
- 省市区三级联动(vue)
vue项目中使用到三级联动,现在自己实现一个三级联动,仅供大家参考一下,直接上代码. <template> <section class="container"& ...
- Flink中接收端反压以及Credit机制 (源码分析)
先上一张图整体了解Flink中的反压 可以看到每个task都会有自己对应的IG(inputgate)对接上游发送过来的数据和RS(resultPatation)对接往下游发送数据, 整个反压机制通 ...
- 安装实时查看日志工具 log.io
官网:http://logio.org/ 一.环境 [root@centos ~]# cat /etc/system-release CentOS release 6.5 (Final) [root@ ...
- [考试反思]0725NOIP模拟测试8
看清你是个什么东西了么? 现在看清了么?rank#15?垃圾玩意? 你什么也不是.你没有骄傲,偷懒的资格! 节节败退,永无止境,你想掉到什么样子? 你还在为了成功拿到送分的T1而沾沾自喜?只不过是勉强 ...
- 如何实现一个MVVM
说一说我对于mvvm模型的理解吧 我第一次接触mvvm也是在学习vue的时候,在我看来vue和react都是数据驱动视图,但是vue属于标准的mvvm模型,react是从组件化演变而来 不多废话,直接 ...
- .NET手撸绘制TypeScript类图——上篇
.NET手撸绘制TypeScript类图--上篇 近年来随着交互界面的精细化,TypeScript越来越流行,前端的设计也越来复杂,而类图正是用简单的箭头和方块,反映对象与对象之间关系/依赖的好方式. ...