查看浏览器缩放比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>查看浏览器缩放比</title>
</head>

<body>
<button onclick="alert(detectZoom())">查看</button>
<script>
function detectZoom() {
var ratio = 0,
screen = window.screen,
ua = navigator.userAgent.toLowerCase();

if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
} else if (~ua.indexOf('msie')) {
if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
}
} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
}

if (ratio) {
ratio = Math.round(ratio * 100);
}

return ratio;
};
</script>
</body>

</html>

canvas- 基本动画

动画的基本步骤:

1.清空canvas

除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法。

2.保存canvas状态

如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。

3.绘制动画图形

这一步才是重绘动画帧。

4.恢复canvas状态

如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

操控动画 Controlling an animation

setInterval(function, delay)

当设定好间隔时间后,function会定期执行。

setTimeout(function, delay)

在设定好的时间之后执行函数

requestAnimationFrame(callback)

这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低.
告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var sun = new Image();
var moon = new Image();
var earth = new Image();

function init() {
sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
window.requestAnimationFrame(draw);
}

function draw() {
var ctx = document.getElementById('tutorial').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
ctx.clearRect(0, 0, 300, 300); //除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法
ctx.fillStyle = 'rgba(0,0,0,0.4)';
ctx.strokeStyle = 'rgba(0,153,255,0.4)'; //画太阳外面的圆
ctx.save(); //如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
ctx.translate(150, 150);
// earth
var time = new Date();
ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 60000) * time.getMilliseconds());
ctx.translate(105, 0);
ctx.fillRect(0, -12, 50, 24);
ctx.drawImage(earth, -12, -12)
// // moon
ctx.save();
ctx.rotate(((2 * Math.PI) / 6) * time.getSeconds() + ((2 * Math.PI) / 6000) * time.getMilliseconds());
ctx.translate(0, 28.5);
ctx.drawImage(moon, -3.5, -3.5);
ctx.restore(); // 如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

ctx.restore();
ctx.beginPath();
ctx.arc(150, 150, 105, 0, Math.PI * 2, false);
ctx.stroke();
ctx.drawImage(sun, 0, 0, 300, 300);

window.requestAnimationFrame(draw);
}
init();
1
2
3
ctx.beginPath();
ctx.arc(150, 150, 105, 0, Math.PI * 2, false);
ctx.stroke();
1
ctx.drawImage(sun, 0, 0, 300, 300);
1
2
3
4
5
var time = new Date();
ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 60000) * time.getMilliseconds());
ctx.translate(105, 0);
ctx.fillRect(0, -12, 50, 24);
ctx.drawImage(earth, -12, -12)
1
2
3
var time = new Date();
ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 60000) * time.getMilliseconds());
ctx.fillRect(0, -12, 50, 24);
1
ctx.translate(105, 0);
1
ctx.drawImage(earth, -12, -12)
1
2
3
ctx.rotate(((2 * Math.PI) / 6) * time.getSeconds() + ((2 * Math.PI) / 6000) * time.getMilliseconds());
ctx.translate(0, 28.5);
ctx.drawImage(moon, -3.5, -3.5);

canvas--变形

1.状态的保存和回复 Saving and Restoring state

1.1 save()

保存画布(canvas)当前的所有状态

1.2 restore()

恢复画布(canvas)的上一个已保存的状

Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。

一个绘画状态包括:

  • 当前应用的变形(即移动,旋转和缩放)
  • strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
  • 当前的裁切路径(clipping path)
    可以调用任意多次 save 方法。
每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 150, 150); // 默认 #000
ctx.save();
ctx.fillStyle = "#f00";
ctx.fillRect(20, 20, 110, 110);
ctx.save();
ctx.fillStyle = "#ff0";
ctx.fillRect(40, 40, 70, 70);
ctx.save();
ctx.restore();
ctx.fillRect(30, 30, 90, 90); // #ff0
ctx.restore();
ctx.fillRect(10, 10, 130, 130); // #f00
ctx.restore();
ctx.fillRect(0, 0, 150, 150); // #000

}
}

2.移动 Translating

1.1 translate(x, y)它用来移动 canvas 和它的原点到一个不同的位置。

translate 方法接受两个参数。

  • x 是左右偏移量
  • y 是上下偏移量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
ctx.save();
ctx.fillStyle = 'rgb(' + (51 * i) + ',' + (255 - 51 * i) + ',255)';
ctx.translate(10 + j * 50, 10 + i * 50);
ctx.fillRect(0, 0, 25, 25)
ctx.restore();

}

}

}
}

未使用translate,如果不使用 translate 方法,那么所有矩形都将被绘制在相同的位置(0,0)

使用translate,可以移动 canvas 原点,translate 方法同时让我们可以任意放置这些图案,而不需要在 fillRect() 方法中手工调整坐标值

2.旋转 Rotating

2.1 rotate(angle) 以原点为中心旋转 canvas

