JavaScript 图形接口canvas 学习笔记2

CanvasRenderingContext2D

实例1

<canvas id="myCanvas" style="border: 1px solid red">canvas</canvas>
<button type="button" id="bt" onclick="f()">draw</button>
var c = document.getElementById('myCanvas')
c.height = 250
function f(){
    var ctx = c.getContext('2d',true);  // CanvasRenderingContext2D
    ctx.lineWidth = 10;  // 线宽
    ctx.strokeRect(75,140,150,110);  // 墙
    ctx.fillRect(130, 190, 40, 60);  // 门
    // 屋顶
    ctx.beginPath()
    ctx.moveTo(50,140)
    ctx.lineTo(150,60)
    ctx.lineTo(250,140)
    ctx.closePath()
    ctx.stroke()
}

实例2

var c = document.getElementById('myCanvas')
function f(){
    var ctx = c.getContext('2d',true)
    ctx.strokeStyle = 'yellow'
    ctx.strokeRect(110,110,100,100)
    ctx.fillStyle = 'lightblue'
    ctx.fillRect(5,5,105,105)
    ctx.clearRect(10,10,55,55)
}

绘制矩形

  • clearRect(x,y,width,height):清除矩形
  • fillRect(x,y,w,h):填充矩形
  • strokeRect(x,y,w,h):用当前笔触绘制矩形

绘制文本

  • fillText(text,x,y):绘制文本
  • strokeText(text,x,y):描边文本
  • measureText(text):返回 TextMetrics 对象
var c = document.getElementById('myCanvas')
function f(){
    var ctx = c.getContext('2d',true);
    ctx.font = '22px 楷体';
    ctx.strokeText('hello, 世界',60,60);
    var mea = ctx.measureText('text');
    console.log(mea.width +'; '+ mea.height)
}

线型

  • lineWidth:线宽,默认1.0
  • lineCap:线端样式,butt|round|square(平不出头,圆出头,平不出头)
  • lineJoin:相交线拐点类型:miter|round|bevel(尖|圆|平)
var c = document.getElementById('myCanvas')
function f(){
    var ctx = c.getContext('2d',true);
    ctx.lineWidth = 20;
    ctx.lineCap='butt';
    ctx.lineJoin = 'miter';
    ctx.moveTo(20,20);
    ctx.lineTo(150,120);
    ctx.lineTo(270,30);
    ctx.stroke();
}
  • miterLImit:斜接面限制比例,默认10
  • getLineDash():返回当前线段样式的数组,数组包含一组数量为偶数的非负数数字。
  • setLineDash([len_line,len_blank]):设置当前的线段样式。
  • lineDashOffset(n):描述在哪里开始绘制线段,线条向左偏移。
var c = document.getElementById('myCanvas')
function f(){
    var ctx = c.getContext('2d',true);
    ctx.setLineDash([5,20])
    console.log(ctx.getLineDash())
    ctx.beginPath()
    ctx.moveTo(0,75)
    ctx.lineTo(300,75)
    ctx.stroke();
}
//蚂蚁线
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true);
ctx.setLineDash([4,2])
var offset=0
function draw(){
    ctx.clearRect(0,0,c.width,c.height)
    if (offset>16){
        offset=0
    }
    ctx.lineDashOffset=-offset
    offset++
    ctx.strokeRect(10,10,100,100)
    setTimeout(draw,20)
}
draw()

文本样式

  • font:字体,默认 10px sans-serif
  • textAlign:对齐方式,start|end|left|right|center(左|?|左|?|中间)
  • textBaseline:基线对齐方式,alphabetic|top|hanging|middle|ideographic|bottom,以基线为标准,分别在基线 字母式上部|顶部|底部|中间|底部|底部
  • direction:文本方向,inherit|ltr|rtl
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true);
const baselines = ['top','hanging','middle','alphabetic','ideographic','bottom']
ctx.font='20px 楷体'
ctx.strokeStyle='red'
baselines.forEach(function(baseline,index){
    ctx.textBaseline = baseline
    y = 10 +25*index  // 修改10 25改变距离
    ctx.beginPath()
    ctx.moveTo(10,y+0.5)  // 画布是300x150,留一点padding
    ctx.lineTo(290,y)
    ctx.stroke()
    ctx.fillText('abcdefghijklmn('+baseline+')',10,y)
})

