共计 27433 个字符,预计需要花费 69 分钟才能阅读完成。
前言
html5Canvas 的知识点,是程序员开发者必备技能,在理论工作中也经常会波及到。
最近熬夜总结 html5Canvas 相干的知识点,大家一起看一下吧:
1.html5Canvas 基础知识
- Canvas,它是画布
- Canvas 元素用于在网页上绘制 2D 图形和图像
Canvas 应用的场景有:1,动画;2,H5 游戏;3,图表。
成果动画,加载 Loading:
H5 游戏成果:
对于 Canvas 须要把握:
- 应用 Canvas 画 直线,矩形,圆形 以及设置它们的款式。
- Canvas 中的 图形变换,突变,文字和图片。
- Canvas 的 像素获取,暗影和曲线绘制以及区域的剪辑。
- Canvas动画,交互和离屏 技术。
应用 Canvas 画根本图形
- Canvas 的坐标体系
- 应用 Canvas 画直线,矩形,圆形
- 为圆形设置款式
Canvas 坐标体系
- canvas 默认大小,300*150
- 通过 HTML,css,JavaScript 设置 width 和 height 的区别
- HTML 和 JavaScript 设置的画布大小
- css 设置的是画布缩放后的大小
- 坐标系原点及方向(原点在左上角,向右为 x 方向,向下为 y 方向)
画直线,矩形和原型
- 画直线:
ctx.moveTo(x1,y1),ctx.lineTo(x2,y2)
- 画圆形:
ctx.arc(x,y,radius,0,Math.PI*2,true)
- 画矩形:能够通过直线来画,也能够间接用(
ctx.strokeRect(x1,y1,x2,y2
)
beginPath 和 closePath
- beginPath 和 closePath并不是成对呈现的
- beginPath 的作用是 开始一条新门路
- closePath 的作用是 使以后门路闭合
描边和填充款式
- strokeStyle 用来设置画笔款式,也就是 直线,曲线,边框的款式
- fillStyle 用来设置 填充款式
- lineWidth 用来设置线条的粗细
Canvas 中的图形变换,突变,文字和图片
- Canvas 中的图像变换
- Canvas 中的突变
- Canvas 中的文字
- Canvas 中的图片
Canvas 中的图形变换
图形变换都是针对坐标系来说的:
- 平移:
ctx.translate(x,y)
- 旋转:
ctx.rotate(rad)
- 缩放:
ctx.scale(x,y)
save 和 restore
用来保留和复原上下文的环境 ctx,个别成对呈现
ctx.save()
,保留以后上下文环境。ctx.restore()
,复原到上一次的上下文环境
Canvas 中的突变
- 线性突变:
ctx.createLinearGradient(xStart,yStart,xEnd,yEnd)
(xStart,yStart)
是线段的终点,(xEnd,yEnd)
是线段起点。终点到起点之间的色彩呈突变。
gradient.addColorStop
能够来管制突变的色彩- 突变能够了解为一种色彩
- 径向突变:
ctx.createRadialGradient(xStart,yStart, radiusStart,xEnd,yEnd,radiusEnd);
(xStart,yStart)
是第一个圆的原心,radiusStart
是第一个圆的半径,(xEnd,yEnd)
是第二个圆的原心,radiusEnd
是第二个圆的半径
第一圆到第二个圆之间的色彩出现突变。
Canvas 中的文字
描边文字:ctx.strokeText(text,x,y)
填充文字:ctx.fillText(text,x,y);
设置字体款式:ctx.font
- 例如:
ctx.font="bold 100px sans-serif"
- 设置程度对齐形式:
ctx.textAlign
- left,start,左对齐,center 居中对齐,end,right,右对齐
设置垂直对齐形式:ctx.textBaseline
- top,顶对齐,middle,居中,bottom,底部对齐
- 计算文本宽度:
ctx.measuerText(text).width
须在设置字体款式之后计算
Canvas 图片
绘制图片 3 种办法
ctx.drawImage(image,x,y)
,该办法把图片绘制在(x,y)
处ctx.drawImage(image,x,y,w,h)
,该办法把图片绘制在(x,y)
处,并缩放为宽 w, 高 hctx.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)
,该办法把图片中(sx,sy)
处的宽 sw,高 sh 的区域,绘制到(dx,dy)
处,并缩放为宽dw
,高dh
在 image 加载实现之后绘制:
示例:
var img = new Image();
img.src = 'logo.png';
img.onload = function() {ctx.drawImage(img,0,0,40,40,0,0,80,80);
}
Canvas 绘制
- Canvas 的图形绘制和像素获取
- Canvas 暗影绘制
- Canvas 剪辑区域
- Canvas 曲线绘制
Canvas 图形画刷
ctx.createPattern
能够创立一个画刷模式,进而能够设置到 fillStyle 里,进行画刷的填充。
- 函数原型:
ctx.createPattern(image,type)
type 取值:
no-repeat
不平铺repeat-x
橫方向平repeat-y
纵方向平铺repeat
全方向平铺
Canvas 像素操作
- 获取像素
var imageData = ctx.getImageData(x,y,w,h)
返回的是一维数组:[r1,g1,b1,a1,r2,g2,b2,a2...]
- 设置像素
ctx.putImageData(imageData,x,y)
把 imageData 放在 (x,y) 处
- 设置像素
ctx.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyW, dirtyH)
只显示(dirtyX,dirtyY)处的宽 dirtyW,dirtyH 的区域
Canvas 暗影绘制
ctx.shadowOffsetX:
暗影 x 方向的偏移间隔ctx.shadowOffsetY:
暗影 y 方向的偏移间隔ctx.shadowColor:
暗影的色彩ctx.shadowBlur:
暗影的含糊半径
效果图:
Canvas 剪辑区域
- 设置一个门路;
- 调用 ctx.clip();
- 再绘制图形。
Canvas 绘制曲线
狐线:
context.arc(x,y,radius, starAngle,endAngle, anticlockwise)
圆心(x,y) 半径 radius
从 starAngle 到 endAngle
anticlockwise 代表是否逆时针方向
生成工具
Canvas Quadratic Curve Example
http://blogs.sitepointstatic….
http://blogs.sitepointstatic….
二次样条曲线:
context.quadraticCurveTo(qcpx,qcpy, qx,qy)
贝塞尔曲线:
context.bezierCurveTo(cp1x,cp1y, cp2x, cp2y, x,y)
- Canvas 动画,Canvas 离屏技术
ctx.clearRect(x,y, width,height)
革除 (x,y)
点起,宽 width, 高 height 的区域,用于从新绘制
离屏技术是什么:通过在离屏 Canvas 中绘制元素,再复制到显示 Canvas 中,从而大幅提高性能的一种技术。
应用离屏技术:
- 动态场景绘制特地耗资源,动静场景绘制简略。为了不每次更新动静场景的时候,都去绘制动态场景。
- 个别把动态场景绘制在离屏 canvas 上,更新动静场景的时候,把动态场景 copy 过去,而不是从新绘制。
离屏技术:
一个 Canvas 中的图形绘制到另一个 Canvas 办法:
ctx.drawImage(canvas,x,y), 该办法把 canvas 绘制在 (x,y) 处
ctx.drawImage(canvas,x,y, w,h), 该办法把 canvas 绘制在 (x,y) 处,并缩放为宽 w, 高 h
ctx.drawImage(canvas, sx, sy, sw, sh, dx, dy, dw, dh),该办法把 canvas 中(sx, sy)处的宽 sw, 高 sh 的区域,绘制到 (dx,dy) 处,并缩放为宽 dw, 高 dh
对 canvas 插件的相干理解
什么是 Canvas 插件,把握 Chart.js 插件,理解 Chartist.js 和 HighCharts.js 插件
(图表)Chart.js 插件:https://www.chartjs.org/
Chartist.js 插件是一个简略的响应式图表插件:反对 SVG 格局(http://gionkunz.github.io/cha…)
HighCharts.js 插件:方便快捷的 HTML5 交互性图标库:https://www.highcharts.com/
Chartist.js 插件与 HighCharts.js 插件
- Chartist.js 配置简略,css 和 JavaScript 拆散,响应式图表,反对不同的浏览器尺寸和分辨率。
- HighCharts.js,兼容当今所有的浏览器,蕴含 iPhone,IE,火狐等。
响应式布局,它的用户体验敌对,响应式网站能够依据不同终端,不同尺寸和不同应用环境,主动调整界面布局,展现内容,提供十分好的视觉效果。响应式布局就是一个网站可能兼容多个终端
2. 构建 Canvas 元素
示例:
<style>
#canva {border: 1px solid red;}
</style>
<div>
<canvas id="canva" width="200" height="200"></canvas>
// 绘制宽高 200 的 canvas
</div>
- 应用 JavaScript 实现绘图的流程
在开始绘图时,先要获取 Canvas 元素的对象,在获取一个绘图的上下文。
获取 Canvas 对象 , 应用 document 对象的 getElementById()办法获取。
var canvas = document.getElementById("canvas")
能够应用通过标签名称来获取对象的 getElementsByTagName 办法
- 创立二维的绘图上下文对象
应用 getContext()办法来获取
var context = canvas.getContext("2d")
- 在 Canvas 上绘制文字
context.font="98px 黑体"; // 文字款式
context.fillStyle="red"; // 文字色彩
context.textAlign = "center"; // 文字对齐形式
// 绘制文字
context.fillText("达达前端",100, 123, 234);
绘制图像:
应用 drawImage()办法能够将图像增加到 Canvas 画布中,绘制一幅图像,须要有三个重载的办法:
应用:
drawImage(image, x, y)
// 在画布上定位图像
// 办法在画布上绘制图像、画布或视频。// 办法也可能绘制图像的某些局部,以及 / 或者减少或缩小图像的尺寸。drawImage(image, x, y, width, height)
// 在画布上定位图像,并规定图像的宽度和高度
drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight)
// 剪切图像,并在画布上定位被剪切的局部
参数:
参数 | 形容 |
---|---|
image | 规定要应用的图像,画布或视频 |
sourceX | 开始剪切的 x 坐标地位 |
sourceY | 开始剪切的 y 坐标地位 |
sourceWidth | 被剪切图像的宽度 |
sourceHeight | 被剪切图像的高度 |
destX | 在画布上搁置图像的 x 坐标地位 |
destY | 在画布上搁置图像的 y 坐标地位 |
destWidth | 要应用的图像的宽度 |
destHeight | 要应用的图像的高度 |
插入图像:
function Draw() {
// 获取 canvas 对象
var canvas = document.getElementById("canvas");
// 获取 2d 上下文绘图对象
var context = canvas.getContext("2d");
// 应用 Image()构造函数创立图像对象
var newImg = new Image();
// 指定图像的文件地址
newImg.src = "../images/dadaqianduan.jpg";
newImg.onload = function () {
// 左上角开始绘制图像
context.drawImage(newImg, 0, 0);
context.drawImage(newImg, 250, 100, 150, 200);
context.drawImage(newImg, 90, 80, 100, 100, 0, 0, 120, 120);
}
}
在 Canvas 中绘制文字“达达前端”:
// canvas 宽高 200
<canvas id="canvas" width="200" height="200"></canvas>
<style type="text/css">
canvas {border: 2px solid #ccc;}
</style>
<script>
// 获取 canvas
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// 设置字体
context.font="98px 黑体";
// 填充
context.fillStyle="#036";
// 文本程度地位
context.textAlign="center";
// 执行绘制
context.fillText("达达前端",100, 120, 200);
</script>
3. 绘制矩形
两个办法:
- strokeRect() – 矩形边框
- fillRect() – 填充矩形区域
- strokeStyle – 设置线条的色彩
- lineWidth – 设置线条宽度,默认宽度为 1,单位是像素
- fillStyle – 设置区域或文字的 填充色彩
绘制矩形边框,应用 strokeStyle 办法:
// 绘制矩形边框
strokeRect(x,y, width, height);
填充矩形区域,应用 fillRect()办法:
// 填充矩形区域
fillRect(x,y,width,height);
绘制矩形
// 绘制矩形
function drawRect() {var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// 描边
context.strokeStyle = "#000";
// 线条宽度
context.lineWidth = 1;
// 矩形边框
context.strokeRect(50,50, 150, 100);
// 填充
context.fillStyle="#f90";
// 矩形
context.fillRect(50,50,150,100);
}
window.addEventListener("load",DrawRect,true);
应用 clearRect 办法,能够擦除指定的矩形区域:
// 擦除指定的矩形区域
context.clearRect(x,y,width,height)
4. 体验 canvas 绘图
在理论开发中,画布是默认 300*150 的大小。
示例:
// 为画布设置边框
canvas {border: 1px solid #ccc;}
// 筹备画布,默认是 300*150
// 设置画布的大小
<canvas width="1200" height="800"></canvas>
// 筹备绘制工具
<script>
// 获取元素
var myCanvas = document.querySelector('canvas');
// 获取上下文,绘制工具箱
var ctx = myCanvas.getContext('2d');
// 挪动画笔
ctx.moveTo(100,100);
// 绘制直线,轨迹
ctx.lineTo(200,100);
// 描边
ctx.stroke()
创立 Canvas 元素
向 HTML5 页面增加 canvas 元素
// 规定元素的 id、宽度和高度
<canvas id="myCanvas" width="200" height="100"></canvas>
图形绘制
须要了解些概念:
- 门路的概念
-
门路的绘制
- 描边
stroke()
- 填充
fill()
- 描边
-
闭合门路
- 手动闭合
- 程序闭合
closePath()
- 开启新的门路
beginPath()
设置款式
-
画笔的状态
- lineWidth 线宽,默认
1px
- lineCap 线末端类型:
(butt 默认)、round、square
- lineJoin 相交线的拐点
miter(默认)、round、bevel
- strokeStyle 线的色彩
- fillStyle 填充色彩
setLineDash()
设置虚线getLineDash()
获取虚线宽度汇合lineDashOffset
设置虚线偏移量(负值向右偏移)
- lineWidth 线宽,默认
矩形绘制
rect(x,y,w,h)
没有独立门路strokeRect(x,y,w,h)
有独立门路,不影响别的绘制fillRect(x,y,w,h)
有独立门路,不影响别的绘制clearRect(x,y,w,h)
擦除矩形区域
圆弧绘制
- 弧度概念
-
arc()
- x 圆心横坐标
- y 圆心纵坐标
- r 半径
startAngle
开始角度endAngle
完结角度anticlockwise
是否逆时针方向绘制(默认 false 示意顺时针;true 示意逆时针)
绘制文本
ctx.font
= ‘ 微软雅黑 ’ 设置字体strokeText()
-
fillText(text,x,y,maxWidth)
- text 要绘制的文本
- x,y 文本绘制的坐标(文本左下角)
- maxWidth 设置文本最大宽度,可选参数
-
ctx.textAlign
文本程度对齐形式,绝对绘制坐标来说的- left
- center
- right
- start 默认
- end
-
ctx.direction
属性css(rtl ltr) start 和 end
于此相干- 如果是
ltr,start 和 left
体现统一 - 如果是
rtl,start 和 right
体现统一
- 如果是
-
ctx.textBaseline
设置基线(垂直对齐形式)- top 文本的基线处于文本的正上方,并且有一段距离
- middle 文本的基线处于文本的正中间
- bottom 文本的基线处于文本的证下方,并且有一段距离
- hanging 文本的基线处于文本的正上方,并且和文本粘合
- alphabetic 默认值,基线处于文本的下方,并且穿过文字
- ideographic 和 bottom 类似,然而不一样
measureText()
获取文本宽度 obj.width
绘制图片
-
drawImage()
-
三个参数
drawImage(img,x,y)
- img 图片对象、canvas 对象、video 对象
- x,y 图片绘制的左上角
-
五个参数
drawImage(img,x,y,w,h)
- img 图片对象、canvas 对象、video 对象
- x,y 图片绘制的左上角
- w,h 图片绘制尺寸设置(图片缩放,不是截取)
-
九个参数
drawImage(img,x,y,w,h,x1,y1,w1,h1)
- img 图片对象、canvas 对象、video 对象
- x,y,w,h 图片中的一个矩形区域
- x1,y1,w1,h1 画布中的一个矩形区域
-
坐标变换
-
平移 挪动画布的原点
translate(x,y)
参数示意挪动指标点的坐标
-
缩放
scale(x,y)
参数示意宽高的缩放比例
-
旋转
rotate(angle)
参数示意旋转角度
5. 应用门路
- lineTo()
- rect()
- arc()
- fill()
- stroke()
创立绘图门路
应用办法:beginPath()和 closePath()
,别离示意开始一个新的门路和敞开以后的门路
- 应用 beginPath()办法创立一个新的门路
- moveTo(x,y),开始绘图时的坐标
- lineTo(x,y),绘制直线到指标坐标
- arc(x,y, radius, startAngle,endAngle, counterclockwise)
- x,y 形容弧的圆形的圆心坐标
- radius 圆形的半径
- startAngle 形容弧的开始点的角度
- endAngle 形容弧的完结点的角度
- counterclockwise,true 值,示意逆时针方向,否则反之
rect(x,y, width, height)
:xy, 终点坐标,矩形的宽高,绘制矩形门路
closePath 办法敞开以后门路
绘制图形款式
stokeStyle
属性设置矩形边框的色彩lineWidth
属性设置边框的宽度fillStyle
属性设置填充的色彩
绘制网格,网格大小
var grid = 10;
// 画多少条 x 轴方向的线,横向的条数,画布的高度
var canvasHeight = myCanvas.height
var canvasWidth = myCanvas.width
// 画布宽高
ctx.canvas.width
ctx.canvas.height
// 网格大小
var gridSize = 10;
var canvasHeight = ctx.canvas.height;
var xLineTotal = canvasHeight / gridSize
// 总线条
var xLineTotal = Math.floor(canvasHeight / gridSize);
for (var i=0; i<=xLineTotal; i++) {ctx.beginPath();
ctx.moveTo(0, i*gridSize-0.5);
ctx.lineTo(canvasWidth, i*gridSize-0.5);
ctx.strokeStyle='#eee';
ctx.stroke();}
// 画多少条 y 轴方向的线
var yLineTotal = canvasWidth / gridSize
var yLineTotal = Math.floor(canvasWidth / gridSize);
for (var i=0; i <= yLineTotal; i++) {ctx.beginPath();
ctx.moveTo(i*gridSize-0.5,0);
ctx.lineTo(i*gridSize-0.5,canvasHeight);
ctx.strokeStyle='#eee';
ctx.stroke();}
绘制坐标系,确定圆点,确定离画布旁边的间隔,确定坐标轴的长度,确定箭头的大小,绘制箭头填充。
// 绘制坐标系
var space = 20;
var arrowSize = 10;
// 画布宽高
var canvasWidth = ctx.canvas.width;
var canvasHeight = ctx.canvas.height;
// 坐标系
var x0 = space;
var y0 = canvasHeight - space;
// 绘制 x 轴
ctx.moveTo(x0,y0);
ctx.lineTo(canvasWidth-space, y0);
ctx.stroke();
// 箭头
ctx.lineTo(canvasWidth-space-arrowSize, y0 + arrowSize/2);
ctx.lineTo(canvasWidth-space-arrowSize, y0 - arrowSize/2);
ctx.lineTo(canvasWidth-space, y0);
ctx.fill();
ctx.stroke();
// 绘制 y 轴
ctx.beginPath();
ctx.moveTo(x0, y0);
ctx.lineTo(space, space);
ctx.stroke();
// 箭头
ctx.lineTo(space+space-arrowSize/2, space + arrowSize);
ctx.lineTo(space-space-arrowSize/2, space - arrowSize);
ctx.lineTo(space, space);
ctx.fill();
ctx.stroke();
// 绘制点
var coordinate = {
x: 146,
y: 356
}
// 点尺寸
var dottedSize = 6;
ctx.moveTo(coordinate.x - dottedSize/2, coordinate.y - dottedSize/2);
ctx.lineTo(coordinate.x + dottedSize/2, coordinate.y - dottedSize/2);
ctx.lineTo(coordinate.x + dottedSize/2, coordinate.y + dottedSize/2);
ctx.lineTo(coordinate.x - dottedSize/2, coordinate.y + dottedSize/2);
ctx.closePath();
ctx.fill();
arc 办法和 rect 办法
arc 创立一个圆形,rect 创立一个矩形,最初调用 stroke()办法和 fill()办法
// 圆形
context.arc(100,100,30,0,Math.PI*2,true);
应用 beginPath()办法能够新创建一个子门路,closePath()办法用来闭合门路的。
绘制两条直线
function DrawLine() {var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// 创立绘制过程
context.beginPath();
context.moveTo(50,50);
context.lineTo(120,120);
context.lineTo(120,60);
context.closePath();
context.strokeStyle="#000";
// 执行绘制
context.stroke();}
- beginPath() 办法开始一条门路,或者重置以后的门路
- closePath() 办法创立从以后点到开始点的门路
如果不必 beginPath()
办法,绘制图形时不再创立子门路,第一次的图形在执行过程中会被绘制填充两次。
图形组合
属性 globalCompositeOperation
设置如何在画布上组合色彩
12 中组合类型:
值 | 阐明 |
---|---|
copy | 只绘制新图形,删除其余所有内容 |
darker | 在图形重叠的中央,色彩由两个色彩值相减后决定 |
destination-atop | 已有的内容只在它和新的图形重叠的中央保留,新图形绘制在内容后 |
destination-in | 在新图形和已有画布重叠的中央,已有内容都保留,所有其余内容成为通明 |
destination-out | 在新图形和已有内容不重叠的中央,已有内容保留所有其余内容成为通明 |
destination-over | 新图形绘制于已有内容的前面 |
lighter | 在图形重叠的中央,色彩由两种色彩值的叠加值来决定 |
source-atop | 只在新图形和已有内容重叠的中央才绘制新图形 |
source-in | 在新图形和已有内容重叠的中央,新图形才会被绘制,所有其余内容成为通明 |
source-out | 只在和已有图形不重叠的中央绘制新图形 |
source-over | 新图形绘制于已有图形的顶部 |
xor | 在重置和失常绘制的其余中央,图形都成为通明 |
绘制曲线
// 圆形,曲线
arc(x, y, radius, startAngle, endAngle, counterclockwise);
x,y
示意弧的圆形的 圆心坐标radius
示意弧的圆形的 半径startAngle
示意圆弧的 开始点的角度endAngle
示意圆弧的 完结点的角度counterclockwise
若 true 示意逆时针,false 反之顺时针
<style>
// 画布背景色彩
#canvas {background: #000;}
</style>
// 画布宽度 400
<canvas id="canvas" width="400" height="400">
<script>
var canvas = document.getElementById('canvas');
var context= canvas.getContext('2d')
// 开始
context.beginPath();
// 绘制圆形
context.arc(100, 100, 50, 0, Math.PI*2, true);
// 敞开
context.closePath();
// 填充色彩
context.fillStyle = 'rgb(255,255,255)';
context.fill();
</script>
如果应用 css
设置宽高,画布会依照 300*150
的比例进行缩放,将 300*150
的页面显示在 400*400
的容器中。
// 设置画布宽度
var cx = canvas.width = 400;
var cy = canvas.height = 400;
应用 js 动静设置宽高。
倡议应用 HTML 中的 width 和 height,或者 js 动静设置宽高
创立一个 canvas 标签,第一步:
// 获取这个 canvas 的上下文对象
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
办法:
fill()
填充门路stroke()
描边arc()
创立圆弧rect()
创立矩形fillRect()
绘制矩形门路区域strokeRect()
绘制矩形门路描边clearRect()
在给定的矩形内革除指定的像素beginPath()
起始一条门路,或重置以后门路moveTo()
把门路挪动到画布中的指定点,不创立线条lineTo()
增加一个新点,在画布中创立从该点到最初指定点的线条clip()
从原始画布剪切任意形态和尺寸的区域arcTo()
创立两切线之间的弧 / 曲线quadraticCurveTo()
创立二次方贝塞尔曲线bezierCurveTo()
创立三次方贝塞尔曲线isPointInPath()
如果指定的点位于以后门路中,则返回 true,否则返回 false
辅助线绘制弧线:arcTo()
办法
语法:
// 辅助线绘制弧线
arcTo(x1, y1, x2, y2, radius)
arcTo()办法绘制一条弧线
代码:
// 绘制一条弧线
function draw() {var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// 开始绘制
context.beginPath();
// 挪动点
context.moveTo(80, 120);
// 绘制线条
context.lineTo(150, 60);
context.lineTo(180, 130);
// 描边
context.strokeStyle="rgba(0,0,0,0.4)";
context.lineWidth=2;
context.stroke();
context.beginPath();
context.moveTo(80,120);
context.arcTo(150,60,180,130,50);
context.strolkeStyle="rgba(255,135,0,1)";
context.stroke();}
绘制二次样条曲线
quadraticCurveTo()
办法:
quadraticCurveTo(cpX, cpY, x, y);
// cpX, cpY 形容了控制点的坐标,x, y 形容了曲线的起点坐标
绘制贝济埃曲线
bezierCurveTo()
办法:它是利用于二维图形应用程序的数学曲线。
bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, x, y);
// cp1X, cp1Y 示意第一个控制点的坐标
// cp2X, cp2Y 示意第二个控制点的坐标
// x, y 示意曲线的起点坐标
绘制曲线:
function draw() {
// 绘制曲线
var canvas = document..getElementById('canvas');
var context = canvas.getContext('2d');
// 开始绘制
context.beginPath();
// 挪动
context.moveTo(100,180);
// 连线
context.lineTo(110,80);
context.moveTo(260,100);
context.lineTo(300,200);
// 描边
context.strokeStyle="rgba(0,0,0,0.4)";
// 设置宽度
context.lineWidth=3;
context.stroke();
context.beginPath();
context.moveTo(100,180);
// 绘制贝济埃曲线
context.bezierCurveTo(110,80,260,100,300,200);
// 设置宽度
context.lineWidth = 3;
context.strokeStyle="rgba(255,135,0,1)";
context.stroke();}
四分之一圆
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// 画布宽度 200
var canX = canvas.width = 200
var canY = canvas.height = 200;
// 开始绘制
context.beginPath();
// 四分之一圆
context.arc(100, 100, 50, 0, Math.PI*0.5, false);
context.strokeStyle="white"
context.stroke();
context.beginPath();
context.lineTo(200, 200);
context.lineTo(200, 100);
context.lineTo(100,50);
context.strokeStyle = '#fff';
context.stroke();
lineCap
设置或返回线条的 完结断点款式lineJoin
设置或返回 两条线相交时,产生拐角类型lineWidth
设置或返回 以后的线条宽度miterLimit
设置或返回 最大斜接长度
fillRect()
绘制一个实心矩形strokeRect()
绘制一个空心矩形
设置暗影,shadowBlur
–context.shadowBlur
= 20
createLinearGradient()
创立 线性突变createPattern()
在指定的方向上反复指定的元素createRadialGradient()
创立 放射状 / 环形的突变addColorStop()
规定突变对象中的 色彩和进行地位
gradient.addColorStop(stop,color)
scale()
缩放以后绘图变大或变小rotate()
旋转以后绘图translate()
从新映射画布的 (0,0) 地位
6. 应用图像
应用三种办法插入图像
function draw() {var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// image 实例
var newImg = new Image();
newImg.src='../images/dada.jpg' // 指定图像的文件地址
newImg.onload = function(){
// 绘图
context.drawImage(newImg, 0, 0);
context.drawImage(newImg, 250,100, 150,200);
context.drawImage(newImg, 90,80,100,100,0,0,120,120);
}
}
在插入图像之前,须要思考 图像加载的工夫 ,如果图像没加载实现就曾经执行 drawImage() 办法,就不会显示任何图片。
7. 绘制突变
提供了两种突变的创立的办法:
// 创立线性突变
createLinearGradient()办法
// 创立径向突变
createRadialGradient()办法
设置突变色彩和过渡形式
语法如下:
- offset 是一个范畴在 0.0 到 1.0 之间的浮点值
示意突变的开始点和完结点之间的一部分
- offset 的 0 为开始点,1 为完结点
addColorStop(offset, color);
绘制线性突变的矩形
function draw() {var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')
// 创立突变对象,线性突变
var grd = context.createLinearGradient(0,0,300,0)
// 设置突变色彩
grd.addColorStop(0, '#xxx'); // 设置色彩
grd.addColorStop(1, '#xxx'); // 设置色彩
// 将填充款式设置为线性突变对象
context.fillStyle = grd;
context.fillRect(0,0,300,80);
}
绘制径向突变的矩形
function draw() {var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')
// 径向突变
var grd = context.createRadialGradient(50,50,0,100,100,90);
// 设置突变色彩以及形式
grd.addColorStop(0,'#xxx');
grd.addColorStop(1,'#xxx');
context.fillStyle = grd;
context.beginPath();
// 圆形
context.arc(100,100,90,0,Math.PI*2,true);
context.fill();}
描边属性
线帽属性:lineCap
,示意 指定线条的末端如何绘制
值:lineCap: butt, round, square
,当线条具备肯定的宽度能力体现进去。
butt
// 定义了线段没有线帽
round
// 定义了线段的末端为一个半圆形的线帽
square
// 定义了线段的末端为一个矩形的线帽
线条的连贯属性lineJoin
,用于两条线条到的连贯形式:
miter
两条线段的外边缘始终延长到它们相交,属性 miterLimit 是用来形容如何绘制两条线段的交点,是示意延长长度和线条长度的比值。
默认为 10,只有 miter
应用时无效
lineJoin = [value];
round
// 两条线段的外边缘应该和一个填充的弧联合
bevel
// 两条线段的外边缘应该和一个填充的三角形相交
8. 模式
语法如下:
createPattern(image, repetitionStyle)
repeat
示意图像在各个方向上循环平铺repeat-x
示意图像在横向上循环平铺repeat-y
示意图像在纵向上循环平铺no-repeat
示意图像只应用一次
function draw() {var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')
var img = new Image();
// 应用 Image()构造函数创立图像对象
img.src='../images/xxx'
// 指定图像的文件地址
img.onload = function() {
// 绘图模式
var ptrn = context.createPattern(img, 'repeat');
// 填充款式
context.fillStyle = ptrn;
// 填充矩形
context.fillReat(0,0,500,200);
}
}
挪动变动:
// 挪动
translate(dx,dy);
// 绘制
function draw() {var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')
// 设置挪动偏移量
context.translate(200, 200);
// 绘制一个圆形
ArcFace(context);
}
// 绘制一个圆形
function ArcFace(context) {
// 绘制一个圆形边框
context.beginPath();
// 绘制圆形
context.arc(0,0,90,0,Math.PI*2,true);
// 线宽
context.lineWidth=5;
// 描边
context.strokeStyle='#f90';
context.stroke();
// 绘制
context.beginPath();
context.moveTo(-30, -30);
context.lineTo(-30, -20);
context.moveTo(30, -30);
context.lineTo(30, -20);
context.moveTo(-20, 30);
// 曲线
context.bezierCurveTo(-20, 44, 20, 30, 30, 20);
context.strokeStyle='#000';
context.lineWidth=10;
context.lineCap = 'round';
// 笑脸????
context.stroke();}
缩放变换,语法如下:
scale(sx, sy);
// sx 为程度方向上的缩放因子,sy 为垂直方向上的缩放因子
// 示例
function draw() {var canvas = document.getElementById('canvas')
var context = canvas.getContent('2d')
// 挪动
context.translate(200,200);
// 缩放
context.scale(0.5,0.5);
ArcFace(context);
}
旋转变换:
rotate(angle)
// 旋转例子
function draw() {var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d')
context.translate(200,200);
// 旋转
context.rotate(Math.PI/6);
context.scale(0.5, 0.5)
ArcFace(context)
}
矩形变形,语法如下:
transform(m1x,m1y,m2x,m2y,dx,dy); // 挪动,缩放,旋转
1. 挪动 translate (dx, dy)
2. 缩放 scale (sx,sy)
3. 旋转 rotate (A)
9. 应用文本
绘制文本的办法:
fillText(text, x, y, maxwidth)
strokeText(texxt, x, y, maxwidth)
text
示意要绘制的文本- 参数 x 示意绘制文字的 终点横坐标
- 参数 y 示意绘制文字的 终点纵坐标
- 参数
maxwidth
示意显示文本的最大宽度
文本属性表:
属性 | 阐明 |
---|---|
font | 数组字体款式 |
textAlign | start,end,left,right,center |
textBaseline | top,hanging,middle,alphabetic,ideographic,bottom |
绘制文本
// 绘制文本示例
function draw() {var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')
// 填充色彩
context.fillStyle = '#000';
context.font = 'bold 12px impact';
// 绘制文本
context..fillText('达达前端,魔王哪吒', 10, 10);
context.strokeStyle = '#000';
context.font = 'bold italic 12px impact';
// 绘制文本
context.strokeText('jeskson', 10, 10);
}
绘制获取文本宽度的 measureText()
办法:
measureText(text)
测量文本的宽度:
function draw() {var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle='#000';
context.font='bold 10px impact';
// 测量文本的宽度
var tm = context.measureText(txt);
context.fillText(txt,10,10);
context.fillText(tm.width, tm.width+10, 50);
context.strokeStyle = '#000';
context.font = 'bold italic 10px impact';
// 测量文本的宽度
tm = context.measureText(txt);
context.strokeText(txt,10,10);
context.strokeText(tm.width, tm.width+10, 100);
}
暗影成果
暗影属性表:
属性 | 阐明 |
---|---|
shadowColor | 应用半透明色彩 |
shadowOffsetX | 暗影的横向位移量 |
shadowOffsetY | 暗影的纵向位移量 |
shadowBlur | 高斯含糊 |
状态保留和复原
- 状态保留办法
save()
- 状态复原办法
restore()
,复原最初一次保留的状态
状态的保留和复原是 通过数据栈进行的
10. 操作像素
- 图像数据对象
ImageData
- 获取图像数据的办法
getImageData()
,用于从Canvas
上下文中获取图像数据。getImageData(sx, sy, sw, sh);
- 绘制图像数据的办法
putImageData()
getImageData(imagedata,dx,dy[,..])
- 创立图像数据的办法
createImageData()
绘制海报
<template>
<view class="backgroundColor">
// 画布
<canvas class="isCan" canvas-id="dadaPoster" :style="{width: cansWh.cansWidth +'px', height: cansWh.cansHeight +'px'}"></canvas>
// 效果图
<image class="showImg" mode="aspectFit" v-if="tempImgShow" @longpress="longpress" :src="tempImg"></image>
// 按钮
<view v-if="tempImgShow" class="fixedBox flex flex-direction">
<view class="boxTop text-white"> 长按图片发送给敌人 </view>
<view class="boxDown">
<button class="flexBtn" hover-class="btnHover" @click="closeCans"> 敞开 </button>
</view>
</view>
</view>
</template>
data() {
return {
tempImgShow: false,
tempImg: '',
cansWh: { // 画布宽高
cansWidth: 800,
cansHeight: 900,
},
qrcode: { // 举例二维码
top: 0.85,
left: 0.035,
width: 0.23,
qrHeight: null,
},
...
productImg: { // 产品图
top: 0.1,
left: 0.03,
width: 1,
height: 0.5,
},
};
},
// 绘制图
drawImg(method,param){return new Promise((resolve, reject)=>{if(param.url.indexOf('http') === 0){
uni.downloadFile({
url: param.url,
success(res) {
param.url = res.tempFilePath
method(param).then(res=>{resolve(res)
}).catch(err=>{reject(err)
})
},
fail(error) {console.log(error)
}
})
}else{method(param).then(res=>{resolve(res)
}).catch(err=>{reject(err)
})
}
})
}
// 绘制圆形
drawCircle(param) {
var that = this,x = param.x,y = param.y,r = param.r,url = param.url;
return new Promise((resolve, reject) => {x = Math.ceil(that.cansWh.cansWidth * x);
y = Math.ceil(that.cansWh.cansHeight * y);
r = r > 1 ? r : Math.ceil(that.cansWh.cansWidth * r);
that.ctx.save();
var d = 2 * r;
var cx = x + r;
var cy = y + r;
that.ctx.arc(cx, cy, r, 0, 2 * Math.PI);
that.ctx.clip();
that.ctx.drawImage(url, x, y, d, d);
that.ctx.restore();
that.ctx.draw(true, res=>{resolve();
});
});
}
// 绘制图
drawPic(item) {return new Promise((resolve, reject) => {
let x, y, w, h, r;
y = item.sTop <= 1 ? this.cansWh.cansHeight * item.sTop : item.sTop;
w = item.sWidth <= 1 ? this.cansWh.cansWidth * item.sWidth : item.sWidth;
h = item.sHeight <= 1 ? this.cansWh.cansHeight * item.sHeight : item.sHeight;
if (item.sLeft == 'center') {x = item.sWidth <= 1 ? this.cansWh.cansWidth * (0.5 - item.sWidth / 2) : this.cansWh.cansWidth * 0.5 - item.sWidth /
2;
} else {x = this.cansWh.cansWidth * item.sLeft;}
if (item.r) {
r = item.r;
this.ctx.save();
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
this.ctx.beginPath();
this.ctx.moveTo(x + r, y);
this.ctx.arcTo(x + w, y, x + w, y + h, r);
this.ctx.arcTo(x + w, y + h, x, y + h, r);
this.ctx.arcTo(x, y + h, x, y, r);
this.ctx.arcTo(x, y, x + w, y, r);
this.ctx.closePath();
this.ctx.clip();
this.ctx.drawImage(item.url, x, y, w, h);
this.ctx.restore(); // 返回上一状态} else {this.ctx.drawImage(item.url, x, y, w, h);
}
this.ctx.draw(true, res=>{resolve();
});
});
}
// 保留
saveCans() {
let tempRatio = 1;
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: this.cansWh.cansWidth * tempRatio,
height: this.cansWh.cansHeight * tempRatio,
destWidth: this.cansWh.cansWidth * tempRatio * 2,
destHeight: this.cansWh.cansHeight * tempRatio * 2,
canvasId: 'dadaPoster',
success: (res) => {
this.tempImg = res.tempFilePath;
setTimeout(() => {this.tempImgShow = true;}, 100);
uni.hideLoading();},
fail: (res) => {console.log(res);
uni.hideLoading();}
},
);
}
小结
canvas 标签的应用
// canvas 标签的应用
<canvas width="100" height="100"></canvas>
// 获取 canvas
var canvas = document.getElementById('target')
if(canvas.getContext) {var ctx = canvas.getContext('2d');
}else {alert('该浏览器版本过低,请更换')
}
// 矩形
fillRect(x , y , width , height) // 填充
strokeRect(x , y , width , height) // 空心
clearRect(x, y , width , height) // 革除通明
var grd = ctx.createLinearGradient(x1 ,y1 ,x2 ,y2); // 线性突变
var grd = ctx.createRadialGradient(x1 ,y1 ,r1 ,x2 ,y2 ,r2);// 径向突变
曲线
- 二次贝塞尔曲线
quadraticCurveTo(cp1x, cp1y , x ,y)
(cp1x,cp1y) 控制点 (x,y)完结点
- 三次贝塞尔曲线
bezierCurveTo(cp1x, cp1y ,cp2x , cp2y ,x , y)
(cp1x,cp1y)控制点 1 (cp2x,cp2y) 控制点 2 (x,y)完结点
HTML5 绘图制作海报
<body>
<img src="img/bg.png" id="img1" style="display: block" width="1200" height="800" />
<img src="img/dada.png" id="img2" style="display: block" width="100" height="100" />
<img id="img3" />
<button onclick="draw()" id="btn"> 点击下载 </button>
<script>
function draw() {var img1 = document.getElementById("img1"),
var img2 = document.getElementById("img2"),
var img3 = document.getElementById("img3");
var img1.width = 1200;
var img1.height = 800;
var img2.width = 100;
var img2.height = 100;
var canvas = document.createElement("canvas"),
context = canvas.getContext("2d");
// 绘制宽度
canvas.width = img1.width;
// 绘制高度
canvas.height = img1.height;
/**
* context.drawImage(image,x,y,w,h)
* var img=new Image(); img.src="url(...)";
* x: 绘制图像的 x 坐标
* y: 绘制图像的 y 坐标
* w: 绘制图像的宽度
* h: 绘制图像的高度
*/
context.drawImage(img1, 0, 0, img1.width, img1.height);
// 将 img2 退出画布
context.drawImage(img2, 100, 100, img2.width, img2.height);
// 文字填充色彩
context.fillStyle = '#333';
// 文字字体
context.font = 'bold 45px 黑体';
// 设置文字
var name_text = '达达前端,魔王哪吒';
// 获取文字的宽度
var name_width = context.measureText(name_text).width;
// 获取除去文本后的一半的宽度
var x = (canvas.width - name_width) / 2;
/**
* context.font: 设置字体款式
* context.textAlign: 程度对齐形式
* context.textBaseline: 垂直对齐形式
* context.measureText(text): 计算字体长度(px)
*/
context.fillText(name_text, x, 450);
context.fillStyle = '#333'; // 文字填充色彩
context.font = '25px bold 黑体';
var con_1 = 'dadaqianduan';
var con_2 = '达达';
/**
* text: 要绘制的文字
* x: 文字终点的 x 坐标轴
* y: 文字终点的 y 坐标轴
*/
context.fillText(con_1, x, 400);
var con_width_2 = context.measureText(con_2).width;
context.fillText(con_2, canvas.width - x - con_width_2, 400);
context.stroke();
// 将画布内容导出
var src = canvas.toDataURL();
img3.src = src;
const a = document.createElement("a");
a.href = src;
a.download = '自定义.png';
a.click();}
</script>
</body>
html5 绘图操作(html2canvas)
script 引入文件
html2canvas(content, { //content 是将要截图的 div 元素
scale: 2,
logging: false, // 在 console 中输入信息
useCORS: true // 容许跨域
//proxy: string, // 代理地址
//timeout: number // 超时工夫
}).then(function(canvas) {let dataUrl = canvas.toDataURL()
console.log(dataUrl)
})
crossOrigin
属性设置成 Anonymous
就能够跨域? – 并不能够的哦!
- 后盾解决跨域问题
- 转成
base64
格局(后端,前端,倡议前端)
html5 挪动端生成海报
大抵成果:
<script>
var code_model = '<div id="qrcode"style="position: fixed; opacity: 0;"></div>', // 搁置二维码
canvas_model = '<canvas width="1200"height="800"style="position: fixed;opacity:0;"id="myCanvas"></canvas>', // 搁置 canvas
poster_model = '<div class="poster_container"><div class="poster"><img src="" alt=""class="poster_img"><p class="save_poster"> 长按保留图片至手机相册 </p><p style="margin-top: 0.5rem"class="aaaa"></p></div></div>';
//poster_model 为效果图
$("body").append(code_model, canvas_model, poster_model);
$.ajax({
url: "/photo/dada",
data: {id: id},
success: function (res) {$.hideLoading();
if (res.e = "1111") {if (!res.data.is_buy) {
location.href = res.data.jump_url;
return false;
}
$(".poster").show();
var data_base = res.data.poster_info;
new QRCode('qrcode', {
text: data_base.url,
width: 100,
height: 100,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
});
var c = document.getElementById("myCanvas"),
cxt = c.getContext("2d");
var img = new Image(), imgUrl, personName = data_base.name;
// 跨域问题
img.crossOrigin = 'anonymous';
img.src = data_base.image;
img.onload = function () {
// 图片加载为异步加载
cxt.drawImage(img, 0, 0);
cxt.save();
cxt.beginPath();
cxt.arc(100, 200, 33, 0, 2 * Math.PI, true);
cxt.strokeStyle = '#fff';
cxt.stroke();
cxt.clip();
var img_head = new Image();
img_head.crossOrigin = 'anonymous';
var avatar_height = data_base.avatar_height, avatar_width = data_base.avatar_width;
img_head.src = data_base.avatar;
img_head.onload = function () {cxt.drawImage(img_head, 0, 0, avatar_height, avatar_width, 54, 520, 80, 80);
cxt.restore();
var img_code = new Image();
img_code.crossOrigin = 'anonymous';
cxt.lineWidth = "4";
cxt.strokeStyle = '#FFF';
cxt.rect(80, 80, 400, 400);
cxt.stroke();
setTimeout(function () {img_code.src = $("#qrcode").find("img").attr("src");
img_code.onload = function () {cxt.drawImage(img_code, 0, 0, 100, 100, 450, 450, 80, 80);
cxt.font = '21px 黑体';
cxt.fillStyle = "#000";
cxt.fillText(personName, 250, 520);
imgUrl = c.toDataURL("image/png", 1);
$(".poster_img").attr("src", imgUrl);
$(".poster_container").show();};
}, 0);
};
};
} else {$.toast(res.m, "text");
}
}
});
</script>
微信小程序所应用的绘图 api
CanvasContext
`canvas` 组件的绘图上下文
CanvasContext
是旧版的接口,新版 Canvas 2D
接口与 Web
统一。
string|CanvasGradient fillStyle
– 填充色彩string|CanvasGradient strokeStyle
– 边框色彩number shadowOffsetX
– 暗影绝对于形态在程度方向的偏移number shadowOffsetY
– 暗影绝对于形态在竖直方向的偏移number shadowColor
– 暗影的色彩number shadowBlur
– 暗影的含糊级别number lineWidth
– 线条的宽度string lineCap
– 线条的端点款式string lineJoin
– 线条的交点款式
lineJoin
值 | 阐明 |
---|---|
bevel | 斜角 |
round | 圆角 |
miter | 尖角 |
number miterLimit
– 最大斜接长度number lineDashOffset
– 虚线偏移量,初始值为 0
几个相干的画图 api 点这里
<view class="photoCan">
<canvas style="width: 375px; height: 612px; position:fixed; top:9999px; left:0; z-index:223;" canvas-id="mycanvas"></canvas>
<image src="{{imagePath}}" mode="widthFix"></image>
</view>
const app = getApp()
const setText = (context, fs, color, x, y, c) => {context.setFontSize(fs);
context.setFillStyle(color);
context.setTextAlign('left');
context.fillText(c, x, y);
context.restore();};
Page({
data: {imagePath:''},
onLoad(){
var that=this;
wx.downloadFile({
url: 'https://xxxx.com/image',
success: function (res) {
that.setData({path: res.tempFilePath})
}
})
var ctx = wx.createCanvasContext('mycanvas');
var c_avatar = '../image/timg2.jpg';
var wechat = '../image/wechat.png';
var path = that.data.path;
ctx.fillStyle = "#ffe200";
ctx.fillRect(0, 0, 375, 612);
setText(ctx, 16, '#xxx', 90, 45, ' 达达);
// 绘制画报背景图
ctx.drawImage(path, 30, 95, 400, 500);
// 头像
ctx.arc(45, 45, 25, 0, 2 * Math.PI)
ctx.strokeStyle = "#fff";
ctx.clip();
ctx.drawImage(c_avatar, 20, 20, 50, 50);
// 绘制生成画报
ctx.draw(true, setTimeout(function () {
// 保留
wx.canvasToTempFilePath({
canvasId: 'mycanvas',
success: function (res) {console.log(res)
var tempFilePath = res.tempFilePath;
that.setData({imagePath: tempFilePath});
},
fail: function (res) {console.log(res);
}
})
}, 1000));
}
})
点关注,不迷路
好了各位,以上就是这篇文章的全部内容,能看到这里的人都是人才。我前面会不断更新网络技术相干的文章,如果感觉文章对你有用,欢送给个“赞”,也欢送分享,感激大家!!