rotate(angle)
这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.translate(75, 75); // 每次循环之后,圆心的位置都回到(75,75)
for (let i = 0; i < 6; i++) { // 第一层循环决定环的数量
ctx.save();
ctx.fillStyle = 'rgb(' + (51 * i) + ',' + (255 - 51 * i) + ',255)';
for (let j = 0; j < i*1; j++) { // 第二层循环决定每环有多少个点
// 每次画圆点,我都以一定夹角来旋转 canvas,而这个夹角则是由环上的圆点数目的决定的。最里层的环有 6 个圆点,这样,每次旋转的夹角就是 360/6 = 60 度。
// 往外每一环的圆点数目是里面一环的 2 倍,那么每次旋转的夹角随之减半。
ctx.rotate(Math.PI * 2 / (i *
6)) // 第一圈旋转0° 第二圈旋转60° 第三圈旋转30° 第四圈旋转15° 第五圈旋转12° 第六圈旋转10° 第七圈旋转8.57°...
ctx.beginPath();
ctx.arc(0, i * 12.5, 5, 0,Math.PI * 2, true); // x,y,r,startAngle,endAngle,anticlockwise
ctx.fill();
}
ctx.restore();

}

}
}

j < i*1;
当i分别为0,1,2,3,4,5时,效果如下:

3.缩放 Scaling

3.1 scale(x,y) 增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大

两个参数都是实数,可以为负数,如果比1小,会比缩放图形, 如果比1大会放大图形。默认值为1, 为实际大小。

  • x 为水平缩放因子
  • y 为垂直缩放因子
1
2
3
4
5
6
7
8
9
10
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.save();
ctx.scale(10, 3);
ctx.fillRect(1, 10, 10, 10);
ctx.restore();
}
}

未设置缩放

设置缩放 ctx.scale(10, 3);

1
2
3
4
5
6
7
8
9
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.scale(-1, 1);
ctx.font = '48px serif';
ctx.fillText('Nancy', -135, 120)
}
}

4.变形 Transforms

4.1 transform(m11, m12, m21, m22, dx, dy) 将当前的变形矩阵乘上一个基于自身参数的矩阵

  • m11:水平方向的缩放
  • m12:水平方向的倾斜偏移
  • m21:竖直方向的倾斜偏移
  • m22:竖直方向的缩放
  • dx:水平方向的移动
  • dy:竖直方向的移动

    4.2 resetTransform() 重置当前变形为单位矩阵

    等同于
    1
    ctx.setTransform(1, 0, 0, 1, 0, 0);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');

var sin = Math.sin(Math.PI/6);
var cos = Math.cos(Math.PI/6);
ctx.translate(100, 100);
var c = 0;
for (var i=0; i <= 12; i++) {
c = Math.floor(255 / 12 * i);
ctx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
ctx.fillRect(0, 0, 100, 10);
ctx.transform(cos, sin, -sin, cos, 0, 0);
}

ctx.setTransform(-1, 0, 0, 1, 100, 100);
ctx.fillStyle = "rgba(255, 128, 255, 0.5)";
ctx.fillRect(0, 50, 100, 100);
}

canvas--使用图片

引入图像到canvas里

需要以下两步基本操作:

1.获得一个指向HTMLImageElement的对象或者另一个canvas元素的引用作为源,也可以通过提供一个URL的方式来使用图片

canvas的API可以使用下面这些类型中的一种作为图片的源:

1.1 HTMLImageElement

这些图片是由Image()函数构造出来的,或者任何的img元素

1.2 HTMLVideoElement

用一个HTML的 video元素作为你的图片源,可以从视频中抓取当前帧作为一个图像

1.3 HTMLCanvasElement

可以使用另一个 canvas 元素作为你的图片源。

1.4 ImageBitmap

这是一个高性能的位图,可以低延迟地绘制,它可以从上述的所有源以及其它几种源中生成。

获取图片的方式

  • 使用相同页面的图片(同域)
  • 使用其他域名下的图片(跨域)
  • 使用其他canvas元素
  • 从零开始创建图像
  • 通过data:url方式嵌入图像
  • 使用视频帧

    2.使用drawImage()函数将图片绘制到画布上

    2.1 绘制图片

    drawImage(image,x,y)

2.2 缩放 Scaling

drawImage(image, x, y, width, height)

1
2
3
4
5
6
7
8
9
10
11
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0, 150, 150);
}
img.src = "./test.jpg";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
ctx.drawImage(img, i * 50, j * 50, 50, 50);
}
}
}
img.src = "./test.jpg";
}
}

2.2 切片 Slicing

drawImage(image,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight)

  • sx,sy,sWidth,sHeight 是定义图像源的切片位置和大小
  • dx,dy,dWidth,dHeight 是定义切片的目标显示位置和大小。
1
2
3
4
5
6
7
8
9
10
11
12
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
ctx.drawImage(img, 50,71,704,824,21,20,237,304);

}
img.src="./avatar.png"
}
}

合成两张图片

1
2
3
4
5
6
7
8
9
10
11
12
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
ctx.drawImage(document.getElementById('bg'),-50,-50)
ctx.drawImage(img, 50,71,704,824,21,20,237,304);
}
img.src="./avatar.png"
}
}

canvas--绘制文本

绘制文本(Drawing Text)

1.1 fillText(text,x,y,[,maxWidth]) 在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.

1
2
3
4
5
6
7
8
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.font = "18px serif";
ctx.fillText("Hello World", 10, 50)
}
}

效果如下:

