Skip to content

Commit

Permalink
canvas
Browse files Browse the repository at this point in the history
  • Loading branch information
wangsuyan committed Oct 17, 2021
1 parent d6b7283 commit 8442f13
Show file tree
Hide file tree
Showing 10 changed files with 506 additions and 6 deletions.
21 changes: 21 additions & 0 deletions learn-canvas/0-demo-template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @author 素燕(我有个公众号:素燕)
* @description 每个 demo 的模板
*/

import { initCanvas } from './share';

function syRunDemo() {
const drawReact = (ctx: CanvasRenderingContext2D) => {
ctx.fillStyle = '#555';
ctx.fillRect(40, 40, 80, 80);
}

// 1. 创建 canvas
let ctx = initCanvas();

// 在画布中画一个矩形区域
drawReact(ctx);
}

syRunDemo();
62 changes: 62 additions & 0 deletions learn-canvas/11-measure-width.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* @author 素燕(我有个公众号:素燕)
* @description 测量绘制宽度
*/

import { initCanvas } from './share';

const text = '< < < < < <';
const fontSize = 30;

interface SYNode {
width: number;
left: number;
text: string;
}

const getChars = (text: string) => {
let rets: SYNode[] = [];
let chars = text.split('');
let measureCanvas = document.createElement('canvas');
let ctx = measureCanvas.getContext('2d') as CanvasRenderingContext2D;
ctx.font = `${fontSize}px Times`;
let left = 120;
chars.forEach(char => {
// measureText 这个方法目前没有遇到测量不准的情况,对于自定义字体,先确保自定义字体已经加载完成
// 再使用这个方法,否则会导致测量不准
let width = ctx.measureText(char).width;
rets.push({
width,
text: char,
left
});
left += width;
});
return rets;
}

function syRunMeasureWidthDemo() {
const drawText = (ctx: CanvasRenderingContext2D) => {
ctx.fillStyle = '#555';
ctx.textBaseline = 'top';
ctx.font = `${fontSize}px Times`;
ctx.fillText(text, 120, 120);
}

const drawByChars = (ctx: CanvasRenderingContext2D) => {
let nodes = getChars(text);
nodes.forEach(aNode => {
ctx.fillText(aNode.text, aNode.left, 140);
ctx.strokeRect(aNode.left, 140, aNode.width, fontSize);
});
}

// 1. 创建 canvas
let ctx = initCanvas();

// 在画布中画一个矩形区域
drawText(ctx);
drawByChars(ctx);
}

syRunMeasureWidthDemo();
58 changes: 58 additions & 0 deletions learn-canvas/12-transform-scale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @author 素燕(我有个公众号:素燕)
* @description canvas 设置 scale
*/

import { initCanvas } from './share';

function syRunDemo() {
const left = 80;
const top = 80;
const height = 80;
const text = '| 和素燕一起学 Canvas,😄¥ |';

const scaleText = (ctx: CanvasRenderingContext2D) => {
ctx.font = '40px Times';
ctx.textBaseline = 'top';
ctx.fillText(text, left, top);

// 保持绘制上下文当前的状态
ctx.save();
/**
* 不会影响已经绘制内容的显示
* scaleX:坐标x和width都会按比例进行缩放
* scaleY:坐标y和height都会按比例进行缩放
*/
ctx.scale(0.5, 1);
ctx.fillText(text, left, top + height);
// 恢复绘制上下文的上一次状态
ctx.restore();

ctx.fillText(text, left, top + 2 * height);
}

const scaleRect = (ctx: CanvasRenderingContext2D) => {
ctx.fillRect(left*2, top + 3 * height, height, height / 2);
// 保持绘制上下文当前的状态
ctx.save();
/**
* 不会影响已经绘制内容的显示
* scaleX:坐标x和width都会按比例进行缩放
* scaleY:坐标y和height都会按比例进行缩放
*/
ctx.scale(2, 0.5);
ctx.fillRect(left*2, top + 4 * height, height, height / 2);
// 恢复绘制上下文的上一次状态
ctx.restore();

ctx.fillRect(left*2, top + 5 * height, height, height / 2);
}

// 1. 创建 canvas
let ctx = initCanvas();

scaleText(ctx);
scaleRect(ctx);
}

