开启VSCode代码提示
js里写
/** @type {HTMLCanvasElement} */
创建基本图形
<canvas id="c1" width="600" height="300" style="position:relative;z-index: 1;">
浏览器不支持Canvas,没有canvas的滚出克
</canvas>
let c1 = document.getElementById("c1")
let ctx = c1.getContext('2d')
矩形(rect)
// 填充的矩形
// 矩形 x,y 宽,高
ctx.fillRect(100,100,300,300)
// 线组成的矩形
ctx.strokeRect(100, 10, 300, 300)
ctx.fillRect(100, 10, 100, 100)
独立区域
ctx.beginPath()
ctx.rect(10, 10, 100, 100)
ctx.stroke()
ctx.closePath()
圆(arc)
// x,y,半径,起始角度,结束角,(顺逆时针 默认false顺时针 true逆时针)
// moveTo 绘制不连续的路径 移动原点到某个位置
ctx.beginPath()
ctx.arc(100, 100, 100, 0, Math.PI * 2)
ctx.moveTo(150,100)
ctx.arc(100, 100, 50, 0, Math.PI)
ctx.moveTo(85, 35)
ctx.arc(75, 35, 10, 0, Math.PI)
ctx.moveTo(135, 35)
ctx.arc(125, 35, 10, 0, Math.PI)
ctx.stroke()
ctx.closePath()
擦除(clear)
let height = 0;
let timer = setInterval(() => {
height++
ctx.clearRect(0, 0, c1.clientWidth, height)
if (height > c1.clientHeight) {
clearInterval(timer)
}
}, 10)
圆弧(arcTo)
// arc 原点到 x1,y1 到 x2,y2
ctx.beginPath()
ctx.moveTo(100,100)
//x,y | x,y 半径
ctx.arcTo(170,100,50,3,30)
ctx.stroke()
ctx.closePath()
quadraticCurveTo()
CanvasRenderingContext2D.quadraticCurveTo() 是 Canvas 2D API 新增二次贝塞尔曲线路径的方法。它需要 2 个点。第一个点是控制点,第二个点是终点。起始点是当前路径最新的点,当创建二次贝赛尔曲线之前,可以使用 moveTo() 方法进行改变。
第一个为原点
ctx.quadraticCurveTo(cpx, cpy, x, y);
cpx
控制点的 x 轴坐标。
cpy
控制点的 y 轴坐标。
x
终点的 x 轴坐标。
y
终点的 y 轴坐标。
bezierCurveTo()
CanvasRenderingContext2D.bezierCurveTo() 是 Canvas 2D API 绘制三次贝赛尔曲线路径的方法。该方法需要三个点。第一、第二个点是控制点,第三个点是结束点。起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改。
路径(path)
// 路径
var heartPath = new Path2D()
heartPath.moveTo(200, 120)
heartPath.bezierCurveTo(80, 20, 50, 220, 200, 250)
heartPath.bezierCurveTo(350, 220, 320, 20, 200, 120)
渐变(gradient)
createLinearGradient
let lineColor = ctx.createLinearGradient(0, 0, 650, 0)
lineColor.addColorStop(0, '#e03131')
lineColor.addColorStop(index, '#ff8787')
lineColor.addColorStop(1, '#ffc9c9')
createConicGradient
let lineColor = ctx.createConicGradient(Math.PI/6, 120, 10)
lineColor.addColorStop(0, '#e03131')
lineColor.addColorStop(.2, '#22b8cf')
lineColor.addColorStop(1, '#ffc9c9')
image
let img = new Image;
img.src = "./image/柴郡.jpg"
img.onload = ()=>{
var partten = ctx.createPattern(img,"repeat")
ctx.fillStyle = partten;
ctx.fillRect(0,0,600,200)
}
line
ctx.lineWidth = 1;
// butt
// 线段末端以方形结束。
// round
// 线段末端以圆形结束。
// square
// 线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域。
ctx.lineCap = "round"
// round
// 通过填充一个额外的,圆心在相连部分末端的扇形,绘制拐角的形状。圆角的半径是线段的宽度。
// bevel
// 在相连部分的末端填充一个额外的以三角形为底的区域,每个部分都有各自独立的矩形拐角。
// miter
// 通过延伸相连部分的外边缘,使其相交于一点,形成一个额外的菱形区域。这个设置可以通过 miterLimit 属性看到效果。
ctx.lineJoin = "mitter"
// 虚线模式 传入间隔数组
ctx.setLineDash([1,2,3,4])
video
// 图片 影音
var video = document.querySelector("video")
var btn = document.getElementById("btn")
var img = new Image()
img.src = "./image/柴郡.jpg"
btn.onclick = function () {
video.play()
render()
}
function render() {
ctx.drawImage(video, 0, 0, 600, 400)
ctx.drawImage(img,500,10,200,100)
requestAnimationFrame(render)
}
案例
<canvas id="c1" width="600" height="300" style="position:relative;z-index: 1;">
浏览器不支持Canvas
</canvas>
<br>
<button class="thickline button">粗线条</button>
<button class="thinline button active">细线条</button>
<button class="saveImg">保存图片</button>
<input type="color" name="" id="colorIpt">
<button class="rubber button">橡皮擦</button>
<button class="clearImg">清空画板</button>
script
/** @type {HTMLCanvasElement} */
let c1 = document.getElementById("c1")
let ctx = c1.getContext('2d')
let thinkBtn = document.querySelector(".thickline")
let thinBtn = document.querySelector(".thinline")
let saveBtn = document.querySelector(".saveImg")
let colorBtn = document.querySelector("#colorIpt")
let clearBtn = document.querySelector(".clearImg")
let rubberBtn = document.querySelector(".rubber")
ctx.fillStyle = "#fff"
ctx.fillRect(0, 0, 600, 300)
ctx.lineJoin = "round"
ctx.lineCap = "round"
ctx.lineWidth = 3;
var isDraw = false;
c1.onmousedown = (e) => {
isDraw = true;
ctx.beginPath()
let x = e.pageX - c1.offsetLeft;
let y = e.pageY - c1.offsetTop;
ctx.moveTo(x, y)
}
c1.ontouchstart = (e) => {
let ev = e.targetTouches[0]
isDraw = true;
ctx.beginPath()
let x = ev.pageX - c1.offsetLeft;
let y = ev.pageY - c1.offsetTop;
ctx.moveTo(x, y)
}
c1.onmouseup = (e) => {
isDraw = false;
ctx.closePath()
}
c1.ontouchcancel = (e) => {
isDraw = false;
ctx.closePath()
}
c1.onmouseleave = (e) => {
isDraw = false;
ctx.closePath()
}
c1.ontouchend = (e) => {
isDraw = false;
ctx.closePath()
}
c1.onmousemove = (e) => {
if (isDraw) {
let x = e.pageX - c1.offsetLeft;
let y = e.pageY - c1.offsetTop;
ctx.lineTo(x, y)
ctx.stroke()
} else {
}
}
c1.ontouchmove = (e) => {
let ev = e.targetTouches[0]
if (isDraw) {
let x = ev.pageX - c1.offsetLeft;
let y = ev.pageY - c1.offsetTop;
ctx.lineTo(x, y)
ctx.stroke()
} else {
}
}
// 清空
clearBtn.onclick = () => {
ctx.clearRect(0, 0, 600, 300);
}
// 橡皮擦
rubberBtn.onclick = () => {
// ctx.clearRect(0, 0, 600, 300);
ctx.globalCompositeOperation = "destination-out"
ctx.lineWidth = 30
rubberBtn.classList.add("active")
thinkBtn.classList.remove("active")
thinBtn.classList.remove("active")
}
// 粗线条
thinkBtn.onclick = () => {
ctx.globalCompositeOperation = "source-over"
ctx.lineWidth = 16;
thinkBtn.classList.add("active")
thinBtn.classList.remove("active")
rubberBtn.classList.remove("active")
}
// 细线条
thinBtn.onclick = () => {
ctx.globalCompositeOperation = "source-over"
ctx.lineWidth = 3;
thinBtn.classList.add("active")
thinkBtn.classList.remove("active")
rubberBtn.classList.remove("active")
}
// 换颜色
colorBtn.onchange = (e) => {
ctx.strokeStyle = e.target.value
}
saveBtn.onclick = (e) => {
// 把img添加到界面
let urlData = c1.toDataURL()
// let img = new Image()
// img.src = urlData;
// document.body.appendChild(img)
// 下载img
var downLoada = document.createElement("a" )
downLoada.setAttribute("download", "酷炫签名")
downLoada.href = urlData;
downLoada.click()
}
toDataURL
toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为 96dpi。