1.2 strokeText(text,x,y,[,maxWidth]) 在指定的(x,y)位置绘制文本边框,绘制的最大宽度是可选的.

1
2
3
4
5
6
7
8
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.font = "18px serif";
ctx.strokeText("Hello World", 10, 50)
}
}

效果如下:

2.有样式的文本(Styling Text)

2.1 设置字体 font = value 默认”10px sans-serif”

和 CSS font 属性相同的语法

2.1 设置文本对齐方式 textAlign = value 默认 “start”

可选值:start、end、left、right、center

2.1 设置基线对齐方式 textBaseline = value 默认 “alphabetic”

可选值:top、hanging、middle、alphabetic、ideographic、bottom

2.1 设置文本方向 direction = value 默认 “inherit”

可选值:ltr(left to right)、rtl(right to left)、inherit

1
2
3
4
5
6
7
8
9
10
11
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.font = "18px serif";
ctx.textAlign = "start";
ctx.textBaseline = "hanging";
ctx.direction="ltr";
ctx.fillText("Hello World", 10, 50);
}
}

效果如下:

canvas--使用样式和颜色

如何在绘图中添加不同的颜色、线条样式、渐变、图案、阴影

1.色彩 Colors

1.1设置图形填充颜色 fillStyle = color

1.2设置图形轮廓颜色 strokeStyle = color

color可以是表示 CSS 颜色值的字符串,渐变对象或者图案对象。

fillStyle

1
2
3
4
5
6
7
8
9
10
11
12
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
ctx.fillStyle = "rgb(" + Math.floor(255 - 42.5 * i) + "," + Math.floor(255 - 42.5 * j) + ",0)";
ctx.fillRect(j * 25, i * 25, 25, 25);
}
}
}
}

效果如下:

strokeStyle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
ctx.strokeStyle = "rgb(" + Math.floor(255 - 42.5 * i) + "," + Math.floor(255 - 42.5 * j) +
",0)";
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, false);
ctx.stroke();
}
}
}
}

效果如下:

2.透明度 Transparency

除了可以绘制实色图形,我们还可以用 canvas 来绘制半透明的图形。通过设置 globalAlpha 属性或者使用一个半透明颜色作为轮廓或填充的样式。

2.1 通过globalAlpha设置全局透明度 globalAlpha = transparencyValue

globalAlpha属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。

2.2 通过CSS3颜色值设置透明度

1
2
3
//  指定透明颜色,用于描边和填充样式
ctx.strokeStyle = "rgba(255,0,0,0.5)";
ctx.fillStyle = "rgba(255,0,0,0.5)";

globalAlpha

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
// 画背景
ctx.fillStyle = "#F00";
ctx.fillRect(0, 0, 75, 75);
ctx.fillStyle = "#FF0";
ctx.fillRect(75, 0, 75, 75);
ctx.fillStyle = "#F0F";
ctx.fillRect(0, 75, 75, 75);
ctx.fillStyle = "#0FF";
ctx.fillRect(75, 75, 75, 75);
ctx.fillStyle = "#FFF";
// 设置透明度值
ctx.globalAlpha = 0.2;
// 画半透明圆
for (var i = 0; i < 7; i++) {
ctx.beginPath();
ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
ctx.fill();
}
}
}

效果如下:

注意:先画图,还是先设置透明度ctx.globalAlpha = 0.2,所得的图形透明度有差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
// 设置全局透明度
ctx.globalAlpha = 0.2;
// 画背景
ctx.fillStyle = "#F00";
ctx.fillRect(0, 0, 75, 75);
ctx.fillStyle = "#FF0";
ctx.fillRect(75, 0, 75, 75);
ctx.fillStyle = "#F0F";
ctx.fillRect(0, 75, 75, 75);
ctx.fillStyle = "#0FF";
ctx.fillRect(75, 75, 75, 75);
ctx.fillStyle = "#FFF";
// 画的矩形均为半透明
}
}

效果如下:

CSS3颜色值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
// 画背景
ctx.fillStyle = 'rgb(255,221,0)';
ctx.fillRect(0, 0, 150, 37.5);
ctx.fillStyle = 'rgb(102,204,0)';
ctx.fillRect(0, 37.5, 150, 37.5);
ctx.fillStyle = 'rgb(0,153,255)';
ctx.fillRect(0, 75, 150, 37.5);
ctx.fillStyle = 'rgb(255,51,0)';
ctx.fillRect(0, 112.5, 150, 37.5);
// 画半透明矩形
for (var i = 0; i < 10; i++) {
ctx.fillStyle = 'rgba(255,255,255,' + (i + 1) / 10 + ')'
for (var j = 0; j < 4; j++) {
ctx.fillRect(5 + i * 14, 5 + j * 37.5, 14, 27.5)
}
}
}
}

效果如下:

3.线型 Line styles

3.1设置线条宽度 lineWidth = value

线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半.
所有宽度为奇数的线并不能精确呈现,这就是因为路径的定位问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
for (var i = 0; i < 10; i++) {
ctx.lineWidth = 1 + i;
ctx.beginPath();
ctx.moveTo(10 + 14 * i, 10);
ctx.lineTo(10 + 14 * i, 140);
ctx.stroke();
}

}
}

3.2设置线条末端样式 lineCap = value