syRunDemo();
66 changes: 66 additions & 0 deletions learn-canvas/13-transform-rotate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* @author 素燕(我有个公众号:素燕)
* @description rotate 旋转
*/

import { initCanvas } from './share';

function syRunDemo() {
const origin = {
x: 360,
y: 280
};
const lineWidth = 200;
const radius = 6;

const drawReact = (ctx: CanvasRenderingContext2D, degree: number) => {
ctx.clearRect(0, 0, ctx.canvas.width * 2, ctx.canvas.height * 2);
ctx.fillStyle = 'red';
ctx.strokeStyle = 'blue';

ctx.beginPath();
ctx.moveTo(origin.x - lineWidth, origin.y);
ctx.lineTo(origin.x + lineWidth, origin.y);
ctx.lineWidth = 1;
ctx.stroke();

ctx.beginPath();
ctx.moveTo(origin.x, origin.y - lineWidth);
ctx.lineTo(origin.x, origin.y + lineWidth);
ctx.stroke();

ctx.beginPath();
ctx.arc(origin.x, origin.y, radius, 0, Math.PI / 180 * 360);
ctx.fill();

ctx.strokeStyle = '#000';
/**
* ctx 默认的绘制原点为左上角
* translate 设置后将修改画布的原点
* 以后绘制的坐标值为相对设置后的原点
*/
ctx.save();
ctx.translate(origin.x, origin.y);
ctx.strokeRect(-80, -40, 160, 80);
// 旋转的角度
ctx.rotate(degree * Math.PI / 180);
ctx.strokeStyle = 'blue';
ctx.strokeRect(-80, -40, 160, 80);
ctx.restore();
}

// 1. 创建 canvas
let ctx = initCanvas();

// 在画布中画一个矩形区域
let count = 0;
setInterval(() => {
count += 6;
if (count >= 360) {
count = 0;
}
drawReact(ctx, count);
}, 1000 / 60);
}

syRunDemo();
60 changes: 60 additions & 0 deletions learn-canvas/14-translate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* @author 素燕(我有个公众号:素燕)
* @description translate 修改坐标原点
*/

import { initCanvas } from './share';

function syRunDemo() {
const origin = {
x: 360,
y: 280
};
const lineWidth = 200;
const radius = 6;

const drawReact = (ctx: CanvasRenderingContext2D) => {
ctx.fillStyle = 'red';
ctx.strokeStyle = 'blue';

ctx.beginPath();
ctx.moveTo(origin.x - lineWidth, origin.y);
ctx.lineTo(origin.x + lineWidth, origin.y);
ctx.lineWidth = 1;
ctx.stroke();

ctx.beginPath();
ctx.moveTo(origin.x, origin.y - lineWidth);
ctx.lineTo(origin.x, origin.y + lineWidth);
ctx.stroke();

ctx.beginPath();
ctx.arc(origin.x, origin.y, radius, 0, Math.PI / 180 * 360);
ctx.fill();

ctx.strokeStyle = '#000';
/**
* ctx 默认的绘制原点为左上角
* translate 设置后将修改画布的原点
* 以后绘制的坐标值为相对设置后的原点
*/
ctx.translate(origin.x, origin.y);
ctx.strokeRect(40, 80, 160, 80);

ctx.strokeRect(-200, -160, 160, 80);

ctx.strokeRect(-80, -40, 160, 80);

ctx.save();
ctx.rotate(45 * Math.PI / 180);
ctx.strokeRect(-80, -40, 160, 80);
}

// 1. 创建 canvas
let ctx = initCanvas();

// 在画布中画一个矩形区域
drawReact(ctx);
}

syRunDemo();
Loading

0 comments on commit 8442f13

Please sign in to comment.