反正我是觉得markdown不如博客园的默认编辑器好用= = 把有道的笔记搬到博客园。。
网视频《 》&《 》笔记
↑老师讲的很好,不过语速很慢,二倍速刚好。
通过 即可创建一个canvas。
不建议直接使用css的方式指定大小。css指定的是显示的大小,通过height和width指定的是显示的大小以及分辨率的大小。
JavaScript中指定canvas宽高。
canvas.height = 768;
canvas 绘图主要通过 canvas.getContext 的获得的上下文的 api 实现。
canvas坐标轴 :左上角为原点,向右为x轴,向下为y轴。
canvas 是基于状态的绘图。
context.fill();
context.linewidth = 5<span style="color: #000000;">;
context.strokeStyle = '#123456'<span style="color: #000000;">;
context.stroke();
context.beginPath();
context.moveto(200,600<span style="color: #000000;">);
context.strokeStyle = 'black'<span style="color: #000000;">;
context.stroke();
moveto(x,y)
画笔移到(x,y)。
lineto(x,y)
从当前点到(x,y)画一条。
stroke()
把当前的路径绘制出来,但并不会清空当前状态(也就是说下一次调用stroke之前绘制的会再次被绘制)。
fill()
如果路径不是封闭的,会把路径首尾相连。
beginPath()
开始一段新的路径,也就是说,此后再次调用stroke()的时候,之前的线条不会被重新绘制。同时清空当前坐标。(紧接着的lineto()相当于moveto())
closePath()
结束一段路径。如果路径没有封闭,就将路径首尾连接起来。
context.linewidth,context.strokeStyle
设置绘制线条宽度和样式。
context.fillStyle
设置填充样式。
绘制圆和弧
通过定时器不断更新状态重新绘制
清空指定区域
一个七巧板">画一个七巧板
<span style="color: #0000ff;"><</span><span style="color: #800000;">script</span><span style="color: #0000ff;">></span>
<span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> t<a href="https://www.jb51.cc/tag/angr/" target="_blank" class="keywords">angr</a>am </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> [
{p:[{x:</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">},{x:</span><span style="background-color: #f5f5f5; color: #000000;">800</span><span style="background-color: #f5f5f5; color: #000000;">,{x:</span><span style="background-color: #f5f5f5; color: #000000;">400</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">400</span><span style="background-color: #f5f5f5; color: #000000;">}],color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">green</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">},{p:[{x:</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">400</span><span style="background-color: #f5f5f5; color: #000000;">},{x:</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">800</span><span style="background-color: #f5f5f5; color: #000000;">}],color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">red</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">},{p:[{x:</span><span style="background-color: #f5f5f5; color: #000000;">800</span><span style="background-color: #f5f5f5; color: #000000;">,{x:</span><span style="background-color: #f5f5f5; color: #000000;">600</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">600</span><span style="background-color: #f5f5f5; color: #000000;">},y:</span><span style="background-color: #f5f5f5; color: #000000;">200</span><span style="background-color: #f5f5f5; color: #000000;">}],color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">yellow</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">},{p:[{x:</span><span style="background-color: #f5f5f5; color: #000000;">600</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">200</span><span style="background-color: #f5f5f5; color: #000000;">},color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">blue</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">},{p:[{x:</span><span style="background-color: #f5f5f5; color: #000000;">400</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">800</span><span style="background-color: #f5f5f5; color: #000000;">},{x:</span><span style="background-color: #f5f5f5; color: #000000;">200</span><span style="background-color: #f5f5f5; color: #000000;">,y:</span><span style="background-color: #f5f5f5; color: #000000;">600</span><span style="background-color: #f5f5f5; color: #000000;">}],color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">pink</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">},{p:[{x:</span><span style="background-color: #f5f5f5; color: #000000;">200</span><span style="background-color: #f5f5f5; color: #000000;">,color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">black</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">},color:</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">gray</span><span style="background-color: #f5f5f5; color: #000000;">"</span><span style="background-color: #f5f5f5; color: #000000;">}
];
window.onload </span><span style="background-color: #f5f5f5; color: #000000;">=</span> <span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;">() {
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> canvas </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> document.getElementById(</span><span style="background-color: #f5f5f5; color: #000000;">'</span><span style="background-color: #f5f5f5; color: #000000;">canvas</span><span style="background-color: #f5f5f5; color: #000000;">'</span><span style="background-color: #f5f5f5; color: #000000;">);
</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> context </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> canvas.getContext(</span><span style="background-color: #f5f5f5; color: #000000;">'</span><span style="background-color: #f5f5f5; color: #000000;">2d</span><span style="background-color: #f5f5f5; color: #000000;">'</span><span style="background-color: #f5f5f5; color: #000000;">);
</span><span style="background-color: #f5f5f5; color: #0000ff;">for</span><span style="background-color: #f5f5f5; color: #000000;"> (</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> i </span><span style="background-color: #f5f5f5; color: #000000;">=</span> <span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">; i </span><span style="background-color: #f5f5f5; color: #000000;"><</span><span style="background-color: #f5f5f5; color: #000000;"> t<a href="https://www.jb51.cc/tag/angr/" target="_blank" class="keywords">angr</a>am.length; i</span><span style="background-color: #f5f5f5; color: #000000;">++</span><span style="background-color: #f5f5f5; color: #000000;">) {
draw(t<a href="https://www.jb51.cc/tag/angr/" target="_blank" class="keywords">angr</a>am[i],context);
}
}
</span><span style="background-color: #f5f5f5; color: #0000ff;">function</span><span style="background-color: #f5f5f5; color: #000000;"> draw(piece,ctx) {
ctx.beginPath();
ctx.mov<a href="https://www.jb51.cc/tag/eto/" target="_blank" class="keywords">eto</a>(piece.p[</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">].x,piece.p[</span><span style="background-color: #f5f5f5; color: #000000;">0</span><span style="background-color: #f5f5f5; color: #000000;">].y);
</span><span style="background-color: #f5f5f5; color: #0000ff;">for</span><span style="background-color: #f5f5f5; color: #000000;"> (</span><span style="background-color: #f5f5f5; color: #0000ff;">var</span><span style="background-color: #f5f5f5; color: #000000;"> i </span><span style="background-color: #f5f5f5; color: #000000;">=</span> <span style="background-color: #f5f5f5; color: #000000;">1</span><span style="background-color: #f5f5f5; color: #000000;">; i </span><span style="background-color: #f5f5f5; color: #000000;"><</span><span style="background-color: #f5f5f5; color: #000000;"> piece.p.length; i</span><span style="background-color: #f5f5f5; color: #000000;">++</span><span style="background-color: #f5f5f5; color: #000000;">) {
ctx.lin<a href="https://www.jb51.cc/tag/eto/" target="_blank" class="keywords">eto</a>(piece.p[i].x,piece.p[i].y);
}
ctx.closePath();
ctx.fillStyle </span><span style="background-color: #f5f5f5; color: #000000;">=</span><span style="background-color: #f5f5f5; color: #000000;"> piece.color;
ctx.fill();
}
</span><span style="color: #0000ff;"></</span><span style="color: #800000;">script</span><span style="color: #0000ff;">></span>
<span style="color: #0000ff;"></
<span style="color: #800000;">body<span style="color: #0000ff;">><span style="color: #0000ff;"></<span style="color: #800000;">html<span style="color: #0000ff;">>
效果
index.html
<span style="color: #0000ff;"><</span><span style="color: #800000;">script </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="digit.js"</span><span style="color: #0000ff;">></</span><span style="color: #800000;">script</span><span style="color: #0000ff;">></span>
<span style="color: #0000ff;"><</span><span style="color: #800000;">script </span><span style="color: #ff0000;">src</span><span style="color: #0000ff;">="countdown.js"</span><span style="color: #0000ff;">></</span><span style="color: #800000;">script</span><span style="color: #0000ff;">></span>
<span style="color: #0000ff;"></
<span style="color: #800000;">body<span style="color: #0000ff;">><span style="color: #0000ff;"></<span style="color: #800000;">html<span style="color: #0000ff;">>
countdown.js 和老师写的不完全一样,因为我懒得看了,所以小部分偷懒自己瞎写的
const colors = ['#ff5b5b','#a2ff95','#95ffc8','#95b2ff','#c195ff','#ff95f4','#ff95c3','#ffe295'<span style="color: #000000;">];
window.onload
= <span style="color: #0000ff;">function<span style="color: #000000;">() {WINDOW_HEIGHT </span>= document.body.clientHeight-1<span style="color: #000000;">;
WINDOW_WIDTH </span>= document.body.clientWidth-1<span style="color: #000000;">;
MARGIN_LEFT </span>= Math.round(WINDOW_WIDTH / 10<span style="color: #000000;">);
RADIUS </span>= Math.round(WINDOW_WIDTH * 4 / 5 / 108) - 1<span style="color: #000000;">;
MARGIN_TOP </span>= Math.round(WINDOW_HEIGHT / 5<span style="color: #000000;">);
</span><span style="color: #0000ff;">var</span> canvas = document.getElementById('canvas'<span style="color: #000000;">);
</span><span style="color: #0000ff;">var</span> context = canvas.getContext('2d'<span style="color: #000000;">);
canvas.width </span>=<span style="color: #000000;"> WINDOW_WIDTH;
canvas.height </span>=<span style="color: #000000;"> WINDOW_HEIGHT;
console.log(canvas);
curShowTimeSeconds </span>= 3 * 3600; <span style="color: #008000;">//</span><span style="color: #008000;"> 倒计时三小时</span>
<span style="color: #0000ff;">var</span> timer =<span style="color: #000000;"> setInterval(
</span><span style="color: #0000ff;">function</span><span style="color: #000000;">() {
render(context);
renderBalls(context);
curShowTimeSeconds </span>-= 1/50;
<span style="color: #000000;"> update();
curShowTimeSeconds = 0<span style="color: #000000;">;
clearInterval(timer);
}
},20<span style="color: #000000;">
)
}
<span style="color: #0000ff;">function<span style="color: #000000;"> update() {
<span style="color: #0000ff;">var tempBalls =<span style="color: #000000;"> [];
<span style="color: #0000ff;">for (<span style="color: #0000ff;">var<span style="color: #000000;"> ball of balls) {
ball.x +=<span style="color: #000000;"> ball.vx;
ball.y +=<span style="color: #000000;"> ball.vy;
ball.vy +=<span style="color: #000000;"> ball.g;
<span style="color: #0000ff;">if (ball.y >= 768 -<span style="color: #000000;"> ball.r) {
ball.y = 768 -<span style="color: #000000;"> ball.r;
ball.vy = -ball.vy * 0.75<span style="color: #000000;">;
}
<span style="color: #0000ff;">if (ball.x + RADIUS > 0 && ball.x - RADIUS <<span style="color: #000000;"> WINDOW_WIDTH) {
tempBalls.push(ball);
}
}
balls =<span style="color: #000000;"> tempBalls;
</span><span style="color: #0000ff;">var</span> seconds = curShowTimeSeconds % 60<span style="color: #000000;">;
</span><span style="color: #0000ff;">if</span> (Math.floor(curShowTimeSeconds) !== Math.floor(curShowTimeSeconds + 1/50)) {
addBalls(MARGIN_LEFT + 78*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10));
addBalls(MARGIN_LEFT + 93*(RADIUS+1),parseInt(seconds%10<span style="color: #000000;">));
}
}
<span style="color: #0000ff;">function<span style="color: #000000;"> addBalls(x,y,num) {
<span style="color: #0000ff;">for (<span style="color: #0000ff;">var i = 0; i < digit[num].length; i++<span style="color: #000000;">) {
<span style="color: #0000ff;">for (<span style="color: #0000ff;">var j = 0; j < digit[num][i].length; j++<span style="color: #000000;">) {
<span style="color: #0000ff;">if (digit[num][i][j] === 1) { <span style="color: #008000;">//<span style="color: #008000;"> 点阵中1表示绘制
<span style="color: #000000;"> balls.push({
x: x+j2(RADIUS+1)+(RADIUS+1<span style="color: #000000;">),y: y+i2(RADIUS+1)+(RADIUS+1<span style="color: #000000;">),r: RADIUS,g: 1.5 +<span style="color: #000000;"> Math.random(),vx: Math.pow(-1,Math.ceil(Math.random() 1000)) 4<span style="color: #000000;">,vy: -10<span style="color: #000000;">,color: colors[Math.floor(Math.random() *<span style="color: #000000;"> colors.length)]
});
}
}
}
}
<span style="color: #0000ff;">function<span style="color: #000000;"> render(ctx) {
ctx.clearRect(0,0<span style="color: #000000;">,WINDOW_WIDTH,WINDOW_HEIGHT);
</span><span style="color: #0000ff;">var</span> hours = parseInt(curShowTimeSeconds / 3600<span style="color: #000000;">);
</span><span style="color: #0000ff;">var</span> minutes = parseInt((curShowTimeSeconds - hours * 3600) / 60<span style="color: #000000;">);
</span><span style="color: #0000ff;">var</span> seconds = curShowTimeSeconds % 60<span style="color: #000000;">;
renderDigit(MARGIN_LEFT,parseInt(hours</span>/10),ctx);
renderDigit(MARGIN_LEFT + 15*(RADIUS+1),parseInt(hours%10<span style="color: #000000;">),ctx)
renderDigit(MARGIN_LEFT </span>+ 30*(RADIUS + 1),10<span style="color: #000000;">,ctx)
renderDigit(MARGIN_LEFT </span>+ 39*(RADIUS+1),parseInt(minutes/10),ctx);
renderDigit(MARGIN_LEFT + 54*(RADIUS+1),parseInt(minutes%10<span style="color: #000000;">),ctx);
renderDigit(MARGIN_LEFT </span>+ 69*(RADIUS+1),ctx);
renderDigit(MARGIN_LEFT </span>+ 78*(RADIUS+1),parseInt(seconds/10),ctx);
renderDigit(MARGIN_LEFT + 93*(RADIUS+1),parseInt(seconds%10<span style="color: #000000;">),ctx);
}
<span style="color: #0000ff;">function<span style="color: #000000;"> renderBalls(ctx) {
balls.forEach((ball) =><span style="color: #000000;"> {
ctx.fillStyle =<span style="color: #000000;"> ball.color;
ctx.beginPath();
ctx.arc(ball.x,ball.y,ball.r,0,2 *<span style="color: #000000;"> Math.PI);
ctx.closePath();
ctx.fill();
})
}
<span style="color: #008000;">//<span style="color: #008000;"> 在 (x,y) 为起点 画一个数字 num
<span style="color: #0000ff;">function<span style="color: #000000;"> renderDigit(x,num,ctx) {
ctx.fillStyle = 'rgb(0,102,153)'<span style="color: #000000;">;
</span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = 0; i < digit[num].length; i++<span style="color: #000000;">) {
</span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> j = 0; j < digit[num][i].length; j++<span style="color: #000000;">) {
</span><span style="color: #0000ff;">if</span> (digit[num][i][j] === 1) { <span style="color: #008000;">//</span><span style="color: #008000;"> 点阵中1表示绘制</span>
<span style="color: #000000;"> ctx.beginPath();
ctx.arc(x+j2(RADIUS+1)+(RADIUS+1),y+i2(RADIUS+1)+(RADIUS+1),RADIUS,2*<span style="color: #000000;">Math.PI);
ctx.closePath();
ctx.fill();
}
}
}
}
digit.js 这个是复制老师的
封闭多边形的首尾交点会有缺口,使用 能解决这个问题。
绘制封闭多边形最好成对使用 和
先绘制线条再填充颜色,边框的一半会被填充色覆盖。所以先绘制填充色再描边。
绘制矩形api:
ctx.fillRect(x,height);
ctx.strokeRect(x,height);
fillStyle 和 strokeStyle 支持所有CSS支持的颜色表示。
线条的属性
- lineCap 线条两端的形状: butt (默认,平的)round(圆的) square(方的) 后面两个比较butt会突出来。只用于线段结尾处,不用于连接处。
- lineJoin 线条连接处形状: miter(默认,尖角)bevel(平的) round(圆角)miter
- lineJoin 为 miter 时,延长线长度大于miterLimit,会自动变为bevel。miterLimit 默认为10。
图形变换
位移、旋转、缩放。
默认多个translate会叠加。
不仅会缩放长度、宽度,还会缩放坐标、边框长度等属性。
save(); restore(); 成对出现,中间绘图状态不会对后面造成影响。
context.transform(); 效果会叠加
如果需要重新初始化矩阵变换的值,用: 会使得之前设置的 context.transform() 失效