3.3设置线条与线条结合处样式 lineJoin = value

3.4限制当两条线相交时交接处最大长度 miterLimit = value

所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。

3.5返回当前虚线样式 getLineDash()

3.6设置虚线样式的起始偏移量 lineDashOffset = value

4.渐变 Gradients

用createLinearGradient、createRadialGradient新建一个 canvasGradient 对象

4.1 createLinearGradient(x1,y1,x2,y2)

createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。

1
var lineargradient = ctx.createLinearGradient(0,0,50,50)

4.2 createRadialGradient(x1,y1,r1,x2,y2,r2)

createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。

1
var radialgradient = ctx.createRadialGradient(50,50,0,50,50,100)

4.3 addColorStop(position,color)

创建出 canvasGradient 对象后,我们就可以用 addColorStop 方法给它上色了。

  • position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。0.5 表示颜色会出现在正中间
  • color 参数必须是一个有效的 CSS 颜色值
    1
    2
    3
    var lineargradient = ctx.createLinearGradient(0,0,150,150)
    lineargradient.addColorStop(0,'#fff');
    lineargradient.addColorStop(1,'#000');

createLinearGradient例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
lingrad.addColorStop(0,"#00abeb");
lingrad.addColorStop(0.5,"#fff");
lingrad.addColorStop(0.5,"#26c000");
lingrad.addColorStop(1,"#fff");
var lingrad2 = ctx.createLinearGradient(0,50,0,95);
lingrad2.addColorStop(0,'#000');
lingrad2.addColorStop(1,'rgba(0,0,0,0)')
ctx.fillStyle = lingrad;
ctx.strokeStyle = lingrad2;
ctx.fillRect(10,10,130,130);
ctx.strokeRect(50,50,50,50);
}
}

效果如下:

createRadialGradient例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30)
radgrad.addColorStop(0, '#a7d30c');
radgrad.addColorStop(0.9, '#019f62');
radgrad.addColorStop(1, 'rgba(1,159,98,0');

var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50);
radgrad2.addColorStop(0, '#FF5F98');
radgrad2.addColorStop(0.75, '#FF0188');
radgrad2.addColorStop(1, 'rgba(255,1,136,0)');

var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40);
radgrad3.addColorStop(0, '#00C9FF');
radgrad3.addColorStop(0.8, '#00B5E2');
radgrad3.addColorStop(1, 'rgba(0,201,255,0)');

var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90);
radgrad4.addColorStop(0, '#F4F201');
radgrad4.addColorStop(0.8, '#E4C700');
radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
// 画图形
ctx.fillStyle = radgrad4;
ctx.fillRect(0, 0, 150, 150);
ctx.fillStyle = radgrad3;
ctx.fillRect(0, 0, 150, 150);
ctx.fillStyle = radgrad2;
ctx.fillRect(0, 0, 150, 150);
ctx.fillStyle = radgrad;
ctx.fillRect(0, 0, 150, 150);
}
}

效果如下:

5.图案样式 Patterns

5.1 createPattern(image,type)

  • Image 可以是一个 Image 对象的引用,或者另一个 canvas 对象。
  • Type 必须是下面的字符串值之一:repeat,repeat-x,repeat-y 和 no-repeat。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
img.onload = function () {
var ptrn = ctx.createPattern(img, 'repeat');
// var ptrn = ctx.createPattern(img, 'repeat-x');
// var ptrn = ctx.createPattern(img, 'repeat-y');
// var ptrn = ctx.createPattern(img, 'no-repeat');
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, 150, 150);
}
}
}

效果如下:
repeat

repeat-x

repeat-y

no-repeat

6.阴影 Shadows

6.1 设定阴影在x轴的延伸距离 shadowOffsetX = float

负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0。

6.1 设定阴影在y轴的延伸距离 shadowOffsetY = float

负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0。

6.1 设定阴影的模糊程度 shadowBlur = float

其数值并不跟像素数量挂钩

6.1 设定阴影的颜色效果 shadowColor = color

标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
// ctx.shadowOffsetX = 2;
// ctx.shadowOffsetY = 20;
ctx.shadowBlur = 2;
ctx.shadowColor = 'rgba(255,0,0,0.5)';

ctx.font = "20px Times New Roman";
ctx.fillStyle = "#000";
ctx.fillText("Shengnan Zheng", 5, 30)
}
}

效果如下:

7.Canvas填充规则 Canvas fill rules

当我们用到 fill(或者 clip和isPointinPath )你可以选择一个填充规则
“nonzero”: 非零缠绕规则, 默认值.
“evenodd”: 奇偶缠绕规则。

1
2
3
4
5
6
7
8
9
10
11
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(50,50,30,0,Math.PI*2,true);
ctx.arc(50,50,15,0,Math.PI*2,true);
// ctx.fill("nonzero");
ctx.fill("evenodd");
}
}

效果如下:

canvas--基本用法和绘制

1.canvas元素

1
<canvas id="tutorial" width="150" height="150"></canvas>

canvas 标签只有两个属性—— width和height。
由于某些较老的浏览器(尤其是IE9之前的IE浏览器)或者文本浏览器不支持HTML元素”canvas”,在这些浏览器上你应该总是能展示替代内容。