填充和描边样式

  • fillStyle:内部填充色, 默认 #000
  • strokeStyle:边线颜色,默认 #000

渐变和图案

  • createLinearGradient(x1,y1,x2,y2):创建线性渐变
  • createRadianGradirent(x1,y1,r1,x2,y2,r2):放射性渐变
  • createPattern():使用指定的图片 (a CanvasImageSource)创建图案。通过 repetition 变量指定的方向上重复源图片。此方法返回 CanvasPattern对象。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true);
// 线型渐变
var gradient = ctx.createLinearGradient(20,0,220,0)
gradient.addColorStop(0,'red')
gradient.addColorStop(.5,'cyan')
gradient.addColorStop(1,'green')
ctx.fillStyle=gradient
ctx.fillRect(20,20,200,100)
// 辐射渐变
var gradient = ctx.createRadialGradient(120,120,100,120,120,0)
ctx.strokeRect(0,0,200,200)
gradient.addColorStop(0,"white");
gradient.addColorStop(1,"green");
ctx.fillStyle = gradient;
ctx.fillRect(0,0,200,200);
// 图片填充
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true);
var img = new Image()
img.src = 'Eraser.png'
img.onload = function(){
    var pattern = ctx.createPattern(img,'repeat')
    ctx.fillStyle = img
    ctx.fillRect(0,0,280,140)
}

阴影

  • shadowBlur:模糊效果,默认 0
  • shadowColor:阴影颜色,默认 fully-transparent black
  • shadowOffsetX:水平方向偏移量,默认0
  • shadowOffsetY:垂直方向偏移量,默认0
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.shadowBlur = 10
ctx.shadowColor = '#999'
ctx.shadowOffsetX = 10
ctx.shadowOffsetY = 10
ctx.fillRect(10,10,210,110)

路径

  • beginPath():清空路径列表,创建一个新的
  • closePath():闭合图形
  • moveTo(x,y):移动起始点
  • lineTo(x,y):用直线连接至
  • bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y):添加一个3次贝赛尔曲线路径。该方法需要三个点。 第一、第二个点是控制点,第三个点是结束点。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改。
  • arc(x,y,r,stAngle,endAngle,anticlockwise):顺、逆时针绘制指定角度、半径的圆弧
  • arcTo(x1,y1,x2,y2,r):使用当前的描点(前一个moveTo或lineTo等函数的止点)。根据当前描点与给定的控制点1连接的直线,和控制点1与控制点2连接的直线,作为使用指定半径的圆的切线,画出两条切线之间的弧线路径。
// 根据圆心、角度、半径画圆弧
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.beginPath()
ctx.arc(100,100,80,-Math.PI/3,Math.PI/3,false)
ctx.stroke()
// 根据两点、半径画圆弧
ctx.beginPath();
ctx.moveTo(150, 20);
ctx.arcTo(150,100,50,20,30);
ctx.stroke();
  • ellipse(x,y,rX,rY,rotation,stAngle,endAngle,anticlockwise):根据圆心、长短轴长、角度、方向绘制圆弧
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.beginPath()
ctx.ellipse(100, 100, 50, 75, 45 * Math.PI/180, 0, 2 * Math.PI); //倾斜45°角
ctx.stroke()
  • rect(x,y,w,h):根据左上角坐标和长宽绘制矩形

绘制路径

  • fill(path, fillRule):可省path或两者,fillRule=nonezero|evenodd(非零|奇偶环绕原则)。
  • stroke(path):使用非零环绕规则,根据当前的画线样式,绘制当前或已经存在的路径,参数选填。
  • drawFocusNeeded(path, element):用来给当前路径或特定路径绘制焦点的方法,如果给定的元素获取了焦点,可省path或两者,element是元素。
  • scrollPathIntoView(path):将当前或给定的路径滚动到窗口,path可省。
  • clip(path, fillRule):将当前创建的路径设置为当前剪切路径。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.arc(100,100,75,Math.PI*2,false)
