>[success] # 绘制圆弧
![](https://box.kancloud.cn/55f03ffe0f25f78101e070c1243c6ccf_468x406.png)
~~~
1.圆360° 也就是2π 弧度长
2.从右面为起点顺时针转动结尾是2π
3.绘制一个弧需要
确定圆心 坐标 --- x y
确定圆半径 --- r
确定起始绘制的位置和结束绘制的位置 确定弧的长度和位置 startAngle endAngle 弧度
取得绘制的方向 direction 默认是顺时针 false 逆时针 true
~~~
>[danger] ##### 绘制一个弧
~~~
1.半径长度为150,逆时针的圆
~~~
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');
/*绘制圆弧*/
/*确定圆心 坐标 x y*/
/*确定圆半径 r */
/*确定起始绘制的位置和结束绘制的位置 确定弧的长度和位置 startAngle endAngle 弧度*/
/*取得绘制的方向 direction 默认是顺时针 false 逆时针 true */
/*在中心位置画一个半径150px的圆弧左下角*/
var w = ctx.canvas.width;
var h = ctx.canvas.height;
ctx.arc(w/2,h/2,150,Math.PI/2,Math.PI,true);
ctx.stroke();
</script>
</body>
</html>
~~~
>[danger] ##### 绘制一个圆弧
~~~
1.为了能让圆弧闭合 ctx.moveTo(w/2,h/2); 从圆心位置开始
~~~
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');
/*在中心位置画一个半径150px的圆弧右上角 扇形 边 填充 */
var w = ctx.canvas.width;
var h = ctx.canvas.height;
/*把起点放到圆心位置*/
ctx.moveTo(w/2,h/2);
ctx.arc(w/2,h/2,150,0,-Math.PI/2,true);
/*闭合路径*/
//ctx.closePath();
ctx.fill();
</script>
</body>
</html>
~~~
>[success] # 圆弧分割6等分
~~~
1. 要画多个扇形弧度 定义个数 定义可以分成多少个弧度
2. 画弧度通过循环实现,开始的边等i* 平均的弧度,结束i* 平均弧度+1
~~~
>[danger] ##### 代码
![](https://box.kancloud.cn/876489d6da0fe974234f9c1da5bab4a0_542x377.png)
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');
var w = ctx.canvas.width;
var h = ctx.canvas.height;
/*分成几等分*/
var num = 6;
/*一份多少弧度*/
var angle = Math.PI * 2 / num;
/*原点坐标*/
var x0 = w / 2;
var y0 = h / 2;
/*获取随机颜色*/
var getRandomColor = function () {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
/*上一次绘制的结束弧度等于当前次的起始弧度*/
//var startAngle = 0;
for (var i = 0; i < num; i++) {
var startAngle = i * angle;
var endAngle = (i + 1) * angle;
ctx.beginPath();
ctx.moveTo(x0, y0);
ctx.arc(x0, y0, 150, startAngle, endAngle);
/*随机颜色*/
ctx.fillStyle = getRandomColor();
ctx.fill();
}
</script>
</body>
</html>
~~~
>[success] # 计算年龄占比
![](https://box.kancloud.cn/10af48c3dcad195608efcfdc35cbb712_475x386.png)
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');
/*1.绘制年龄占比*/
/*2.准备统计的数据*/
/*15-20岁 6个*/
/*20-25岁 30个*/
/*25-30岁 10个*/
/*30-35岁 8个*/
var data = [6, 30, 10, 8];
/*3.在饼图表示出来*/
/*4.需要把数据转出弧度*/
var angleList = [];
var total = 0;
// 求出总共多少
data.forEach(function (item, i) {
total += item;
});
console.log(total);
/*第二是转换成弧度的时候就可以去绘制扇形 减少一次遍历*/
data.forEach(function (item, i) {
// 算出弧度大小
var angle = Math.PI * 2 * (item/total);
angleList.push(angle);
});
console.log(angleList);
/*5.根据弧度绘制扇形*/
var w = ctx.canvas.width;
var h = ctx.canvas.height;
var x0 = w/2;
var y0 = h/2;
/*获取随机颜色*/
var getRandomColor = function () {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
var startAngle = 0;
angleList.forEach(function (item,i) {
/*上一次绘制的结束弧度等于当前次的起始弧度*/
var endAngle = startAngle + item;
ctx.beginPath();
ctx.moveTo(x0,y0);
ctx.arc(x0,y0,150,startAngle,endAngle);
ctx.fillStyle = getRandomColor();
ctx.fill();
/*记录当前的结束位置作为下一次的起始位置*/
startAngle = endAngle;
});
</script>
</body>
</html>
~~~
>[success] # 做一个完整饼状图
![](https://box.kancloud.cn/2d12280f9e79cd35ca176327bd62141a_679x419.png)
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
canvas {
border: 1px solid #ccc;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
/*var myCanvas = document.querySelector('canvas');
var ctx = myCanvas.getContext('2d');*/
/*1.绘制饼状态图*/
/*1.1 根据数据绘制一个饼图*/
/*1.2 绘制标题 从扇形的弧中心伸出一条线在画一条横线在横线的上面写上文字标题*/
/*1.3 在画布的左上角 绘制说明 一个和扇形一样颜色的矩形 旁边就是文字说明*/
var PieChart = function (ctx) {
/*绘制工具*/
this.ctx = ctx || document.querySelector('canvas').getContext('2d');
/*绘制饼图的中心*/
this.w = this.ctx.canvas.width;
this.h = this.ctx.canvas.height;
/*圆心*/
this.x0 = this.w / 2 + 60;
this.y0 = this.h / 2;
/*半径*/
this.radius = 150;
/*伸出去的线的长度*/
this.outLine = 20;
/*说明的矩形大小*/
this.rectW = 30;
this.rectH = 16;
this.space = 20;
}
PieChart.prototype.init = function (data) {
/*1.准备数据*/
this.drawPie(data);
};
PieChart.prototype.drawPie = function (data) {
var that = this;
/*1.转化弧度*/
var angleList = this.transformAngle(data);
/*2.绘制饼图*/
var startAngle = 0;
angleList.forEach(function (item, i) {
/*当前的结束弧度要等于下一次的起始弧度*/
var endAngle = startAngle + item.angle;
that.ctx.beginPath();
that.ctx.moveTo(that.x0, that.y0);
that.ctx.arc(that.x0, that.y0, that.radius, startAngle, endAngle);
var color = that.ctx.fillStyle = that.getRandomColor();
that.ctx.fill();
/*下一次要使用当前的这一次的结束角度*/
/*绘制标题*/
that.drawTitle(startAngle, item.angle, color , item.title);
/*绘制说明*/
that.drawDesc(i,item.title);
startAngle = endAngle;
});
};
PieChart.prototype.drawTitle = function (startAngle, angle ,color , title) {
/*1.确定伸出去的线 通过圆心点 通过伸出去的点 确定这个线*/
/*2.确定伸出去的点 需要确定伸出去的线的长度*/
/*3.固定伸出去的线的长度*/
/*4.计算这个点的坐标*/
/*5.需要根据角度和斜边的长度*/
/*5.1 使用弧度 当前扇形的起始弧度 + 对应的弧度的一半 */
/*5.2 半径+伸出去的长度 */
/*5.3 outX = x0 + cos(angle) * ( r + outLine)*/
/*5.3 outY = y0 + sin(angle) * ( r + outLine)*/
/*斜边*/
var edge = this.radius + this.outLine;
/*x轴方向的直角边*/
var edgeX = Math.cos(startAngle + angle / 2) * edge;
/*y轴方向的直角边*/
var edgeY = Math.sin(startAngle + angle / 2) * edge;
/*计算出去的点坐标*/
var outX = this.x0 + edgeX;
var outY = this.y0 + edgeY;
this.ctx.beginPath();
this.ctx.moveTo(this.x0, this.y0);
this.ctx.lineTo(outX, outY);
this.ctx.strokeStyle = color;
/*画文字和下划线*/
/*线的方向怎么判断 伸出去的点在X0的左边 线的方向就是左边*/
/*线的方向怎么判断 伸出去的点在X0的右边 线的方向就是右边*/
/*结束的点坐标 和文字大小*/
this.ctx.font = '14px Microsoft YaHei';
var textWidth = this.ctx.measureText(title).width ;
if(outX > this.x0){
/*右*/
this.ctx.lineTo(outX + textWidth,outY);
this.ctx.textAlign = 'left';
}else{
/*左*/
this.ctx.lineTo(outX - textWidth,outY);
this.ctx.textAlign = 'right';
}
this.ctx.stroke();
this.ctx.textBaseline = 'bottom';
this.ctx.fillText(title,outX,outY);
};
PieChart.prototype.drawDesc = function (index,title) {
/*绘制说明*/
/*矩形的大小*/
/*距离上和左边的间距*/
/*矩形之间的间距*/
this.ctx.fillRect(this.space,this.space + index * (this.rectH + 10),this.rectW,this.rectH);
/*绘制文字*/
this.ctx.beginPath();
this.ctx.textAlign = 'left';
this.ctx.textBaseline = 'top';
this.ctx.font = '12px Microsoft YaHei';
this.ctx.fillText(title,this.space + this.rectW + 10 , this.space + index * (this.rectH + 10));
};
PieChart.prototype.transformAngle = function (data) {
/*返回的数据内容包含弧度的*/
var total = 0;
data.forEach(function (item, i) {
total += item.num;
});
/*计算弧度 并且追加到当前的对象内容*/
data.forEach(function (item, i) {
var angle = item.num / total * Math.PI * 2;
item.angle = angle;
});
return data;
};
PieChart.prototype.getRandomColor = function () {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')';
};
var data = [
{
title: '15-20岁',
num: 6
},
{
title: '20-25岁',
num: 30
},
{
title: '25-30岁',
num: 10
},
{
title: '30以上',
num: 8
}
];
var pieChart = new PieChart();
pieChart.init(data);
</script>
</body>
</html>
~~~
- HTML
- Html标签
- canvas绘图
- 直线案例
- 黑到白的渐变矩形
- 制作坐标绘图效果
- 绘制矩形效果
- 绘制字体
- 绘制圆弧
- 图片的绘制
- 坐标的移动
- html5
- html5 --- 兼容问题
- html5 ---页面布局的标签
- html5--- 新增type 属性
- html5 ---input/表单新增的其他元素
- html5---新增的js事件
- html5---新增的进度条标签
- html5---知识点整合案例
- html5 --- 音频视频
- html5---dom和class事件
- html5---自定义属性
- html5---tab切换
- html5--接口
- html5--网络接口
- html5--全屏接口
- html5---读取文档信息
- html5--拖拽
- html5--地图
- html5--数据存储
- html5--视频案例
- html5-css
- css3选择器
- 属性选择器
- 兄弟选择器
- 伪类选择器
- 创建befor-after
- 盒子属性
- 盒子模型
- 盒子圆角
- 盒子阴影
- 盒子颜色的渐变
- 伪元素首字下沉
- 颜色透明度
- 文本阴影
- backgrou 设置
- 过渡动画效果
- 手风琴案例
- 2D效果
- 2D水平移动
- 2D的方大缩放效果
- 2D旋转
- 2D斜切
- 2D旋转扑克牌案例
- 盾牌案例
- 实现居中定位
- 3D效果
- 画一个正方体
- 滚动轮播图
- 帧动画效果
- 无缝滚动效果
- 时钟动画效果
- 字体
- 多列布局
- 弹性盒子布局
- 伸缩布局flex-grow子项填充空白比例
- 设置侧轴的居中方式
- 定义子元素的收缩比例
- 用flex实现子元素比例缩放
- 菜单伸缩案例
- 布局案例
- 携程网案例
- 全屏滚动效果动画
- 手机端
- 流式布局概念
- 手机适配方案
- 通用样式的处理
- 两栏自适应布局
- 手机端js新事件touch
- 左滑右滑方法封装
- 点击事件的封装
- 京东案例
- 完整的代码
- 效果的js代码
- 购物页面案例
- 全部完整css/html
- iscroll--对隐藏容器滚动
- 轮播图插件--swiper
- CSS
- 什么是css
- 常用属性
- 字体选属性
- 样式书写三种方式
- 选择器
- 1.1基础选择器
- 1.1.1谷歌标题案例
- 1.2复合选择器
- 1.2.1新闻布局练习
- 标签选择器
- css三大特性/权重
- 块级元素/内行/内行块
- a标签的5个方式
- 连接导航案例
- 商城图标转换
- 背景属性
- input 框中加图标案例
- 在ul前加图片案例
- 背景案例分析
- 文字行高
- 行高居中案例
- 盒子模型
- 盒子模型边框属性-boder
- input边框案例
- 盒子模型内边距-padding影响盒子大小
- 新浪标题栏
- 盒子模型外边距-margin
- 行内元素/行内块 盒子
- 盒子模型综合案例
- 综合案例一
- 综合案例二
- 综合案例三
- 浮动布局
- 文本绕图
- 制作导航
- 制作导航二
- 浮动布局练习一
- 浮动布局练习二
- 清除浮动
- 同行常用的开头清除
- overflow-溢出
- 定位
- margin-left/right 左右靠
- 定位案例
- 定位案例-关于定位和浮动
- 绝对定位案例
- 定位的盒子居中显示
- 图片和文字居中对齐
- 设置logo图片点击跳转
- css 可见性
- 精灵图
- 滑动门
- css综合案例
- 手机官网案例
- 头部分析
- 内容分析
- 新闻分析
- Js初始
- js-基本语法
- 注释
- 类型
- 数字类型-number
- 字符串类型-string
- 类型转换
- 变量
- 变量交换案例
- 流程控制
- 分支语句
- if-分支语句
- if-else分支语句
- 三元分支语句
- if-else if 分支语句
- switch-case 分支语句
- 分支判断的总结
- 循环语句
- while循环语句
- do-while 循环语句
- do 和 while 区别
- for循环语句
- 经典题目画星星
- 经典题目斐波那契数列
- break--关键字
- continue-关键字
- 操作运算符
- 一个和python 不一样的问题
- 数组
- 循环数组中的数据
- 求数组简单案例
- 冒泡排序
- 函数
- js-全局/局部作用域
- js-匿名函数和命名函数
- js-预解析
- js-回调函数
- js-函数的返回-return
- js-arguments-伪数字统计实参
- js-函数-综合案例
- 对象
- 系统构造函数对象
- 工厂模式创建对象
- 自定义构造函数对象
- 自变量函数对象
- 循环json格式
- 基本类型和引用类型
- 内置对象
- 内置对象-Math
- 内置对象-Date
- 内置对象-String
- 内置对象-Array
- js-操作DOM
- 常见的操作方法
- DOM-入门分析
- Dom-案例
- DOM-案例一
- DOM-案例二
- DOM-node节点操作
- NODE-节点案例
- NODE - 应用案例
- DOM-创建元素
- DOM-点击事件
- DOM-鼠标移动事件
- DOM-百度搜索案例
- DOM-兼容性案例
- DOM-offset 获取位置
- DOM-scroll
- DOM -client可视区域
- js-操作BOM
- 常见的操作
- onload -- 页面加载事件
- BOM--对象
- location--当前 URL 信息
- history -- 控制前进后退
- navigator --- 判断浏览器类型
- setInterval -- 定时器
- setTimeout -- 一次性定时器
- getComputedStyle -- 最强的获取位置
- 轮播图--加速效果案例
- 一、为轮播图做准备工作
- 二、轮播图小试牛刀
- 三、初入佳境点击触发轮播效果
- 四、升级改造无缝轮播
- 五、最后的轮播
- 轮播图--匀速动画案例
- 一、小试牛刀 --- 筋斗云案例
- 二、德艺双馨 -- 手风琴案例
- 三、毁天灭地 -- 开机动画
- 四、一鸣惊人 -- 旋转木马
- 鼠标移动-一系列案例
- onmousedown -- 摁住鼠标移动弹窗
- JS的回调思想
- onmousemove -- 高清放大镜
- onmousemove -- 自定义滚动条
- JS的回调思想
- 回调地狱
- Promise 具体用法
- Js高级
- 一、创建对象的四种方式
- 二、构造函数和实例对象关系
- 三、小试牛刀编写面向对象
- 四、深入了解面向对象
- 五、把局部变量更新成全局
- 六、做一个贪吃蛇
- 七、继承
- 八、函数声明和函数表达区别
- 九、this 指向
- 十、apply 和 call 方法
- 十一、bind 方法
- 十二、常见函数中的成员
- 十三、函数作为参数和返回值
- 十四、闭包
- 十五、沙箱
- 十六、递归
- 十七、赋值、深浅copy
- Jquery
- dom对象和jq对象不同点深入
- 基本选择器 -- 通过css找jq对象
- 基本选着器 -- 条件过滤选择器
- 标签筛选选择器 --- 找儿子爸爸孙子
- 以下案例知识储备
- 下拉菜单案例
- 选中突出展示效果
- 手风琴效果
- 淘宝小广告案例
- jquey -- 对css/class 操作总结
- tab -- 栏切换
- jquery -- 自定义属性 attr/prop
- 利用attr 实现相册点击小图变大
- 利用prop实现全选单选
- juqery -- 显示隐藏/动画效果
- slideDown/slideUp -- 下拉菜单
- fadeIn/fadeOut -- 淡入淡出的轮播效果
- animate -- 手风琴效果
- animate -- 钢琴效果的导航
- jquery -- 创建子节点/兄弟节点
- 左面的内容到右面
- 模仿微博案例
- jquery -- 删除和复制
- 弹幕效果
- jquery -- 获取文本值/焦点
- jquery -- 中的innerHTML /innerText
- jquery -- 获取标签的宽高
- jquery --- scrollTop与scrollLeft
- 固定导航栏
- 点击火箭返回顶部
- jquery --- 获取元素距离document和父类距离
- jquery --- on委托 事件
- 表格删除事件委托
- jquery --- 移除事件
- jquery -- 触发事件
- jquery --- 触发事件
- 钢琴标题代码
- jquey -- 提醒消息显示后在隐藏
- jquery -- 五星好评
- jquery -- each
- jquery -- 更改jq$符号
- jquery --插件
- 正则表达式
- 一、正则表达式练习
- 二、js正则表达式模块
- 二·一、js正则表达式更多用法
- 三、案例验证密码长度
- 四、判断用户输入的是否是邮箱
- 五、验证用户输入是否是中文
- 六、多个表单验证
- 七、常用的正则
- less
- 变量声明
- Mixin--混合使用
- @import --- 引入样式
- 嵌套使用less
- 函数和计算
- less在浏览器端自解析
- less编写案例
- 案例less/html
- 移动端zepto 介绍
- 响应式布局
- Bootstrap
- Bootstrap-栅格系统
- Bootstrap-响应式工具
- 简单菜单案例
- Bootstrap-预定义风格
- 简单的登录案列
- Bootstrap-按钮风格
- 按钮-下拉菜单
- 延迟下拉
- 滑动下拉
- 同步下拉
- Bootstrap-标签页
- 标签页-内容
- Bootstrap-导航条
- 制作导航样式
- 隐藏导航样式
- Bootstrap-轮播图
- Bootstrap-table
- 属性介绍
- 简单后台+前台交互
- 微金所案例
- ajax/jsonp 处理方式
- jquery - ajax 使用
- jq--load
- jsonp--跨域
- 前端模板使用
- 项目案例
- 移动端首页/分类
- 搜索页面
- 搜索列表页
- 商品页
- 用户登录页
- 购物车页
- 编写通用的windows对象js
- 后台管理端
- 登陆页面
- 管理端页面
- 管理端数据展示页面
- Node.js
- 利用node.js 搭建服务器
- 创建简单的服务器连接请求
- 处理静态文件 -- 留言板案例
- npm -- 使用
- Express -- 框架使用
- 规划Express -- 结构目录
- 简单的案例
- NODE配合mongodb
- Vue
- Vue常用指令
- 大胡子语法
- v-text -- 标签内添加内容
- v-html -- 显示标签内容
- v-bind -- 给标签属性绑定内容
- v-model -- 双向绑定数据
- v-for -- 循环用法
- v-on -- 绑定触发事件
- v-if / v-show 显示和隐藏dom
- 事件修饰符
- 样式控制
- 简单案例
- 点击变色
- 最简单的增删改查
- 综合案例增删改查
- 简单的购车案例
- VUE监听和计算watch/computed
- 监听案例
- 模糊查询
- Vue过滤器
- 自定义指令 -- 绑定事件
- VUE生命周期
- Vue异步请求
- VUE-异步请求案例
- Vue动画效果
- VUE创建组件
- 创建全局组件
- 创建局部组件
- 组件中的data 使用
- 利用组件做切换效果显示
- 组件切换动画效果
- 获取dom对象
- 组件传值父传子
- 组件传值子传父/父传子方法
- 评论案例
- 点击显示侧边栏案例
- slot内容分发
- 动态组件
- 使用render 函数渲染组件
- Vue路由映射
- VUE路由映射样式
- VUE获取路由参数
- VUE路由的嵌套
- VUE命名视图
- vuex
- webpack
- webpack.config.js -- 具体配置
- package.json 具体配置
- 在webpack使用Vue
- webpack.config.js -- vue 配置版本
- VUE -- 案例
- 基本配置
- 路由做页面切换
- 创建新闻展示组件
- 图片组件展示效果
- 商品详情页插件
- 轮播图的组件
- number 组件
- 购物车组件
- 配合Vue-cli创建项目
- ##### 伪数组
- 前端 -- 精华篇总结
- HTML--精华
- HTML--标签
- HTML5--标签
- css--基础
- css -- 三大特性
- css--基本选择器
- css--伪类选择器
- css--复合选择器
- css -- 属性选择器
- css -- 伪元素选择器
- 标签元素--块/行内/行内块
- font-- 字体
- text -- 文本
- background -- 背景
- css -- 盒子模型
- css3 -- 盒子模型
- 盒子模型布局遵循
- 文字、盒子水平居中
- 背景和图片的区别
- css -- 浮动
- 常见的布局
- css -- 定位(position)
- 元素的显示与隐藏
- css -- transition过渡动画
- css -- transform2D变形操作
- css -- transform3D变形
- css -- 动画animation
- css -- 常用的篇
- css -- 文字溢出隐藏
- css3 -- flex伸缩布局
- BFC -- 特性
- 精灵图和文字篇
- css -- 前缀
- css -- 经典案例
- 工具篇章