1
2
3
<canvas id="tutorial" width="150" height="150">
你的浏览器不支持canvas元素
</canvas>

2.渲染上下文(The rendering context)

  • canvas 元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。
  • canvas起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。canvas 元素有一个叫做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。
  • getContext()只有一个参数,上下文的格式。
1
2
3
4
5
6
7
var canvas = document.getElementById('tutorial');
if(canvas.getContext){
var ctx = canvas.getContext('2d');
// drawing code here
} else {
// canvas-unsupported code here
}

3.绘制

canvas 只支持两种形式的图形绘制:矩形和路径(由一系列点连成的线段)。所有其他类型的图形都是通过一条或者多条路径组合而成的。

3.1 绘制矩形

canvas提供了三种方法绘制矩形:

1.fillRect(x, y, width, height) 绘制一个填充的矩形
2.strokeRect(x, y, width, height) 绘制一个矩形的边框
3.clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明

参数:

  • x与y指定了在canvas画布上所绘制的矩形的左上角(相对于原点)的坐标。
  • width和height设置矩形的尺寸。

举个栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.canvas {
width: 900px;
height: 900px;
margin: 20px auto;
}

canvas {
border: 1px solid #aaa;
margin: 10px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(25,25,100,100);
ctx.clearRect(45,45,60,60);
ctx.strokeRect(50,50,50,50);
}
}
</script>
</head>

<body onload="draw();">
<div class="canvas">
<canvas id="tutorial" width="150" height="150">
你的浏览器不支持canvas
</canvas>
</div>
</body>

</html>

效果如下图:

3.2 绘制路径

图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  • 1.首先,你需要创建路径起始点。
  • 2.然后你使用画图命令去画出路径。
  • 3.之后你把路径封闭。
  • 4.一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

常用方法:

1.beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径
2.closePath() 闭合路径之后图形绘制命令又重新指向到上下文中
3.moveTo(x, y) 将一个新的子路径的起始点移动到(x,y)坐标。
4.lineTo(x, y) 使用直线连接子路径的最后的点到x,y坐标。
5.arc(x, y, r, startAngle, endAngle, anticlockwise)绘制一段圆弧路径
  • 圆弧路径的圆心在 (x, y) 位置
  • 半径为 r
  • 根据anticlockwise (默认为顺时针,false)指定的方向从 startAngle 开始绘制,到 endAngle 结束。
  • 参数anticlockwise为一个布尔值。为true时,是逆时针方向,否则顺时针方向。
  • arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式:
    弧度=(Math.PI/180)*角度
6.stroke() 通过线条来绘制图形轮廓
7.fill() 通过填充路径的内容区域生成实心的图形

绘制三角形:(绘制矩形)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
// 注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo()
// 无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。
ctx.moveTo(75,50);
ctx.lineTo(100,75);
ctx.lineTo(100,25);
ctx.fill();
// 当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
}
}

效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
// 注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo()
// 无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。
ctx.moveTo(75,50);
ctx.lineTo(100,75);
ctx.lineTo(100,25);
ctx.stroke();
// 当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
}
}

效果如下:

绘制笑脸:(绘制路径)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // 圆心(75,75) 半径50 起始角度0,结束角度360
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false); // 圆心(75,75) 半径35 起始角度0,结束角度180
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true);
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true);
ctx.stroke();
}
}

效果如下:

stroke与fill的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(25,25);
ctx.lineTo(125,25);
ctx.lineTo(25,125);
ctx.fill();

ctx.beginPath();
ctx.moveTo(125,125);
ctx.lineTo(125,45);
ctx.lineTo(45,125);
// 因为路径使用填充(fill)时,路径自动闭合,使用描边(stroke)则不会闭合路径。
// 如果没有添加闭合路径closePath()到描述三角形函数中,则只绘制了两条线段,并不是一个完整的三角形。
ctx.closePath();
ctx.stroke();
}
}

效果如下:

更复杂的绘制路径的方法

8.quadraticCurveTo(cp1x, cp1y, x, y) 绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
9.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

二次贝塞尔曲线绘制会话气泡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(75,25);
ctx.quadraticCurveTo(25,25,25,62.5);
ctx.quadraticCurveTo(25,100,50,100);
ctx.quadraticCurveTo(50,120,30,125);
ctx.quadraticCurveTo(60,120,60,100);
ctx.quadraticCurveTo(125,100,125,62.5);
ctx.quadraticCurveTo(125,25,75,25);
ctx.stroke();
}
}

效果如图:

三次贝塞尔曲线绘制爱心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(75,40);
ctx.bezierCurveTo(75,37,70,25,50,25);
ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
ctx.bezierCurveTo(20,80,40,102,75,120);
ctx.bezierCurveTo(110,102,130,80,130,62.5);
ctx.bezierCurveTo(130,62.5,130,25,100,25);
ctx.bezierCurveTo(85,25,75,37,75,40);
ctx.stroke();
ctx.fill();
}
}

效果如下:

vue项目中使用水印

vue项目中通过自定义指令

在vue项目中通过自定义指令,使用canvas特性生成base64格式的图片文件,并将其设置为背景图片,从而实现页面或组件局部水印效果