ctx.clip()
ctx.fillRect(0,0,200,200)判断在当前路径中是否包含检测点
  • isPointPath(path,x,y,fillRule):判断在当前路径中是否包含检测点,path、fillRule或两者可省。
  • isPointInStroke(path,x,y):检测某点是否在路径的描边线上,path可省。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.rect(10,10,110,110)
console.log(ctx.isPointInPath(11,11))
console.log(ctx.isPointInStroke(10,10))

变换

  • currentTransform
  • rotate(angle=degree*Math.PI/180):将画布顺时针旋转一个角度。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.rotate(45*Math.PI/180)
ctx.rect(70,20,100,30)
ctx.stroke()
  • scale(x,y):将画布x,y方向缩放相应倍数。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.scale(10,5)
ctx.fillStyle = 'red'
ctx.fillRect(10,10,8,8)
ctx.setTransform(1,0,0,1,0,0)
ctx.fillStyle = 'gray'
ctx.fillRect(10,10,8,8)
  • translate(x,y):将画布沿着x,y方向平移相应像素。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d',true)
ctx.translate(50,50)
ctx.fillRect(0,0,100,100)
  • transform(a,b,c,d,e,f):参数为 水平缩放|垂直倾斜|水平倾斜|垂直缩放|水平移动|垂直移动。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d')
const img = new Image(50,30)
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'
img.onload = drawImageActuralSize
function drawImageActuralSize(){
    c.width = this.naturalWidth
    c.height= this.naturalHeight
    ctx.drawImage(this, 0, 0)  // 绘制原图,忽略(50,30)
    ctx.drawImage(this, 0, 0, this.width, this.height)  // 绘制自定义大小图片
}
  • resetTransform():

合成

  • globalAlpha
  • globalCompositeOperation

绘制图像

  • drawImage()

像素控制

  • createImageData(w,h,imagedata):创建一个新的、空白的、指定大小的 ImageData 对象。 所有的像素在新对象中都是透明的。
  • getImageData(x,y,w,h):获取矩形区域内的图像数据,返回链接,左上坐标|宽|高
  • putImageData(imagedata,dx,dy,dirtyX,dirtyY,dirtyWidth,dirtyHeight):将数据从已有的 ImageData 对象绘制到位图的方法。 如果提供了一个绘制过的矩形,则只绘制该矩形的像素。此方法不受画布转换矩阵的影响。源图像数据 x,y偏移量|矩形左上角坐标|宽高
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d')
ctx.fillRect(0,0,100,100)
data = ctx.getImageData(0,0,100,100)
ctx.putImageData(data,30,30)

图像平滑

  • imageSmoothingEnabled:true/False,让图像平滑。
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d')
ctx.font = '16px 楷体'
ctx.textAlign = 'center'
const img = new Image()
img.src = 'https://interactive-examples.mdn.mozilla.net/media/examples/star.png';
img.onload = function(){
    const w = img.width, h = img.height
    ctx.fillText('Source', w*.5, 20)
    ctx.drawImage(img,0,24,w,h)
    ctx.fillText('Smoothing = False', w*2.5, 20)
    ctx.drawImage(img,w,24,w*3,h*3)
    ctx.fillText('Smooth = True', w*5.5, 20)
    ctx.imageSmoothingEnabled = true
    ctx.drawImage(img,w*4,24,w*3,h*3)
}

canvas 状态

  • save():保存画布当时状态(填充颜色等)。
  • restore():恢复到 save 时的状态。
  • canvas:
var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d')
ctx.save()
ctx.fillStyle = 'greenyellow'
ctx.fillRect(4,4,50,50)
ctx.restore()
ctx.fillRect(60,60,50,50)  // 此时填充色为黑色,即save 时的颜色
posted @ 2021-07-19 15:04  君*邪  阅读(106)  评论(0编辑  收藏  举报