1.新建directives.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Vue from "vue";
Vue.directive('watermark', (el, binding) => {
function addWaterMarker(str, parentNode, font, textColor) {
var can = document.createElement('canvas'); //创建canvas元素
parentNode.appendChild(can); // 将canvas挂在到父节点
can.width = 400;
can.height = 200;
can.style.display = 'none';
var cans = can.getContext('2d');
cans.rotate(-20 * Math.PI / 180)
cans.font = font || "14px Helvetica";
cans.fillStyle = textColor || "rgba(180, 180, 180, 0.3)";
cans.textAlign = 'left';
cans.textBaseline = 'Middle';
cans.fillText(str, can.width / 20, can.height / 2);
parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")"; //将canvas转为转为图片展示的dataURL
}
addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor)
})

2.在入口文件 main.js引入 directives.js

1
import "@/assets/utils/directives";

注意:directives.js存放的路径 src//assets/utils/directives.js

3.调用指令

  如果希望在整个项目中都添加水印,可以在app.vue中使用指令

1
2
3
4
5
<template>
<div id="app">
<router-view v-watermark="{text:'水印名称',textColor:'rgba(180, 180, 180, 0.3)'}" />
</div>
</template>

我的项目时将{text:’水印名称’,textColor:’rgba(180, 180, 180, 0.3)’}存储在状态机中,以便可以几张管理配置,一旦text内容需要改变,就没必要取所有的组件去修改指令里面的内容了,附上状态机存储

1
2
3
4
5
6
7
 //  state.js
export default {
waterMarkObj: {
text: '水印名称',
textColor: 'rgba(180,180,180,0.3)'
}
};

在组件中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<div id="app">
<router-view v-watermark="waterMarkObj" />
</div>
</template>
<script>
export default {
computed:{
waterMarkObj() {
return this.$store.state.waterMarkObj;
}
}
};
</script>

补充知识

1.canvas.toDataURL(type, encoderOptions) 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。

参数
  • type 可选
    图片格式,默认为 image/png
  • encoderOptions 可选
    在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
  • 如果画布的高度或宽度是0,那么会返回字符串“data:,”。
  • 如果传入的类型非“image/png”,但是返回的值以“data:image/png”开头,那么该传入的类型是不支持的。
  • Chrome支持“image/webp”类型。
    返回值
    包含 data URI 的DOMString。
1
2
<!-- html -->
<canvas id="canvas" width="5" height="5"></canvas>
1
2
3
4
5
// js
var canvas = document.getElementById("canvas");
var dataURL = canvas.toDataURL();
console.log(dataURL);
// data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAD0lEQVQYV2NkwAIYaSAIAAGkAAa+Ds1zAAAAAElFTkSuQmCC

2.Data URLs 即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。

data:[mediatype][;base64],[data]
由四个部分组成:

  • 1.前缀(data:)
  • 2.指示数据类型的MIME类型,如果被省略,则默认值为 text/plain;charset=US-ASCII
    • 如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。
    • 如果是二进制数据,你可以将数据进行base64编码之后再进行嵌入。
  • 3.如果非文本则为可选的base64标记
  • 4.数据本身
    1
    2
     data:,Hello%2C%20World!
    /* 简单的 text/plain 类型数据 */
    1
    2
      data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
    /* 上一条示例的 base64 编码版本 */
    1
    2
      data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
    /* 一个HTML文档源代码 <h1>Hello, World</h1> */
    1
    2
     data:text/html,<script>alert('hi');</script>
    /* 一个会执行 JavaScript alert 的 HTML 文档。注意 script 标签必须封闭。 */

3.canvas.fillText(text, x, y [, maxWidth]) 在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.

  • text 文本内容
  • (x,y)文本的起点
  • maxWidth 绘制的最大宽度

4.canvas.font = value

当前我们用来绘制文本的样式. 这个字符串使用和 CSS font 属性相同的语法. 默认的字体是 10px sans-serif。

5.canvas.textAlign = value

文本对齐选项. 可选的值包括:start, end, left, right or center. 默认值是 start。

6.canvas.textBaseline = value

基线对齐选项. 可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。

7.canvas.direction = value

文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit。

利用hexo搭建属于自己的github博客

安装依赖环境

Git:https://git-scm.com/downloads
Node:https://nodejs.org/en/download/

如果您的电脑中已经安装上述必备程序,那么恭喜您!接下来只需要使用 npm 即可完成 Hexo 的安装。

  • 安装 Hexo
1
$ npm install -g hexo-cli

安装

  • 安装 Git
    下载并安装 Git.
  • 安装 Node
    下载并安装 Node
    • 检查是否安装成功
1
$ node -v

node_v

  • 安装 Hexo
1
$ npm install -g hexo-cli
  • 检查是否安装成功
1
$ hexo -v

hexo_v

创建 Hexo

  • 新建文件夹并初始化
1
$ hexo init <folder>
  • 进入文件夹
1
$ cd <folder>
  • 安装依赖
1
$ npm install

安装完成,项目结构目录如下

├── _config.yml // 网站的配置信息
├── package.json // 应用程序信息
├── scaffolds // 模板文件夹
├── source // 存放用户资源
│ ├── _drafts
│ ├── _post
└── themes // 主题

  • 创建
1
$ hexo g
  • 在服务端打开
1
$ hexo server

server
你就可以查看你的 hexo 了,默认端口 4000,http://localhost:4000

新建 git 仓库项目

Github 账户注册和新建项目

  • 新建
    new
  • 项目名称格式: githubname.github.io,如:zhangsan.github.io
    注意:一定要是你注册 github 的用户名+github.io
    create_new_repo
  • Github Pages
    选择 settings,下拉至 Github Pages,你就发现你刚才新建的项目已经部署到网上了,可以直接访问
    github_pages

将 git 仓库与 hexo 关联起来

在所在文件夹 打开 Git Bash

  • 设置你的 github 用户名和邮箱
1
2
3
4
$ git config --global user.name "github_name"
$ git config --global user.emil "github_emil"

//你的github注册名和注册邮箱

emil

  • 检查是否存在 ssh key
1
$ cd ~/.ssh
  • 如果已经存在,可可以看见该.ssh 文件夹
    ssh_folder
  • 如果没有则需要去生成
1
2
$ ssh-keygen -t rsa -C "github_emil"
// 三次回车,就会生成key

key

  • 进入.ssh 文件夹,可以看见三个文件,id_rsa 是你的私钥,id_rsa.pub 是公钥,需要放在 github 上,这样你每次提交代码到仓库,都会进行本地的私钥和 git 混的公钥进行匹配,匹配完成,你才能进行一系列的操作
    ssh_folder
  • 打开 id_rsa.pub,复制里面的内容到 github 上的 SSH key 中(最后一行包含的是你的注册邮箱的信息)
    ssh_text
  • 登录 Github,点击头像下的 settings
    set_ssh
  • 选择 SSH and GPG keys
  • 找到右侧 New SSH key
    ssh_key
  • title 随便填写,将复制的 id_rsa.pub 内容放至 key 中,点击Add SSH key保存,即可
  • 输入 ssh -T git@github.com,测试添加 ssh 是否成功
1
$ ssh -T git@github.com

如果看见Hi,xxxxx…,说明你就成功了
test_ssh

新建文章

1
$ hexo new post "如何利用Hexo-Github搭建博客"

配置 deploy

  • 打开根目录下的_config.yml 文件
  • deploy:
    • type: git
    • repo: git@github.com:githubname/githubname.github.io.git
    • branch: master

安装插件hexo-deployer-git,可以自动部署至github

1
$ npm install hexo-deployer-git --save

生成文章

1
$ hexo g

完成部署

1
$ hexo d

打开 https://githubname.github.io/ ,查看你的博客吧!

如果你还想在你的博客中插入如图片,

1.安装插件 hexo-asset-image

1
$ npm install https://github.com/CodeFalling/hexo-asset-image --save

2.配置_config.yml

1
2
post_asset_folder: true 
// 可以在新建.md文件的时候,同步建一个同名的文件夹,放置图片等资料

当资源文件管理功能打开后,Hexo将会在你每一次通过 hexo new [layout] 命令创建新文章时自动创建一个文件夹。这个资源文件夹将会有与这个文章文件一样的名字。将所有与你的文章有关的资源放在这个关联文件夹中之后,你可以通过相对路径来引用它们,这样你就得到了一个更简单而且方便得多的工作流。

3.新建文章

1
$ hexo new post "test"

执行上述命令后,会生成test.md和test文件夹,将文章所需图片放置在test文件夹中

3.使用

方法1. 使用相对路径的常规 markdown 语法

test文件夹中,放一张图片 test.jpg

1
![test](test.jpg)
方法2. 相对路径引用的标签插件
1
{% asset_img slug [title] %}

比如 图片test.jpg

1
{% asset_img test.jpg This is an example image %}

以下时两种方式,生成dom的对比

1
2
//  方法1
<img src="/2019/12/13/test/test.jpg" alt="test">
1
2
// 方法2
<img src="/2019/12/13/test/test.jpg" class="" title="This is an example image">

关于 Hexo 的详细配置

配置信息 _config.yml

Site(网站)

参数 描述
title 网站标题
subtitle 网站副标题
description 网站描述,description 主要用于 SEO
keywords 关键字
author 你的名字
language 网站使用的语言
timezone 网站时区,默认是你电脑的时区

URL(网址)

参数 描述 默认值
url 网址
root 网站根目录
permalink 文章的永久链接格式 :year/:month/:day/:title/
permalink_defaults 永久链接中各部分的默认值
网站存放在子目录

如果你的网站存放在子目录中:http://yoursite.com/blog,则:
url:http://yoursite.com/blog
root:/blog/

Directory(目录)

参数 描述 默认值
source_dir 资源文件夹,这个文件夹用来存放内容 source
public_dir 公共文件夹,这个文件夹用于存放生成的站点文件 public
tag_dir 标签文件夹 tags
archive_dir 归档文件夹 archives
category_dir 分类文件夹 categories
code_dir Include code 文件夹 downloads/code
i18n_dir 国际化文件夹 :lang
skip_render 跳过指定文件的渲染

tips:如果您刚刚开始接触 Hexo,通常没有必要修改这一部分的值。

Writing(文章)

参数 描述 默认值
new_post_name 新建文章的名称 :title.md
default_layout 预设布局 post
auto_spacing 在中文和英文之间加入空格 false
titlecase 把标题转为 title case false
external_link 在新标签中打开链接 true
filename_case 把文件名称转换为小写(1)或者大写(2) 0
render_drafts 显示草稿 false
post_asset_folder 启动 Asset 文件夹 true
relative_link 把链接改为与根目录的相对位址 false
future 现实未来的文章 true
highlight 代码块的设置

Category & Tag(分类&标签)

参数 描述 默认值
default_category 默认分类 uncategorized
category_map 分类别名
tag_map 标签别名

Date / Time format

Hexo 使用 Moment.js 来解析和显示时间。

参数 描述 默认值
date_format 日期格式 YYYY-MM-DD
time_format 时间格式 HH:mm:ss

Pagination(分页)

参数 描述 默认值
per_page 每页显示的文章量 (0 = 关闭分页功能) 10
pagination_dir 分页目录 page

Extensions(扩展)

Plugins
Themes

参数 描述 默认值
theme 当前主题,值为 false 时禁用主题 landscape

Deployment

Docs

├──deploy //配置
│ ├──type: git //类型
│ ├──repo: git@github.com:githubname/githubname.github.io.git //新建仓库地址,注意 githubname 是你的 github 名称
│ ├──branch: master //分支

常用命令

  • init 新建一个网站
1
$ hexo init <folder>

如果没有设置文件夹,hexo 默认在当前文件夹新建

  • new 新建一篇文章
1
$ hexo new [layout] <title>

如果没有设置 layout 的话,默认使用 _config.yml 中的 default_layout 参数代替。默认是 post,如果标题包含空格的话,请使用引号括起来。

  • 布局(Layout)
    hexo 三种默认布局:post、page、draft

    布局 路径
    post source/_posts
    page source
    draft source/_drafts
  • 文件名称(title)
    Hexo 默认以标题做为文件名称,但您可编辑 new_post_name 参数来改变默认的文件名称,举例来说,设为 :year-:month-:day-:title.md 可让您更方便的通过日期来管理文章。

    变量 描述
    :title 标题(小写,空格将会被替换为短杠)
    :year 建立的年份,比如, 2015
    :month 建立的月份(有前导零),比如, 04
    :i_month 建立的月份(无前导零),比如, 4
    :day 建立的日期(有前导零),比如, 07
    :i_day 建立的日期(无前导零),比如, 7
  • generate 生成静态文件
1
$ hexo generate

也可以简写为:

1
$ hexo g
参数 描述
-d,–deploy 文件生成后立即部署网站
-w,–watch 监视文件变动
1
$ hexo g -d
1
$ hexo g -w
  • publish 发布草稿

通过 publish 命令将草稿移动到 source/_posts 文件夹,该命令的使用方式与 new 十分类似,您也可在命令中指定 layout 来指定布局

1
$ hexo publish [layout] <filename>
  • server 启动服务器
1
$ hexo server
参数 描述
-p,–port 重设端口
-s,–static 只使用静态文件
-l,–log 启动日志记录,使用覆盖记录格式
  • deploy 部署网站
1
$ hexo deploy

也可以简写为:

1
$ hexo d
参数 描述
-g, –generate 部署之前预先生成静态文件
1
$ hexo d -g

注意两者区别:

1
2
$ hexo g -d // 文件生成后立即部署网站(新生成的文件)
$ hexo d -g // 部署之前预先生成静态文件(之前已经生成的文件)
  • render 渲染文件
1
$ hexo render <file1> [file2] ...
参数 描述
-o, –output 设置输出路径
  • migrate 从其他博客系统
1
$ hexo migrate <type>
  • clean 清除缓存文件
1
$ hexo clean
  • list 列出网站资料。
1
$ hexo list <type>
  • version 显示 Hexo 版本。
1
$ hexo version
  • 安全模式
1
$ hexo --safe

在安全模式下,不会载入插件和脚本。当您在安装新插件遭遇问题时,可以尝试以安全模式重新执行。

  • 调试模式
1
$ hexo --debug

在终端中显示调试信息并记录到 debug.log。当您碰到问题时,可以尝试用调试模式重新执行一次,并 提交调试信息到 GitHub。

  • 简洁模式
1
$ hexo --silent

隐藏终端信息。

  • 自定义配置文件的路径
1
$ hexo --config custom.yml

自定义配置文件的路径,执行后将不再使用 _config.yml。

  • 显示草稿
1
$ hexo --draft

显示 source/_drafts 文件夹中的草稿文章。

  • 自定义 CWD
1
$ hexo --cwd /path/to/cwd

自定义当前工作目录(Current working directory)的路径。

Scaffold(模板)

在新建文章时,Hexo 会根据 scaffolds 文件夹内相对应的文件来建立文件,

1
$ hexo new photo "My Gallery"

在执行这行指令时,Hexo 会尝试在 scaffolds 文件夹中寻找 photo.md,并根据其内容建立文章,

新建文章模板

1
$ hexo new post "My Gallery"

新建分页模板

1
$ hexo new page "My Gallery"

新建草稿模板

1
$ hexo new draft "My Gallery"

以下是你可以在模版中使用的变量:

变量 描述
layout 布局
title 标题
date 文件建立日期

Hexo文档

Hexo文档