canvas基础简单易懂教程(完结,多图)

Python微信订餐小程序课程视频

https://blog.csdn.net/m0_56069948/article/details/122285951

Python实战量化交易理财系统

https://blog.csdn.net/m0_56069948/article/details/122285941
目录* Canvas学习
+ 一、 Canvas概述
- 1.1 Hello world
- 1.2 Canvas的像素化
- 1.3 Canvas的动画思想
- 1.4 面向对象思维实现canvas动画
+ 二、Canvas的绘制功能
- 2.1 绘制矩形
- 2.2 绘制路径
- 2.3 绘制圆弧
- 2.4 炫彩小球
- 2.5 透明度
- 2.6 小球连线
- 2.7 线型
* lineWidth
* lineCap
* lineJoin
* setLineDash
* lineDashOffset
- 2.8 文本
- 2.9 渐变 Gradients
- 2.10 阴影
+ 三、使用图片
+ 四、资源管理器
+ 4.1 获取对象中属性的长度
+ 4.2 管理器的实现
+ 五、变形
- 5.1 移动translate
- 5.2 旋转 rotate
- 5.3 缩放 scale
- 5.4 变形 transform
- 5.5 滚动的车轮案例
+ 六、合成与裁剪
- 6.1 globalCompositeOperation
- 6.2 裁剪路径
- 6.3 刮刮乐案例
+ 七、总结

Canvas学习

canvas 读音 /ˈkænvəs/, 即kæn və s(看我死).

学习的目的主要是为了网状关系拓扑图形的绘制.

推荐文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial

一、 Canvas概述

canvas是用来绘制图形的.它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。

长久以来, web上的动画都是Flash. 比如动画广告\ 游戏等等, 基本都是Flash 实现的. Flash目前都被禁用了, 而且漏洞很多, 重量很大, 需要安装Adobe Flash Player, 而且也会卡顿和不流畅等等.

canvas是HTML5提出的新标签,彻底颠覆了Flash的主导地位。无论是广告、游戏都可以使用canvas实现。

Canvas 是一个轻量级的画布, 我们使用Canvas进行JS的编程,不需要增加额外的组件,性能也很好,不卡顿,在手机中也很流畅。

1.1 Hello world

我们可以在页面中设置一个canvas标签



|  |  |
|  |  当前的浏览器版本不支持,请升级浏览器 |
|  | canvas> |


canvas的标签属性只有两个,width和height,表示的是canvas画布的宽度和高度,不要用css来设置,而是用属性来设置,画布会失真变形。

标签的innerContent是用来提示低版本浏览器(IE6、7、8)并不能正常使用canvas,高版本的浏览器是看不到canvas标签内部的文字的。

canvas基础简单易懂教程(完结,多图)_第1张图片



|  | // 得到canvas的画布 |
|  | const myCanvas:HTMLCanvasElement = document.getElementById("main\_canvas") as HTMLCanvasElement// 返回某种类型的HTMLElement |
|  |  |
|  | // 得到画布的上下文,上下文有两个,2d的上下文和3d的上下文 |
|  | // 所有的图像绘制都是通过ctx属性或者是方法进行设置的,和canvas标签没有关系了 |
|  | const ctx = myCanvas.getContext("2d") |
|  | if(ctx !== null) { |
|  | // 设置颜色 |
|  |  ctx.fillStyle = 'green' |
|  | // 绘制矩形 |
|  |  ctx.fillRect(100, 100, 200, 50)  |
|  | } |


canvas基础简单易懂教程(完结,多图)_第2张图片

通过上面的代码我们发下canvas本质上就是利用代码在浏览器的页面上进行画画,比如上面的代码fillRect就代表在页面中绘制矩形,一共四个属性,前两个100,100代表(x, y), 即填充起始位置,200代表宽,50代表高,单位都是px。

1.2 Canvas的像素化

我们用canvas绘制了一个图形,一旦绘制成功了,canvas就像素化了他们。canvas没有能力,从画布上再次得到这个图形,也就是我们没有能力去修改已经在画布上的内容,这个就是canvas比较轻量的原因,Flash重的原因之一就有它可以通过对应的api得到已经上“画布”的内容然后再次绘制

如果我们想要这个canvas图形移动,必须按照:清屏——更新——渲染的逻辑进行编程。总之,就是重新再画一次

1.3 Canvas的动画思想

要使用面向对象的思想来创建动画。

canvas上画布的元素,就被像素化了,所以不能通过style.left方法进行修改,而且必须要重新绘制。



|  | // 得到画布 |
|  | const myCanvas:HTMLCanvasElement = document.getElementById("main\_canvas") as HTMLCanvasElement |
|  |  |
|  | // 获取上下文 |
|  | const ctx = myCanvas.getContext("2d") |
|  |  |
|  | if(ctx !== null) { |
|  | // 设置颜色 |
|  |  ctx.fillStyle = "blue" |
|  | // 初始信号量 |
|  | let left:number = -200 |
|  | // 动画过程 |
|  | setInterval(() => { |
|  | // 清除画布,0,0代表从什么位置开始,600,600代表清除的宽度和高度 |
|  |  ctx.clearRect(0,0,600,600) |
|  | // 更新信号量 |
|  |  left++ |
|  | // 如果已经走出画布,则更新信号量为初始位置 |
|  | if(left > 600) { |
|  |  left = -200 |
|  |  } |
|  |  ctx.fillRect(left, 100, 200, 200) |
|  |  },10) |
|  | } |


canvas基础简单易懂教程(完结,多图)_第3张图片

实际上,动画的生成就是相关静态画面连续播放,这个就是动画的过程。我们把每一次绘制的静态话面叫做一帧,时间的间隔(定时器的间隔)就是表示的是帧的间隔。

1.4 面向对象思维实现canvas动画

因为canvas不能得到已经上屏的对象,所以我们要维持对象的状态。在canvas动画重,我们都是用面向对象来进行编程,因为我们可以使用面向对象的方式来维持canvas需要的属性和状态;



|  | // 得到画布 |
|  | const myCanvas:HTMLCanvasElement = document.getElementById("main\_canvas") as HTMLCanvasElement |
|  |  |
|  | // 获取上下文 |
|  | const ctx = myCanvas.getContext("2d") |
|  |  |
|  | class Rect { |
|  | // 维护状态 |
|  | constructor( |
|  | public x: number, |
|  | public y: number,  |
|  | public w: number,  |
|  | public h: number,  |
|  | public color: string |
|  |  ) {  |
|  |  } |
|  | // 更新的方法 |
|  | update() { |
|  | this.x++ |
|  | if(this.x > 600) { |
|  | this.x = -200 |
|  |  } |
|  |  } |
|  | // 渲染 |
|  | render(ctx: CanvasRenderingContext2D) { |
|  | // 设置颜色 |
|  |  ctx.fillStyle = this.color |
|  | // 渲染 |
|  |  ctx.fillRect(this.x, this.y, this.w, this.h) |
|  |  } |
|  | } |
|  |  |
|  | // 实例化 |
|  | let myRect1: Rect = new Rect(-100, 200, 100, 100, 'purple') |
|  | let myRect2: Rect = new Rect(-100, 400, 100, 100, 'pink') |
|  |  |
|  | // 动画过程 |
|  |  |
|  | // 更新的办法 |
|  | setInterval(() => { |
|  | // 清除画布,0,0代表从什么位置开始,600,600代表清除的宽度和高度 |
|  | if(ctx !== null) { |
|  | // 清屏 |
|  |  ctx.clearRect(0,0,600,600) |
|  | // 更新方法 |
|  |  myRect1.update() |
|  |  myRect2.update() |
|  | // 渲染方法 |
|  |  myRect1.render(ctx) |
|  |  myRect2.render(ctx) |
|  |  } |
|  | },10) |


canvas基础简单易懂教程(完结,多图)_第4张图片

动画过程在主定时器重,每一帧都会调用实例的更新和渲染方法。

二、Canvas的绘制功能

2.1 绘制矩形

填充一个矩形:



|  | if(ctx !== null) { |
|  | // 设置颜色 |
|  |  ctx.fillStyle = 'green' |
|  | // 填充矩形 |
|  |  ctx.fillRect(100, 100, 300, 50) |
|  | } |


参数含义:分别代表填充坐标x、填充坐标y、矩形的高度和宽度。

绘制矩形边框,和填充不同的是绘制使用的是strokeRect, 和strokeStyle实现的



|  | if (ctx !== null) { |
|  | // 设置颜色 |
|  |  ctx.strokeStyle = 'red' |
|  | // 绘制矩形 |
|  |  ctx.strokeRect(300, 100, 100, 100) |
|  | } |


参数含义:分别代表绘制坐标x、绘制坐标y、矩形的高度和宽度。

canvas基础简单易懂教程(完结,多图)_第5张图片

清除画布,使用clearRect



|  | // 擦除画布内容 |
|  | btn3.onclick = () => { |
|  | if (ctx !== null) { |
|  |  ctx.clearRect(0, 0, 600, 600) |
|  |  } |
|  | } |


参数含义:分别代表擦除坐标x、擦除坐标y、擦除的高度和擦除的宽度。

2.2 绘制路径

绘制路径的作用是为了设置一个不规则的多边形状态

路径都是闭合的,使用路径进行绘制的时候需要既定的步骤:

  1. 需要设置路径的起点
  2. 使用绘制命令画出路径
  3. 封闭路径
  4. 填充或者绘制已经封闭路径的形状


|  | // 创建一个路径 |
|  | ctx.beginPath() |
|  | // 1. 移动绘制点 |
|  | ctx.moveTo(100, 100) |
|  | // 2. 描述行进路径 |
|  | ctx.lineTo(200, 200) |
|  | ctx.lineTo(400, 180) |
|  | ctx.lineTo(380, 50) |
|  | // 3. 封闭路径 |
|  | ctx.closePath(); |
|  |  |
|  | // 4. 绘制这个不规则的图形 |
|  | ctx.strokeStyle = 'red' |
|  | ctx.stroke() |
|  | ctx.fillStyle = 'orange' |
|  | ctx.fill() |


canvas基础简单易懂教程(完结,多图)_第6张图片

总结我们要绘制一个图形,要按照顺序

  1. 开始路径ctx.beginPath()
  2. 移动绘制点ctx.moveTo(x, y)
  3. 描述绘制路径ctx.lineTo(x, y)
  4. 多次描述绘制路径ctx.lineTo(x, y)
  5. 闭合路径ctx.closePath()
  6. 描边ctx.stroke()
  7. 填充ctx.fill()

此时我们发现之前我们在学习绘制矩形的时候使用的是fillRectstrokeRect,但是实际上fillstroke也是具有绘制填充功能的

stroke(): 通过线条来绘制图形轮廓。

fill(): 通过填充路径的内容区域生成实心的图形。

我们在绘制路径的时候选择不关闭路径(closePath),这个时候会实现自封闭现象(只针对fill,stroke不生效)

canvas基础简单易懂教程(完结,多图)_第7张图片

2.3 绘制圆弧

arc(x, y, radius, startAngle, endAngle, anticlockwise)

画一个以(x, y)为圆心的以radius为半径的圆弧(圆), 从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针false, true为逆时针)来生成。



|  | // 创建一个路径 |
|  | ctx.beginPath() |
|  | // 移动绘制点 |
|  | // ctx.arc(200, 200, 100, 0, 2 * Math.PI, false) |
|  | ctx.arc(200, 200, 100, 0, 2 * 3.14, false) |
|  |  |
|  | ctx.stroke() |


圆弧也是绘制路径的一种,也需要beginPath和stroke.

canvas基础简单易懂教程(完结,多图)_第8张图片

参数的含义:200, 200代表的是起始x,y坐标,100代表的是圆心半径,0和1代表的是开始和结束位置,单位如果是数字,代表的是一个圆弧的弧度(一个圆的弧度是Math.PI * 2, 约等于7个弧度),所以在顺时针的情况下,如果如果两个参数的差为7,则代表绘制一个圆。

2.4 炫彩小球



|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById("main\_canvas") as HTMLCanvasElement |
|  |  |
|  | // 获取上下文 |
|  | const ctx = myCanvas.getContext("2d") |
|  |  |
|  | class Ball { |
|  | color: string // 小球的颜色 |
|  | r: number // 小球的半径 |
|  | dx: number // 小球在x轴的运动速度/帧 |
|  | dy: number // 小球在y轴的运动速度/帧 |
|  | constructor(public x: number, public y: number) { |
|  | // 设置随机颜色 |
|  | this.color = this.getRandomColor() |
|  | // 设置随机半径[1, 101) |
|  | this.r = Math.floor(Math.random() * 100 + 1) |
|  | // 设置x轴, y轴的运动速度(-5, 5) |
|  | this.dx = Math.floor(Math.random() * 10) - 5 |
|  | this.dy = Math.floor(Math.random() * 10) - 5 |
|  |  } |
|  | // 随机颜色,最后返回的是类似'#3fe432' |
|  | getRandomColor(): string { |
|  | let allType = "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f" |
|  | let allTypeArr = allType.split(',') |
|  | let color = '#' |
|  | for (let i = 0; i < 6; i++) { |
|  | let random = Math.floor(Math.random() * allTypeArr.length) |
|  |  color += allTypeArr[random] |
|  |  } |
|  | return color |
|  |  } |
|  |  |
|  | // 渲染小球 |
|  | render(): void { |
|  | if(ctx !== null) { |
|  |  ctx.beginPath() |
|  |  ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false) |
|  |  ctx.fillStyle=this.color |
|  |  ctx.fill() |
|  |  } |
|  |  } |
|  |  |
|  | // 更新小球 |
|  | update(): void { |
|  | // 小球的运动 |
|  | this.x += this.dx |
|  | this.y += this.dy |
|  | this.r -= 0.5 |
|  | // 如果小球的半径小于0了,从数组中删除 |
|  | if(this.r <= 0) { |
|  | this.remove() |
|  |  } |
|  |  } |
|  |  |
|  | // 移除小球 |
|  | remove(): void { |
|  | for(let i = 0; i < ballArr.length; i++) { |
|  | if(ballArr[i] === this) { |
|  |  ballArr.splice(i, 1) |
|  |  } |
|  |  } |
|  |  } |
|  | } |
|  | // 维护小球的数组 |
|  | let ballArr: Ball[] = [] |
|  |  |
|  | // canvas设置鼠标监听 |
|  | myCanvas.addEventListener("mousemove", (event)=> { |
|  |  ballArr.push(new Ball(event.offsetX, event.offsetY)) |
|  | }) |
|  |  |
|  |  |
|  | // 定时器进行动画渲染和更新 |
|  | setInterval(function() { |
|  | // 动画的逻辑,清屏-更新-渲染 |
|  | if(ctx !== null) { |
|  |  ctx.clearRect(0, 0, myCanvas.width, myCanvas.height) |
|  |  } |
|  | for(let i = 0; i < ballArr.length; i++) { |
|  | // 小球的更新和渲染 |
|  |  ballArr[i].update() |
|  | if(ballArr[i]) { |
|  |  ballArr[i].render() |
|  |  } |
|  |  |
|  |  } |
|  | // 60 帧 |
|  | }, 1000 / 60) |


2.5 透明度

透明度的值是0到1之间: (1是完全不透明,0是完全透明)



|  | ctx.globalAlpha = 1 |


2.6 小球连线



|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById("mycanvas") as HTMLCanvasElement |
|  |  |
|  | // 获取上下文 |
|  | const ctx = myCanvas.getContext("2d") |
|  |  |
|  | // 设置画布的尺寸 |
|  | myCanvas.width = document.documentElement.clientWidth - 30 |
|  | myCanvas.height = document.documentElement.clientHeight - 30 |
|  |  |
|  | class Ball { |
|  | x: number = Math.floor(Math.random() * myCanvas.width) |
|  | y: number = Math.floor(Math.random() * myCanvas.height) |
|  | r: number = 10 |
|  | color: string = 'gray' |
|  | dx: number = Math.floor(Math.random() * 10) - 5 |
|  | dy: number = Math.floor(Math.random() * 10) - 5 |
|  | constructor() { |
|  |  ballArr.push(this) |
|  |  } |
|  |  |
|  | // 小球的渲染 |
|  | render() { |
|  | if(ctx !== null) { |
|  |  ctx.beginPath() |
|  | // 透明度 |
|  |  ctx.globalAlpha = 1 |
|  | // 画小球 |
|  |  ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false) |
|  |  ctx.fillStyle = this.color |
|  |  ctx.fill() |
|  |  } |
|  |  } |
|  | // 小球的更新 |
|  | update() { |
|  | // 更新x |
|  | this.x += this.dx |
|  | // 纠正x |
|  | if(this.x <= this.r) { |
|  | this.x = this.r |
|  |  } else if ( this.x >= myCanvas.width - this.r) { |
|  | this.x = myCanvas.width - this.r |
|  |  } |
|  | // 更新y |
|  | this.y += this.dy |
|  | // 纠正y |
|  | if(this.y <= this.r) { |
|  | this.y = this.r |
|  |  } else if ( this.y >= myCanvas.height - this.r) { |
|  | this.y = myCanvas.height - this.r |
|  |  } |
|  | // 碰壁返回 |
|  | if(this.x + this.r >= myCanvas.width || this.x - this.r <= 0) { |
|  | this.dx *= -1 |
|  |  } |
|  | if(this.y + this.r >= myCanvas.height || this.y - this.r <= 0) { |
|  | this.dy *= -1 |
|  |  } |
|  |  } |
|  |  |
|  | } |
|  |  |
|  | // 小球数组 |
|  | let ballArr: Ball[] = [] |
|  |  |
|  | // 创建20个小球 |
|  | for(let i = 0; i < 20; i++) { |
|  | new Ball() |
|  | } |
|  |  |
|  | // 定时器动画 |
|  | setInterval(() => { |
|  | // 清除画布 |
|  | if(ctx !== null) { |
|  |  ctx.clearRect(0, 0, myCanvas.width, myCanvas.height) |
|  |  } |
|  | // 小球渲染和更新 |
|  | for(let i = 0; i < ballArr.length; i++) { |
|  |  ballArr[i].render() |
|  |  ballArr[i].update() |
|  |  } |
|  | // 画线的逻辑 |
|  | if(ctx !== null) { |
|  | for(let i = 0; i < ballArr.length; i++) { |
|  | for(let j = i + 1; j < ballArr.length; j++) { |
|  | let distance = Math.sqrt(Math.pow((ballArr[i].x - ballArr[j].x), 2) + Math.pow((ballArr[i].y -ballArr[j].y), 2)) |
|  | if( distance <= 150) { |
|  |  ctx.strokeStyle = '#000' |
|  |  ctx.beginPath() |
|  | // 线的透明度,根据当前已经连线的小球的距离进行线的透明度设置 |
|  | // 距离越近透明度越大,距离越远透明度越小 |
|  |  ctx.globalAlpha = 1 - distance / 150 |
|  |  ctx.moveTo(ballArr[i].x, ballArr[i].y) |
|  |  ctx.lineTo(ballArr[j].x, ballArr[j].y) |
|  |  ctx.closePath() |
|  |  ctx.stroke() |
|  |  } |
|  |  } |
|  |  } |
|  |  } |
|  | }, 1000/60) |


2.7 线型

lineWidth

我们可以利用lineWidth设置线的粗细,属性值为number型,默认为1,没有单位



|  | ctx.lineWidth = 1.0 |


canvas基础简单易懂教程(完结,多图)_第9张图片

lineCap

我们可以使用lineCap指定如何绘制每一条线段末端的属性:"butt" | "round" | "square", 其中butt代表线段末端以方形结束,round表示线段末端以圆形结束,square线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域,默认是butt



|  | ctx.lineCap = "round"; |


canvas基础简单易懂教程(完结,多图)_第10张图片

canvas基础简单易懂教程(完结,多图)_第11张图片

该图是三种lineCapd的类型,从左到右依次为buttroundsquare

lineJoin

我们可以使用lineJoin来设置设置2个长度不为0的相连部分(线段,圆弧,曲线)如何连接在一起的属性(长度为0的变形部分,其指定的末端和控制点在同一位置,会被忽略):"bevel" | "round" | "miter"



|  | ctx.lineJoin = "bevel"; |


  • round表示通过填充一个额外的,圆心在相连部分末端的扇形,绘制拐角的形状。 圆角的半径是线段的宽度。
  • bevel表示在相连部分的末端填充一个额外的以三角形为底的区域, 每个部分都有各自独立的矩形拐角。
  • mitter表示通过延伸相连部分的外边缘,使其相交于一点,形成一个额外的菱形区域。

canvas基础简单易懂教程(完结,多图)_第12张图片

setLineDash

我们可以使用setLineDash方法在填充线时使用虚线模式。



|  | ctx.setLineDash(segments); |


  • segments是一个Array数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25] 会变成 [5, 15, 25, 5, 15, 25]。数组内部是虚线的交替状态


|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById("mycanvas") as HTMLCanvasElement |
|  |  |
|  | // 获取上下文 |
|  | const ctx = myCanvas.getContext("2d") |
|  |  |
|  | // 画布的尺寸 |
|  | myCanvas.width = document.documentElement.clientWidth - 30 |
|  | myCanvas.height = document.documentElement.clientHeight - 30 |
|  |  |
|  | if(ctx !== null) { |
|  |  ctx.setLineDash([15, 15]); |
|  |  ctx.strokeRect(50,50, 90, 90) |
|  |  ctx.setLineDash([15,10,2,10]) |
|  |  ctx.strokeRect(200,50, 90, 90) |
|  | } |


canvas基础简单易懂教程(完结,多图)_第13张图片

lineDashOffset

我们可以使用lineDashOffset设置虚线偏移量的属性。设置的是起始偏移量,使线向左移动value



|  | ctx.lineDashOffset = value; |


  • value偏移量是float精度的数字。 初始值为 0.0

2.8 文本

我们可以在画布上绘制文字:



|  | ctx.font = "30px 微软雅黑" // 空格前为文字大小,空格后为字体类型 |
|  | // 第一个参数为文字内容,第二和第三个参数为文字绘制坐标, |
|  | // 第四个参数是可选参数,代表文字的最大宽度,如果字体宽度超过该值则压缩字体宽度 |
|  | ctx.fillText("你好,世界!", 100, 100)  |


canvas基础简单易懂教程(完结,多图)_第14张图片

我们可以使用textAlign来设置文本的对齐选项。可选的值包括:start, end, left, right or center。默认值是 start。该对齐是基于fillText方法的x的值。



|  | ctx.textAlign = "left" || "right" || "center" || "start" || "end"; |


  • left : 文本左对齐。
  • right: 文本右对齐。
  • center: 文本居中对齐。
  • start: 文本对齐界线开始的地方 (左对齐指本地从左向右,右对齐指本地从右向左)。
  • end: 文本对齐界线结束的地方 (左对齐指本地从左向右,右对齐指本地从右向左)。

2.9 渐变 Gradients

提供两种渐变方式,一种是线性渐变,一种是径向渐变。

  • 线性渐变:createLinearGradient 方法接受 4 个参数,表示图形渐变线的起点 (x1,y1) 与终点 (x2,y2),渐变将沿着这条线向两边渐变。


|  | ctx.createLinearGradient(x1, y1, x2, y2) |


addColorStop内部接收两个参数,第一个参数是当前渐变的位置(0~1之间的小数),第二个参数是颜色。



|  | let liner: CanvasGradient = ctx.createLinearGradient(0, 0, 100, 100) |
|  | liner.addColorStop(0, 'red') |
|  | liner.addColorStop(.5, 'blue') |
|  | liner.addColorStop(.8, 'yellow') |
|  | liner.addColorStop(1, 'green') |
|  | ctx.fillStyle = liner |
|  | ctx.fillRect(10, 10, 100,100) |


canvas基础简单易懂教程(完结,多图)_第15张图片

径向渐变:createRadialGradient方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的开始圆形,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的结束圆形。



|  | let radial: CanvasGradient = ctx.createRadialGradient(100, 100, 0, 100, 100, 100) |
|  | radial.addColorStop(0, 'red') |
|  | radial.addColorStop(1, 'purple') |
|  | ctx.fillStyle = radial |
|  | ctx.arc(100, 100, 100, 0, Math.PI *2, false) |
|  | ctx.fill( |


canvas基础简单易懂教程(完结,多图)_第16张图片

2.10 阴影

我们可以在画布中设置画布的阴影的状态:

  • shadowOffsetX: shadowOffsetXshadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0
  • shadowOffsetY: shadowOffsetXshadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0
  • shadowBlur: shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0
  • shadowColor: shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。


|  | ctx.shadowOffsetX = 1 // 阴影左右偏离的距离 |
|  | ctx.shadowOffsetY = 1 // 阴影上下偏离的距离 |
|  | ctx.shadowBlur = 1 // 模糊状态 |
|  | ctx.shadowColor = 'green' // 阴影颜色 |
|  | ctx.font ='30px 宋体' |
|  | ctx.fillText('你好,世界!', 100, 100) |


canvas基础简单易懂教程(完结,多图)_第17张图片

三、使用图片

canvs中使用drawImage来绘制图片,主要是把外部的图片导入进来,绘制到画布上。

图片的渲染过程:



|  | // 导入图片 |
|  | if(ctx !== null) { |
|  | // 第一步是创建一个image元素 |
|  | let image:HTMLImageElement = new Image() |
|  | // 用src设置图片的地址 |
|  |  image.src = "image/test1.png" |
|  | // 必须要在onload函数内绘制图片,否则不会渲染 |
|  |  image.onload = function() { |
|  |  ctx.drawImage(image, 100, 100) |
|  |  } |
|  | } |


canvas基础简单易懂教程(完结,多图)_第18张图片

如果我们在drawImage里设置的参数一共是两个(不包含第一个image参数),表示的是图片的加载位置。



|  | ctx.drawImage(image, 100, 100) |


canvas基础简单易懂教程(完结,多图)_第19张图片

如果drawImage有四个参数,分别表示图片的绘制位置和图片的宽高。(注意,此时图像会被拉伸)



|  | ctx.drawImage(image, 100, 100, 50, 50) |


canvas基础简单易懂教程(完结,多图)_第20张图片

还可以使用八个参数的drawImage, 前四个参数指的是你在图片中设置切片的宽度和高度,以及切片的位置,后四个参数指的是切片在画布上的位置和切片宽度高度



|  | // ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); |
|  | ctx.drawImage(image, 100, 300, 200, 200) |
|  | ctx.drawImage(image, 100, 100, 200, 200, 100, 100, 200, 200) |


  • sx: 需要绘制到目标上下文中的,image的矩形(裁剪)选择框的左上角 X 轴坐标。
  • sy: 需要绘制到目标上下文中的,image的矩形(裁剪)选择框的左上角 Y 轴坐标。
  • sWidth: 需要绘制到目标上下文中的,image的矩形(裁剪)选择框的宽度。如果不说明,整个矩形(裁剪)从坐标的sxsy开始,到image的右下角结束。
  • sHeight: 需要绘制到目标上下文中的,image的矩形(裁剪)选择框的高度。
  • dx: image的左上角在目标canvas上 X 轴坐标。
  • dy: image的左上角在目标canvas上 Y 轴坐标。
  • dWidth: image在目标canvas上绘制的宽度。 允许对绘制的image进行缩放。 如果不说明, 在绘制时image宽度不会缩放。
  • dHeight: image在目标canvas上绘制的高度。 允许对绘制的image进行缩放。 如果不说明, 在绘制时image高度不会缩放。

canvas基础简单易懂教程(完结,多图)_第21张图片

canvas基础简单易懂教程(完结,多图)_第22张图片

四、资源管理器

canvas基础简单易懂教程(完结,多图)_第23张图片

我们在开发游戏的时候,有一些静态资源是需要请求回来的,否则如果直接开始,某些静态资源没有,会报错,或者空白,比如我们的游戏被禁锢,如果没有请求回来就直接开始,页面会有空白现象。

资源管理器就是当游戏需要资源全部加载完毕的时候,再开始游戏

我们现在主要是图片的资源,所以我们要在canvas渲染过程中进行图片的资源加载。

4.1 获取对象中属性的长度

有下面一个JSON(对象),此时我们想获取当前这个JSON属性数量



|  | this.imgURL = { |
|  | 'fengjing1':'./image/下载1.jpg', |
|  | 'fengjing2':'./image/下载2.jpg', |
|  | 'fengjing3':'./image/下载3.jpg', |
|  | 'fengjing4':'./image/下载4.jpg', |
|  | 'fengjing5':'./image/下载5.jpg', |
|  | } |


此时我们使用this.imgURL.length是得不到的,因为当前的this.imgURL.length指的是获取imgURL对象的length属性,而不是获取当前对象的属性个数,会返回undefined

正确答案是使用Object.keys()来获取当前的属性key列表,然后通过这个列表获取长度。



|  | Object.keys(this.imgURL).length |


4.2 管理器的实现



|  | interface StringOrImage { |
|  | // 定义了一个接口,该接口要求对象的属性是string或者是HTMLImageElement类型 |
|  |  [index: string]: string | HTMLImageElement |
|  | } |
|  |  |
|  | class Game { |
|  | dom: HTMLCanvasElement |
|  | ctx: CanvasRenderingContext2D | null |
|  | imgURL: StringOrImage |
|  | constructor() { |
|  | // 得到画布 |
|  | this.dom = document.getElementById("mycanvas") as HTMLCanvasElement |
|  | // 获取上下文 |
|  | this.ctx = this.dom.getContext("2d") |
|  | // 在属性中保存需要的图片地址 |
|  | this.imgURL = { |
|  | // 'fengjing1':'./image/下载1.jpg', |
|  | // 'fengjing2':'./image/下载2.jpg', |
|  | // 'fengjing3':'./image/下载3.jpg', |
|  | // 'fengjing4':'./image/下载4.jpg', |
|  | // 'fengjing5':'./image/下载5.jpg', |
|  | 'fengjing1':'https://gimg2.baidu.com/image\_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651933471&t=34b40d339ce3bc4177afb393e7785575', |
|  | 'fengjing2':'https://gimg2.baidu.com/image\_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0827%2Fc0c92bd51bb72e6d12d5b877dce338e8.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651933483&t=453f28e751e0d54d70a2e3393e57b423', |
|  | 'fengjing3':'https://gimg2.baidu.com/image\_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F1113%2F032120114622%2F200321114622-4-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651933493&t=e9017fa69deb525312e214d2583a76d4', |
|  | 'fengjing4':'https://pic.rmb.bdstatic.com/1530971282b420d77bdfb6444d854f952fe31f0d1e.jpeg', |
|  | 'fengjing5':'https://gimg2.baidu.com/image\_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp01%2F1ZZQ214233446-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651933521&t=2cc050574824ec2761b539ab3a697522', |
|  |  } |
|  | // 获取资源图片的总数 |
|  | let imgCount = Object.keys(this.imgURL).length |
|  | // 计数器,记录的是加载完毕的数量 |
|  | let count = 0 |
|  | // 遍历imgURL对象获取每一个路径地址 |
|  | for(let key in this.imgURL) { |
|  | // 备份每一张图片的地址 |
|  | let src: string = this.imgURL[key] as string |
|  | // 创建一个图片 |
|  | this.imgURL[key] = new Image(); |
|  |  |
|  | // 判断图片是否加载完成,如果完成了,记数,如果加载完毕的数量和总数量相同了,则说明资源加载完毕 |
|  | // 第一种方法,将值提取出去做类型缩小 |
|  | let value = this.imgURL[key] |
|  | // 类型缩小成HTMLImageElement类型 |
|  | if(typeof value !== 'string') { |
|  |  value.src = src |
|  |  value.onload = () => { |
|  | // 增加计数器 |
|  |  count++ |
|  | if(this.ctx !== null) { |
|  | // 清屏 |
|  | this.ctx.clearRect(0, 0, 600, 600) |
|  | this.ctx.font = '16px Arial' |
|  | this.ctx.fillText("图片已经加载:" + count +" / " + imgCount, 50, 50) |
|  | // 判断图片是否加载完毕,如果加载完毕了再开始显示 |
|  | if(count === imgCount) { |
|  | this.start() |
|  |  } |
|  |  } |
|  |  }  |
|  |  } |
|  |  |
|  | // 第二种方法,使用as直接断言成HTMLImageElement |
|  | //(this.imgURL[key] as HTMLImageElement).src = src |
|  |  |
|  |  } |
|  |  } |
|  | start() { |
|  | if(this.ctx !== null) { |
|  | // 清屏 |
|  | this.ctx.clearRect(0, 0, 600, 600) |
|  | let startX = 0 |
|  | let startY = 0 |
|  | for(let key in this.imgURL) { |
|  | this.ctx.drawImage(this.imgURL[key] as HTMLImageElement, startX, startY, 100, 100) |
|  |  startX += 100 |
|  |  startY += 100 |
|  |  } |
|  |  } |
|  |  } |
|  | } |
|  |  |
|  | new Game() |


五、变形

canvas是可以进行变形的,但是变形的不是元素,而是ctx,ctx就是整个画布的渲染区域,整个画布在变形,我们需要在画布变形前进行保存和恢复:

  • save():保存画布(canvas)的所有状态。
  • restore():save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

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

  • 当前应用的变形(即移动,旋转和缩放,见下)
  • 以及下面这些属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
  • 当前的裁切路径(clipping path),会在下一节介绍

你可以调用任意多次 save方法。每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。

以下的例子可以很好的印证这两个的用法:



|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  | if (ctx !== null) { |
|  |  ctx.fillRect(0, 0, 150, 150); // 使用默认设置绘制一个矩形 |
|  |  ctx.save(); // 保存默认状态 |
|  |  |
|  |  ctx.fillStyle = '#09F' // 在原有配置基础上对颜色做改变 |
|  |  ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形 |
|  |  |
|  |  ctx.save(); // 保存当前状态 |
|  |  ctx.fillStyle = '#FFF' // 再次改变颜色配置 |
|  |  ctx.globalAlpha = 0.5; |
|  |  ctx.fillRect(30, 30, 90, 90); // 使用新的配置绘制一个矩形 |
|  |  |
|  |  ctx.restore(); // 重新加载之前的颜色状态 |
|  |  ctx.fillRect(45, 45, 60, 60); // 使用上一次的配置绘制一个矩形 |
|  |  |
|  |  ctx.restore(); // 加载默认颜色配置 |
|  |  ctx.fillRect(60, 60, 30, 30); // 使用加载的配置绘制一个矩形 |
|  | } |


canvas基础简单易懂教程(完结,多图)_第24张图片

5.1 移动translate

translate(x, y): translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量。

在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。又,如果你是在一个循环中做位移但没有保存和恢复 canvas 的状态,很可能到最后会发现怎么有些东西不见了,那是因为它很可能已经超出 canvas 范围以外了。

我们知道了变形实际上就是将整个画布进行的变形,所以如果一旦我们的变形操作变多了,画布将变得不可控。

所以如果我们使用到变形,一定记住下面的规律:变形之前要先备份,将世界和平的状态进行备份,然后再变形,变形完毕后再恢复到世界和平的样子,不要影响下一次的操作。



|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  | if (ctx !== null) { |
|  | // 保存 |
|  |  ctx.save() |
|  |  ctx.translate(50, 50) |
|  |  ctx.fillRect(0, 0, 120, 120) |
|  | // 恢复 |
|  |  ctx.restore() |
|  | // 渲染位置是没有存档之前的位置 |
|  |  ctx.fillRect(120, 300, 120, 120) |
|  | } |


canvas基础简单易懂教程(完结,多图)_第25张图片

5.2 旋转 rotate

rotate(angle)这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。

旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。

5.3 缩放 scale

scale(x, y): scale 方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比1小,会缩小图形, 如果比1大会放大图形。默认值为1, 为实际大小。

画布初始情况下, 是以左上角坐标为原点的第一象限。如果参数为负实数, 相当于以x 或 y轴作为对称轴镜像反转(例如, 使用translate(0,canvas.height); scale(1,-1); 以y轴作为对称轴镜像反转, 就可得到著名的笛卡尔坐标系,左下角为原点)。

默认情况下,canvas 的 1 个单位为 1 个像素。举例说,如果我们设置缩放因子是 0.5,1 个单位就变成对应 0.5 个像素,这样绘制出来的形状就会是原先的一半。同理,设置为 2.0 时,1 个单位就对应变成了 2 像素,绘制的结果就是图形放大了 2 倍。

5.4 变形 transform

transform(a, b, c, d, e, f)

a (m11): 水平方向的缩放;

b(m12): 竖直方向的倾斜偏移;

c(m21): 水平方向的倾斜偏移;

d(m22): 竖直方向的缩放;

e(dx): 水平方向的移动;

f(dy): 竖直方向的移动.



|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  | if (ctx !== null) { |
|  | // 保存 |
|  |  ctx.save() |
|  |  ctx.transform(0.5, 0, 1, 0.5, 100, 100) |
|  |  ctx.fillRect(0, 0, 100,100) |
|  | // 恢复 |
|  |  ctx.restore() |
|  | // 渲染位置是没有存档之前的位置 |
|  |  ctx.fillRect(0, 200, 100, 100) |
|  |  |
|  | } |


canvas基础简单易懂教程(完结,多图)_第26张图片

5.5 滚动的车轮案例

  • index.html


|  | html> |
|  |  |
|  |  |
|  |  |
|  |  |
|  |  |
|  |  |
|  | canvas的变形-滚动的车轮title> |
|  | <link rel="stylesheet" href="./css/reset.css" type="text/css"> |
|  | <link rel="stylesheet" href="./css/index.css" type="text/css"> |
|  | head> |
|  |  |
|  | <body> |
|  | <canvas id="mycanvas"width="1200" height="600" > |
|  |  当前的浏览器版本不支持,请升级浏览器 |
|  | canvas> |
|  | <script src='./dist/canvas.js'>script> |
|  | body> |
|  | html> |


</code></pre> 
  <ul> 
   <li>所需图片</li> 
  </ul> 
  <p><a href="http://img.e-com-net.com/image/info8/755956050f4845f38be0cf085e5ce4c5.webp" target="_blank"><img src="http://img.e-com-net.com/image/info8/755956050f4845f38be0cf085e5ce4c5.webp" alt="canvas基础简单易懂教程(完结,多图)_第27张图片" width="886" height="890" style="border:1px solid black;"></a></p> 
  <ul> 
   <li>canvas.ts</li> 
  </ul> 
  <pre><code>

|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  |  |
|  | if (ctx !== null) { |
|  | // 第一步是创建一个image元素 |
|  | const image:HTMLImageElement = new Image() |
|  | // 用src设置图片的地址 |
|  |  image.src = "image/汽车车轮.png" |
|  | // 必须要在onload函数内绘制图片,否则不会渲染 |
|  |  image.onload = () => { |
|  | // 定时器 |
|  | // 旋转的度数 |
|  | let deg = 0 |
|  | // 位置 |
|  | let x= -100 |
|  |  |
|  | setInterval(() => { |
|  | // 清除画布 |
|  |  ctx.clearRect(0, 0, myCanvas.width, myCanvas.height) |
|  |  deg += 0.1 |
|  |  x += 5 |
|  | if(x >= myCanvas.width - 100) { |
|  |  x = -100 |
|  |  } |
|  | // 备份 |
|  |  ctx.save() |
|  | // 平移, 目前我们的原点为(100,300) |
|  |  ctx.translate(x, 300) |
|  | // 旋转,因为旋转始终在canvas的原点,所以我们得用translate改变原点。 |
|  |  ctx.rotate(deg) |
|  | // 我们得让车轮的中心处于原点,所以我们需要在第一个和第二个参数各为第三和第四个参数的一半然后再加负号 |
|  |  ctx.drawImage(image, -100, -100, 200, 200) |
|  | // 恢复 |
|  |  ctx.restore() |
|  |  }, 1000/60) |
|  |  } |
|  | } |


</code></pre> 
  <ul> 
   <li>整体架构</li> 
  </ul> 
  <p><a href="http://img.e-com-net.com/image/info8/34c9868282614ad7b86b7690195e19d8.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/34c9868282614ad7b86b7690195e19d8.jpg" alt="canvas基础简单易懂教程(完结,多图)_第28张图片" width="152" height="177" style="border:1px solid black;"></a></p> 
  <ul> 
   <li>实现的效果<br> </li> 
  </ul> 
  <h2>六、合成与裁剪</h2> 
  <p>合成其实就是我们常见的蒙版状态,本质就是如何进行压盖,如何进行显示。</p> 
  <p>在之前我们总是将一个图形画在另一个之上,对于其他更多的情况,仅仅这样是远远不够的。比如,对合成的图形来说,绘制顺序会有限制。不过,我们可以利用 <code>globalCompositeOperation</code> 属性来改变这种状况。此外, <code>clip</code>属性允许我们隐藏不想看到的部分图形。</p> 
  <p>比如我们此时花了一个方和一个圆,第一次画的是方,第二次画的是圆,所以会出现圆压盖方的现象</p> 
  <pre><code>

|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  | if (ctx !== null) { |
|  |  ctx.fillStyle = 'skyblue' |
|  |  ctx.fillRect(100, 100, 100, 100) |
|  |  ctx.fillStyle = 'deeppink' |
|  |  ctx.beginPath() |
|  |  ctx.arc(200, 200, 60, 0, 7,false) |
|  |  ctx.fill() |
|  | } |


</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/4d997d679ffa4951b8d8a1e270b6959c.png" target="_blank"><img src="http://img.e-com-net.com/image/info8/4d997d679ffa4951b8d8a1e270b6959c.png" alt="canvas基础简单易懂教程(完结,多图)_第29张图片" width="513" height="523" style="border:1px solid black;"></a></p> 
  <h3>6.1 globalCompositeOperation</h3> 
  <p><code>globalCompositeOperation = type</code></p> 
  <p>这个属性设定了在画新图形时采用的遮盖策略,其值是一个标识12种遮盖方式的字符串。具体情况看MDN。</p> 
  <p>我们可以通过这个属性来对上方设置压盖顺序:</p> 
  <p>比如说此时我们想让粉色在下面, 可以使用destination-over:</p> 
  <pre><code>

|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  | if (ctx !== null) { |
|  |  ctx.fillStyle = 'skyblue' |
|  |  ctx.fillRect(100, 100, 100, 100) |
|  |  ctx.globalCompositeOperation= 'destination-over' |
|  |  ctx.fillStyle = 'deeppink' |
|  |  ctx.beginPath() |
|  |  ctx.arc(200, 200, 60, 0, 7,false) |
|  |  ctx.fill() |
|  | } |


</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/6fea087929cb4f1d80c0391c35f66d47.png" target="_blank"><img src="http://img.e-com-net.com/image/info8/6fea087929cb4f1d80c0391c35f66d47.png" alt="canvas基础简单易懂教程(完结,多图)_第30张图片" width="262" height="239" style="border:1px solid black;"></a></p> 
  <h3>6.2 裁剪路径</h3> 
  <p>裁切路径和普通的 canvas 图形差不多,不同的是它的作用是遮罩,用来隐藏不需要的部分。如下图所示。红边五角星就是裁切路径,所有在路径以外的部分都不会在 canvas 上绘制出来。</p> 
  <p><a href="http://img.e-com-net.com/image/info8/5aca7fea7801488b8c6806dd6e45f5fa.png" target="_blank"><img src="http://img.e-com-net.com/image/info8/5aca7fea7801488b8c6806dd6e45f5fa.png" alt="canvas基础简单易懂教程(完结,多图)_第31张图片" width="241" height="245" style="border:1px solid black;"></a></p> 
  <p>如果和上面介绍的 <code>globalCompositeOperation</code> 属性作一比较,它可以实现与 <code>source-in</code> 和 <code>source-atop</code>差不多的效果。最重要的区别是裁切路径不会在 canvas 上绘制东西,而且它永远不受新图形的影响。这些特性使得它在特定区域里绘制图形时相当好用。</p> 
  <p><code>clip()</code>: 将当前正在构建的路径转换为当前的裁剪路径。默认情况下,canvas 有一个与它自身一样大的裁切路径(也就是没有裁切效果)。</p> 
  <h3>6.3 刮刮乐案例</h3> 
  <ul> 
   <li>index.html</li> 
  </ul> 
  <pre><code>

|  | html> |
|  | <html lang="en"> |
|  |  |
|  | <head> |
|  | <meta charset="UTF-8"> |
|  | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|  | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|  | <title>canvas实现刮刮乐title> |
|  | <link rel="stylesheet" href="./css/reset.css" type="text/css"> |
|  | <link rel="stylesheet" href="./css/index.css" type="text/css"> |
|  | head> |
|  |  |
|  | <body> |
|  | <div> |
|  |  特等奖 |
|  | <canvas width="250" height="60" id="mycanvas"> |
|  |  当前的浏览器版本不支持,请升级浏览器 |
|  | canvas> |
|  | div> |
|  | <script src='./dist/canvas.js'>script> |
|  | body> |
|  | html> |


</code></pre> 
  <ul> 
   <li>index.css</li> 
  </ul> 
  <pre><code>

|  | div { |
|  | border: 1px solid #000; |
|  | width: 250px; |
|  | height: 60px; |
|  | font-size: 40px; |
|  | line-height: 60px; |
|  | text-align: center; |
|  | position: relative; |
|  |  user-select: none; |
|  | } |
|  |  |
|  | canvas { |
|  | position: absolute; |
|  | left: 0; |
|  | top: 0; |
|  | } |


</code></pre> 
  <ul> 
   <li>canvas.ts</li> 
  </ul> 
  <pre><code>

|  | // 得到画布 |
|  | const myCanvas: HTMLCanvasElement = document.getElementById('mycanvas') as HTMLCanvasElement |
|  | // 获得上下文 |
|  | const ctx = myCanvas.getContext('2d') |
|  |  |
|  | if (ctx !== null) { |
|  |  ctx.fillStyle = '#333' |
|  |  ctx.fillRect(0, 0, 250, 60) |
|  | // 设置新画上的元素,实际上就是擦除之前的元素 |
|  |  ctx.globalCompositeOperation = 'destination-out' |
|  |  |
|  | const func = (event:any) => { |
|  | // 画图 |
|  |  ctx.beginPath() |
|  |  ctx.arc(event.offsetX, event.offsetY,10, 0, Math.PI * 2,false) |
|  |  ctx.fill() |
|  |  } |
|  | // 按下 |
|  |  myCanvas.onmousedown = () => { |
|  | // 添加鼠标移动事件 |
|  |  myCanvas.addEventListener('mousemove', func) |
|  |  } |
|  | // 松开 |
|  |  myCanvas.onmouseup = () => { |
|  | // 删除鼠标移动事件 |
|  |  myCanvas.removeEventListener('mousemove', func) |
|  |  } |
|  | } |


</code></pre> 
  <ul> 
   <li>实现效果</li> 
  </ul> 
  <p><a href="http://img.e-com-net.com/image/info8/8053df5acdb64f5bb2c5f1f4c9a7f5fa.gif" target="_blank"><img src="http://img.e-com-net.com/image/info8/8053df5acdb64f5bb2c5f1f4c9a7f5fa.gif" alt="" width="281" height="79"></a></p> 
  <h2>七、总结</h2> 
  <p>至此,一个简单的学习canvas教程已经完结,大家还是多看看文档吧,希望这个教程能让大家喜欢上canvas并且好好的利用它!</p> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1666203987755491328"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(计算机,计算机)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835513803861749760.htm"
                           title="机器学习与深度学习间关系与区别" target="_blank">机器学习与深度学习间关系与区别</a>
                        <span class="text-muted">ℒℴѵℯ心·动ꦿ໊ོ꫞</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>一、机器学习概述定义机器学习(MachineLearning,ML)是一种通过数据驱动的方法,利用统计学和计算算法来训练模型,使计算机能够从数据中学习并自动进行预测或决策。机器学习通过分析大量数据样本,识别其中的模式和规律,从而对新的数据进行判断。其核心在于通过训练过程,让模型不断优化和提升其预测准确性。主要类型1.监督学习(SupervisedLearning)监督学习是指在训练数据集中包含输入</div>
                    </li>
                    <li><a href="/article/1835496780066811904.htm"
                           title="在一台Ubuntu计算机上构建Hyperledger Fabric网络" target="_blank">在一台Ubuntu计算机上构建Hyperledger Fabric网络</a>
                        <span class="text-muted">落叶无声9</span>
<a class="tag" taget="_blank" href="/search/%E5%8C%BA%E5%9D%97%E9%93%BE/1.htm">区块链</a><a class="tag" taget="_blank" href="/search/%E8%B6%85%E7%BA%A7%E8%B4%A6%E6%9C%AC/1.htm">超级账本</a><a class="tag" taget="_blank" href="/search/Hyperledger/1.htm">Hyperledger</a><a class="tag" taget="_blank" href="/search/fabric/1.htm">fabric</a><a class="tag" taget="_blank" href="/search/%E5%8C%BA%E5%9D%97%E9%93%BE/1.htm">区块链</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/%E6%9E%84%E5%BB%BA/1.htm">构建</a><a class="tag" taget="_blank" href="/search/hyperledger/1.htm">hyperledger</a><a class="tag" taget="_blank" href="/search/fabric/1.htm">fabric</a>
                        <div>在一台Ubuntu计算机上构建HyperledgerFabric网络Hyperledgerfabric是一个开源的区块链应用程序平台,为开发基于区块链的应用程序提供了一个起点。当我们提到HyperledgerFabric网络时,我们指的是使用HyperledgerFabric的正在运行的系统。即使只使用最少数量的组件,部署Fabric网络也不是一件容易的事。Fabric社区创建了一个名为Cello</div>
                    </li>
                    <li><a href="/article/1835496402042580992.htm"
                           title="GitHub上克隆项目" target="_blank">GitHub上克隆项目</a>
                        <span class="text-muted">bigbig猩猩</span>
<a class="tag" taget="_blank" href="/search/github/1.htm">github</a>
                        <div>从GitHub上克隆项目是一个简单且直接的过程,它允许你将远程仓库中的项目复制到你的本地计算机上,以便进行进一步的开发、测试或学习。以下是一个详细的步骤指南,帮助你从GitHub上克隆项目。一、准备工作1.安装Git在克隆GitHub项目之前,你需要在你的计算机上安装Git工具。Git是一个开源的分布式版本控制系统,用于跟踪和管理代码变更。你可以从Git的官方网站(https://git-scm.</div>
                    </li>
                    <li><a href="/article/1835495644123459584.htm"
                           title="Day1笔记-Python简介&标识符和关键字&输入输出" target="_blank">Day1笔记-Python简介&标识符和关键字&输入输出</a>
                        <span class="text-muted">~在杰难逃~</span>
<a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a>
                        <div>大家好,从今天开始呢,杰哥开展一个新的专栏,当然,数据分析部分也会不定时更新的,这个新的专栏主要是讲解一些Python的基础语法和知识,帮助0基础的小伙伴入门和学习Python,感兴趣的小伙伴可以开始认真学习啦!一、Python简介【了解】1.计算机工作原理编程语言就是用来定义计算机程序的形式语言。我们通过编程语言来编写程序代码,再通过语言处理程序执行向计算机发送指令,让计算机完成对应的工作,编程</div>
                    </li>
                    <li><a href="/article/1835476476514889728.htm"
                           title="Shell、Bash、Zsh这都是啥啊" target="_blank">Shell、Bash、Zsh这都是啥啊</a>
                        <span class="text-muted">小白码上飞</span>
<a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>Zsh和Bash都是我们常用的Shell,那先搞明白啥是shell吧。Shell作为一个单词,他是“壳”的意思,蛋壳坚果壳。之所以叫壳,是为了和计算机的“核”来区分,用它表示“为使用者提供的操作界面”。所以这个命名其实很形象,翻译成中文,直译过来叫“壳层”。个人认为这个叫法很奇怪,意译貌似也没有什么好的词汇来匹配。就还是叫shell吧。维基百科给的定义是:Incomputing,ashellisa</div>
                    </li>
                    <li><a href="/article/1835476350190841856.htm"
                           title="ExpRe[25] bash外的其它shell:zsh和fish" target="_blank">ExpRe[25] bash外的其它shell:zsh和fish</a>
                        <span class="text-muted">tritone</span>
<a class="tag" taget="_blank" href="/search/ExpRe/1.htm">ExpRe</a><a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a>
                        <div>文章目录zsh基础配置实用特性插件`autojump`语法高亮自动补全fish优点缺点时效性本篇撰写时间为2021.12.15,由于计算机技术日新月异,博客中所有内容都有时效和版本限制,具体做法不一定总行得通,链接可能改动失效,各种软件的用法可能有修改。但是其中透露的思想往往是值得学习的。本篇前置:ExpRe[10]Ubuntu[2]准备神秘软件、备份恢复软件https://www.cnblogs</div>
                    </li>
                    <li><a href="/article/1835473830873755648.htm"
                           title="简单了解 JVM" target="_blank">简单了解 JVM</a>
                        <span class="text-muted">记得开心一点啊</span>
<a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a>
                        <div>目录♫什么是JVM♫JVM的运行流程♫JVM运行时数据区♪虚拟机栈♪本地方法栈♪堆♪程序计数器♪方法区/元数据区♫类加载的过程♫双亲委派模型♫垃圾回收机制♫什么是JVMJVM是JavaVirtualMachine的简称,意为Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统(如:JVM、VMwave、VirtualBox)。JVM和其他两个虚拟机</div>
                    </li>
                    <li><a href="/article/1835463621124124672.htm"
                           title="数据结构 | 栈和队列" target="_blank">数据结构 | 栈和队列</a>
                        <span class="text-muted">TT-Kun</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/1.htm">数据结构与算法</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E6%A0%88/1.htm">栈</a><a class="tag" taget="_blank" href="/search/%E9%98%9F%E5%88%97/1.htm">队列</a><a class="tag" taget="_blank" href="/search/C%E8%AF%AD%E8%A8%80/1.htm">C语言</a>
                        <div>文章目录栈和队列1.栈:后进先出(LIFO)的数据结构1.1概念与结构1.2栈的实现2.队列:先进先出(FIFO)的数据结构2.1概念与结构2.2队列的实现3.栈和队列算法题3.1有效的括号3.2用队列实现栈3.3用栈实现队列3.4设计循环队列结论栈和队列在计算机科学中,栈和队列是两种基本且重要的数据结构,它们在处理数据存储和访问顺序方面有着独特的规则和应用。本文将详细介绍栈和队列的概念、结构、实</div>
                    </li>
                    <li><a href="/article/1835449250159357952.htm"
                           title="计算机木马详细编写思路" target="_blank">计算机木马详细编写思路</a>
                        <span class="text-muted">小熊同学哦</span>
<a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E6%9C%A8%E9%A9%AC/1.htm">木马</a><a class="tag" taget="_blank" href="/search/%E6%9C%A8%E9%A9%AC%E6%80%9D%E8%B7%AF/1.htm">木马思路</a>
                        <div>导语:计算机木马(ComputerTrojan)是一种恶意软件,通过欺骗用户从而获取系统控制权限,给黑客打开系统后门的一种手段。虽然木马的存在给用户和系统带来严重的安全风险,但是了解它的工作原理与编写思路,对于我们提高防范意识、构建更健壮的网络安全体系具有重要意义。本篇博客将深入剖析计算机木马的详细编写思路,以及如何复杂化挑战,以期提高读者对计算机木马的认识和对抗能力。计算机木马的基本原理计算机木</div>
                    </li>
                    <li><a href="/article/1835436012189347840.htm"
                           title="4 大低成本娱乐方式: 小说, 音乐, 视频, 电子游戏" target="_blank">4 大低成本娱乐方式: 小说, 音乐, 视频, 电子游戏</a>
                        <span class="text-muted">穷人小水滴</span>
<a class="tag" taget="_blank" href="/search/%E5%A8%B1%E4%B9%90/1.htm">娱乐</a><a class="tag" taget="_blank" href="/search/%E9%9F%B3%E8%A7%86%E9%A2%91/1.htm">音视频</a><a class="tag" taget="_blank" href="/search/%E4%BD%8E%E6%88%90%E6%9C%AC/1.htm">低成本</a><a class="tag" taget="_blank" href="/search/%E5%B0%8F%E8%AF%B4/1.htm">小说</a><a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F/1.htm">游戏</a>
                        <div>穷人如何获得快乐?小说,音乐,视频,游戏,本文简单盘点一下这4大低成本(安全)娱乐方式.这里是穷人小水滴,专注于穷人友好型低成本技术.(本文为58号作品.)目录1娱乐方式1.1小说(网络小说)1.2音乐1.3视频(b站)1.4游戏(电子游戏/计算机软件)2低成本:一只手机即可3总结与展望1娱乐方式这几种,也可以说是艺术的具体形式.更专业的说,(娱乐)是劳动力再生产的重要组成部分.使人放松,获得快乐</div>
                    </li>
                    <li><a href="/article/1835434875872702464.htm"
                           title="计算机网络八股总结" target="_blank">计算机网络八股总结</a>
                        <span class="text-muted">Petrichorzncu</span>
<a class="tag" taget="_blank" href="/search/%E5%85%AB%E8%82%A1%E6%80%BB%E7%BB%93/1.htm">八股总结</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/1.htm">计算机网络</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a>
                        <div>这里写目录标题网络模型划分(五层和七层)及每一层的功能五层网络模型七层网络模型(OSI模型)==三次握手和四次挥手具体过程及原因==三次握手四次挥手TCP/IP协议组成==UDP协议与TCP/IP协议的区别==Http协议相关知识网络地址,子网掩码等相关计算网络模型划分(五层和七层)及每一层的功能五层网络模型应用层:负责处理网络应用程序,如电子邮件、文件传输和网页浏览。主要协议包括HTTP、FTP</div>
                    </li>
                    <li><a href="/article/1835428821877223424.htm"
                           title="计算机毕业设计PHP仓储综合管理系统(源码+程序+VUE+lw+部署)" target="_blank">计算机毕业设计PHP仓储综合管理系统(源码+程序+VUE+lw+部署)</a>
                        <span class="text-muted">java毕设程序源码王哥</span>
<a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1/1.htm">课程设计</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a>
                        <div>该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流项目运行环境配置:phpStudy+Vscode+Mysql5.7+HBuilderX+Navicat11+Vue+Express。项目技术:原生PHP++Vue等等组成,B/S模式+Vscode管理+前后端分离等等。环境需要1.运行环境:最好是小皮phpstudy最新版,我们在这个版本上开发的。其他版本理论上也可以。2.开发</div>
                    </li>
                    <li><a href="/article/1835427057279004672.htm"
                           title="经纬恒润二面&三七互娱一面&元象二面" target="_blank">经纬恒润二面&三七互娱一面&元象二面</a>
                        <span class="text-muted">Redstone Monstrosity</span>
<a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>1.请尽可能详细地说明,进程和线程的区别,分别有哪些应用场景?进程间如何通信?线程间如何通信?你的回答中不要写出示例代码。进程和线程是操作系统中的两个基本概念,它们在计算机系统中扮演着不同的角色,并且在不同的应用场景中发挥作用。进程和线程的区别定义:进程:进程是操作系统进行资源分配和调度的基本单位。每个进程都有独立的内存空间和系统资源。线程:线程是进程内的一个执行单元,是操作系统进行调度的最小单位</div>
                    </li>
                    <li><a href="/article/1835421131713114112.htm"
                           title="AI大模型的架构演进与最新发展" target="_blank">AI大模型的架构演进与最新发展</a>
                        <span class="text-muted">季风泯灭的季节</span>
<a class="tag" taget="_blank" href="/search/AI%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF%E4%BA%8C/1.htm">AI大模型应用技术二</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a>
                        <div>随着深度学习的发展,AI大模型(LargeLanguageModels,LLMs)在自然语言处理、计算机视觉等领域取得了革命性的进展。本文将详细探讨AI大模型的架构演进,包括从Transformer的提出到GPT、BERT、T5等模型的历史演变,并探讨这些模型的技术细节及其在现代人工智能中的核心作用。一、基础模型介绍:Transformer的核心原理Transformer架构的背景在Transfo</div>
                    </li>
                    <li><a href="/article/1835409784543735808.htm"
                           title="【加密算法基础——RSA 加密】" target="_blank">【加密算法基础——RSA 加密】</a>
                        <span class="text-muted">XWWW668899</span>
<a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>RSA加密RSA(Rivest-Shamir-Adleman)加密是非对称加密,一种广泛使用的公钥加密算法,主要用于安全数据传输。公钥用于加密,私钥用于解密。RSA加密算法的名称来源于其三位发明者的姓氏:R:RonRivestS:AdiShamirA:LeonardAdleman这三位计算机科学家在1977年共同提出了这一算法,并发表了相关论文。他们的工作为公钥加密的基础奠定了重要基础,使得安全通</div>
                    </li>
                    <li><a href="/article/1835399324834557952.htm"
                           title="【ShuQiHere】 进制与补码的世界:从符号-大小表示法到二补码" target="_blank">【ShuQiHere】 进制与补码的世界:从符号-大小表示法到二补码</a>
                        <span class="text-muted">ShuQiHere</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%8C%E8%BF%9B%E5%88%B6/1.htm">二进制</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/1.htm">计算机组成原理</a>
                        <div>【ShuQiHere】在计算机系统中,表示正数是相对简单的,只需使用其对应的二进制形式即可。然而,如何有效地表示负数一直是计算机科学中的一个关键问题。为了解决这个问题,科学家们提出了多种表示方法,包括符号-大小表示法(Sign-MagnitudeRepresentation)、一补码(One’sComplement)和二补码(Two’sComplement)。在本文中,我们将深入探讨这些表示方法的</div>
                    </li>
                    <li><a href="/article/1835385331923382272.htm"
                           title="【大模型应用开发 动手做AI Agent】第一轮行动:工具执行搜索" target="_blank">【大模型应用开发 动手做AI Agent】第一轮行动:工具执行搜索</a>
                        <span class="text-muted">AI大模型应用之禅</span>
<a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E7%A7%91%E5%AD%A6/1.htm">计算科学</a><a class="tag" taget="_blank" href="/search/%E7%A5%9E%E7%BB%8F%E8%AE%A1%E7%AE%97/1.htm">神经计算</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/1.htm">神经网络</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%9E%8B%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/1.htm">大型语言模型</a><a class="tag" taget="_blank" href="/search/AI/1.htm">AI</a><a class="tag" taget="_blank" href="/search/AGI/1.htm">AGI</a><a class="tag" taget="_blank" href="/search/LLM/1.htm">LLM</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/1.htm">架构设计</a><a class="tag" taget="_blank" href="/search/Agent/1.htm">Agent</a><a class="tag" taget="_blank" href="/search/RPA/1.htm">RPA</a>
                        <div>【大模型应用开发动手做AIAgent】第一轮行动:工具执行搜索作者:禅与计算机程序设计艺术/ZenandtheArtofComputerProgramming1.背景介绍1.1问题的由来随着人工智能技术的飞速发展,大模型应用开发已经成为当下热门的研究方向。AIAgent作为人工智能领域的一个重要分支,旨在模拟人类智能行为,实现智能决策和自主行动。在AIAgent的构建过程中,工具执行搜索是至关重要</div>
                    </li>
                    <li><a href="/article/1835374765892792320.htm"
                           title="2020年 12月3日 渥太华 阴" target="_blank">2020年 12月3日 渥太华 阴</a>
                        <span class="text-muted">一生守望一人</span>

                        <div>今天结课了。全面备战,准备期末考试了。最近看到纽约州立阿尔伯尼法学院和西奈山医学院有一个联合生命科学的硕士学位,有点心动,打算考完试以后找教授和相关负责人问一下。新闻方面,中国第一次实现了外太空运载器发射,嫦娥今天正式启程返家了。这也预示着我们面对载人登月又踏出了自己坚实的一步。同时,我们继美国之后在同一年制造出了量子计算机“九章”。“九章”量子计算机可以以200秒的速度计算出当前最强大超级计算机</div>
                    </li>
                    <li><a href="/article/1835374486308876288.htm"
                           title="一文让你彻底搞懂什么是VR、AR、AV、MR" target="_blank">一文让你彻底搞懂什么是VR、AR、AV、MR</a>
                        <span class="text-muted">码上飞扬</span>
<a class="tag" taget="_blank" href="/search/vr/1.htm">vr</a><a class="tag" taget="_blank" href="/search/ar/1.htm">ar</a><a class="tag" taget="_blank" href="/search/mr/1.htm">mr</a><a class="tag" taget="_blank" href="/search/av/1.htm">av</a>
                        <div>随着科技的飞速发展,现实世界与虚拟世界的界限变得越来越模糊。各种与现实增强相关的技术如雨后春笋般涌现,令人眼花缭乱。本文将为你详细解读四种常见的现实增强技术:虚拟现实(VR)、增强现实(AR)、混合现实(MR)和增强虚拟(AV),让你彻底搞懂它们之间的区别与联系。一、虚拟现实(VR)1.什么是VR?虚拟现实(VirtualReality,简称VR)是一种通过计算机模拟生成的三维环境,使用户能够沉浸</div>
                    </li>
                    <li><a href="/article/1835373604464848896.htm"
                           title="python中文版下载官网-Python下载 v3.8.3 官方中文版" target="_blank">python中文版下载官网-Python下载 v3.8.3 官方中文版</a>
                        <span class="text-muted">weixin_37988176</span>

                        <div>Python中文版是一款非常专业的通用型计算机程序设计语言安装包,Python具有比其他语言更有特色语法结构,而且在设计上坚持了清晰划一的风格,使得它成为一门易读、易维护并且被大量用户所欢迎的、用途广泛的语言,随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。Python中文版软件介绍Python中文版是一门跨平台的脚本语言,Python规定了一个Python语法规则,实</div>
                    </li>
                    <li><a href="/article/1835366671058038784.htm"
                           title="python中文版软件下载-Python中文版" target="_blank">python中文版软件下载-Python中文版</a>
                        <span class="text-muted">编程大乐趣</span>

                        <div>python中文版是一种面向对象的解释型计算机程序设计语言。python中文版官网面向对象编程,拥有高效的高级数据结构和简单而有效的方法,其优雅的语法、动态类型、以及天然的解释能力,让它成为理想的语言。软件功能强大,简单易学,可以帮助用户快速编写代码,而且代码运行速度非常快,几乎可以支持所有的操作系统,实用性真的超高的。python中文版软件介绍:python中文版的解释器及其扩展标准库的源码和编</div>
                    </li>
                    <li><a href="/article/1835356591562518528.htm"
                           title="个人学习笔记7-6:动手学深度学习pytorch版-李沐" target="_blank">个人学习笔记7-6:动手学深度学习pytorch版-李沐</a>
                        <span class="text-muted">浪子L</span>
<a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89/1.htm">计算机视觉</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/1.htm">神经网络</a><a class="tag" taget="_blank" href="/search/pytorch/1.htm">pytorch</a>
                        <div>#人工智能##深度学习##语义分割##计算机视觉##神经网络#计算机视觉13.11全卷积网络全卷积网络(fullyconvolutionalnetwork,FCN)采用卷积神经网络实现了从图像像素到像素类别的变换。引入l转置卷积(transposedconvolution)实现的,输出的类别预测与输入图像在像素级别上具有一一对应关系:通道维的输出即该位置对应像素的类别预测。13.11.1构造模型下</div>
                    </li>
                    <li><a href="/article/1835348897355100160.htm"
                           title="保研日记--哈工大威海计算机学院" target="_blank">保研日记--哈工大威海计算机学院</a>
                        <span class="text-muted">faaarii</span>
<a class="tag" taget="_blank" href="/search/%E4%BF%9D%E7%A0%94/1.htm">保研</a>
                        <div>传送门保研日记--中国海洋大学计算机系保研日记--中国人民大学信息学院(人大信院)保研日记--北京交通大学计算机学院保研材料模板(自我介绍,个人简历,个人陈述,推荐信)哈工大威海计算机学院这次夏令营给我的感觉非常的朴素,哈哈哈哈营员就有四个群,985/211、双一流、双非、四非??没有宣讲会、见面会,在面试开始之前放了一个简短的宣传片。(傲娇,绝对不整那些花里胡哨的哈哈哈)面试有三组老师,分别问你</div>
                    </li>
                    <li><a href="/article/1835337048534380544.htm"
                           title="计算机视觉中,Pooling的作用" target="_blank">计算机视觉中,Pooling的作用</a>
                        <span class="text-muted">Wils0nEdwards</span>
<a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89/1.htm">计算机视觉</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a>
                        <div>在计算机视觉中,Pooling(池化)是一种常见的操作,主要用于卷积神经网络(CNN)中。它通过对特征图进行下采样,减少数据的空间维度,同时保留重要的特征信息。Pooling的作用可以归纳为以下几个方面:1.降低计算复杂度与内存需求Pooling操作通过对特征图进行下采样,减少了特征图的空间分辨率(例如,高度和宽度)。这意味着网络需要处理的数据量会减少,从而降低了计算量和内存需求。这对大型神经网络</div>
                    </li>
                    <li><a href="/article/1835331376895848448.htm"
                           title="【JS】前端文件读取FileReader操作总结" target="_blank">【JS】前端文件读取FileReader操作总结</a>
                        <span class="text-muted">程序员-张师傅</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>前端文件读取FileReader操作总结FileReader是JavaScript中的一个WebAPI,它允许web应用程序异步读取用户计算机上的文件(或原始数据缓冲区)的内容,例如读取文件以获取其内容,并在不将文件发送到服务器的情况下在客户端使用它。这对于处理图片、文本文件等非常有用,尤其是当你想要在用户界面中即时显示文件内容或进行文件预览时。创建FileReader对象首先,你需要创建一个Fi</div>
                    </li>
                    <li><a href="/article/1835323818122506240.htm"
                           title="OpenCV图像处理技术(Python)——入门" target="_blank">OpenCV图像处理技术(Python)——入门</a>
                        <span class="text-muted">森屿_</span>
<a class="tag" taget="_blank" href="/search/opencv/1.htm">opencv</a>
                        <div>©FuXianjun.AllRightsReserved.OpenCV入门图像作为人类感知世界的视觉基础,是人类获取信息、表达信息的重要手段,OpenCV作为一个开源的计算机视觉库,它包括几百个易用的图像成像和视觉函数,既可以用于学术研究,也可用于工业邻域,它于1999年由因特尔的GaryBradski启动,OpenCV库主要由C和C++语言编写,它可以在多个操作系统上运行。1.1图像处理基本操作</div>
                    </li>
                    <li><a href="/article/1835319907047272448.htm"
                           title="机器学习 流形数据降维:UMAP 降维算法" target="_blank">机器学习 流形数据降维:UMAP 降维算法</a>
                        <span class="text-muted">小嗷犬</span>
<a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%8F%8A%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">数据分析及可视化</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a>
                        <div>✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。个人主页:小嗷犬的个人主页个人网站:小嗷犬的技术小站个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。本文目录UMAP简介理论基础特点与优势应用场景在Python中使用UMAP安装umap-learn库使用UMAP可视化手写数字数据集UMAP简介UMAP(UniformManifoldApproximatio</div>
                    </li>
                    <li><a href="/article/1835315746935238656.htm"
                           title="操作系统基础" target="_blank">操作系统基础</a>
                        <span class="text-muted">怡晗★</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>目录操作系统基础冯诺依曼体系结构介绍操作系统基本认知本篇文章是后面学习操作系统知识的基础操作系统基础冯诺依曼体系结构介绍冯诺依曼体系结构如下:在上图中「输入设备」和「输出设备」一般被称为计算机的外设,而「存储器」在冯诺依曼体系结构中表示「内存」输入设备一般包括:网卡、磁盘、键盘、触摸屏等输出设备一般包括:网卡、磁盘、鼠标、触摸屏、显示器(非触摸屏)等内存的作用「内存」是中央处理器与计算机其他设备的</div>
                    </li>
                    <li><a href="/article/1835288964056051712.htm"
                           title="分享一个基于python的电子书数据采集与可视化分析 hadoop电子书数据分析与推荐系统 spark大数据毕设项目(源码、调试、LW、开题、PPT)" target="_blank">分享一个基于python的电子书数据采集与可视化分析 hadoop电子书数据分析与推荐系统 spark大数据毕设项目(源码、调试、LW、开题、PPT)</a>
                        <span class="text-muted">计算机源码社</span>
<a class="tag" taget="_blank" href="/search/Python%E9%A1%B9%E7%9B%AE/1.htm">Python项目</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%AF%95%E4%B8%9A%E8%AE%BE%E8%AE%A1%E9%80%89%E9%A2%98/1.htm">计算机毕业设计选题</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%AF%95%E4%B8%9A%E8%AE%BE%E8%AE%A1%E6%BA%90%E7%A0%81/1.htm">计算机毕业设计源码</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/spark%E6%AF%95%E8%AE%BE/1.htm">spark毕设</a>
                        <div>作者:计算机源码社个人简介:本人八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流!学习资料、程序开发、技术解答、文档报告如需要源码,可以扫取文章下方二维码联系咨询Java项目微信小程序项目Android项目Python项目PHP项目ASP.NET项目Node.js项目选题推荐项目实战|p</div>
                    </li>
                    <li><a href="/article/1835279386866184192.htm"
                           title="数据结构 1" target="_blank">数据结构 1</a>
                        <span class="text-muted">五花肉村长</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/c%E8%AF%AD%E8%A8%80/1.htm">c语言</a><a class="tag" taget="_blank" href="/search/visualstudio/1.htm">visualstudio</a>
                        <div>1.什么是数据结构数据结构(DataStructure)是计算机存储和组织数据的方式,是指相互之间存在的一种或多种特定关系的数据元的集合。2.什么是算法算法(Algorithm)就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。3.数据结构和算法的书籍资料学习完数据结构知识,可以去看《剑指offer》和《</div>
                    </li>
                                <li><a href="/article/96.htm"
                                       title="怎么样才能成为专业的程序员?" target="_blank">怎么样才能成为专业的程序员?</a>
                                    <span class="text-muted">cocos2d-x小菜</span>
<a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a><a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a>
                                    <div>  
如何要想成为一名专业的程序员?仅仅会写代码是不够的。从团队合作去解决问题到版本控制,你还得具备其他关键技能的工具包。当我们询问相关的专业开发人员,那些必备的关键技能都是什么的时候,下面是我们了解到的情况。 
  
关于如何学习代码,各种声音很多,然后很多人就被误导为成为专业开发人员懂得一门编程语言就够了?!呵呵,就像其他工作一样,光会一个技能那是远远不够的。如果你想要成为</div>
                                </li>
                                <li><a href="/article/223.htm"
                                       title="java web开发 高并发处理" target="_blank">java web开发 高并发处理</a>
                                    <span class="text-muted">BreakingBad</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/%E5%B9%B6%E5%8F%91/1.htm">并发</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91/1.htm">开发</a><a class="tag" taget="_blank" href="/search/%E5%A4%84%E7%90%86/1.htm">处理</a><a class="tag" taget="_blank" href="/search/%E9%AB%98/1.htm">高</a>
                                    <div>java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF。尤其是Web2.0的应用,数据库的响应是首先要解决的。 一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降。常用的优化措施是M-S(</div>
                                </li>
                                <li><a href="/article/350.htm"
                                       title="mysql批量更新" target="_blank">mysql批量更新</a>
                                    <span class="text-muted">ekian</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>mysql更新优化: 
一版的更新的话都是采用update set的方式,但是如果需要批量更新的话,只能for循环的执行更新。或者采用executeBatch的方式,执行更新。无论哪种方式,性能都不见得多好。 
三千多条的更新,需要3分多钟。 
查询了批量更新的优化,有说replace into的方式,即: 
 
 
replace into tableName(id,status) values</div>
                                </li>
                                <li><a href="/article/477.htm"
                                       title="微软BI(3)" target="_blank">微软BI(3)</a>
                                    <span class="text-muted">18289753290</span>
<a class="tag" taget="_blank" href="/search/%E5%BE%AE%E8%BD%AFBI+SSIS/1.htm">微软BI SSIS</a>
                                    <div>1) 
Q:该列违反了完整性约束错误;已获得 OLE DB 记录。源:“Microsoft SQL Server Native Client 11.0” Hresult: 0x80004005 说明:“不能将值 NULL 插入列 'FZCHID',表 'JRB_EnterpriseCredit.dbo.QYFZCH';列不允许有 Null 值。INSERT 失败。”。 
A:一般这类问题的存在是 </div>
                                </li>
                                <li><a href="/article/604.htm"
                                       title="Java中的List" target="_blank">Java中的List</a>
                                    <span class="text-muted">g21121</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>        List是一个有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。 
        与 set 不同,列表通常允许重复</div>
                                </li>
                                <li><a href="/article/731.htm"
                                       title="读书笔记" target="_blank">读书笔记</a>
                                    <span class="text-muted">永夜-极光</span>
<a class="tag" taget="_blank" href="/search/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/1.htm">读书笔记</a>
                                    <div>   1.  K是一家加工厂,需要采购原材料,有A,B,C,D 4家供应商,其中A给出的价格最低,性价比最高,那么假如你是这家企业的采购经理,你会如何决策? 
    
     传统决策: A:100%订单  B,C,D:0% 
  
  &nbs</div>
                                </li>
                                <li><a href="/article/858.htm"
                                       title="centos 安装 Codeblocks" target="_blank">centos 安装 Codeblocks</a>
                                    <span class="text-muted">随便小屋</span>
<a class="tag" taget="_blank" href="/search/codeblocks/1.htm">codeblocks</a>
                                    <div>1.安装gcc,需要c和c++两部分,默认安装下,CentOS不安装编译器的,在终端输入以下命令即可yum install gccyum install gcc-c++ 
  
2.安装gtk2-devel,因为默认已经安装了正式产品需要的支持库,但是没有安装开发所需要的文档.yum install gtk2* 
3. 安装wxGTK 
   yum search w</div>
                                </li>
                                <li><a href="/article/985.htm"
                                       title="23种设计模式的形象比喻" target="_blank">23种设计模式的形象比喻</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a>
                                    <div>1、ABSTRACT FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory    工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:</div>
                                </li>
                                <li><a href="/article/1112.htm"
                                       title="开发管理 CheckLists" target="_blank">开发管理 CheckLists</a>
                                    <span class="text-muted">aoyouzi</span>
<a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E7%AE%A1%E7%90%86+CheckLists/1.htm">开发管理 CheckLists</a>
                                    <div>开发管理 CheckLists(23) -使项目组度过完整的生命周期 
开发管理 CheckLists(22) -组织项目资源 
开发管理 CheckLists(21) -控制项目的范围开发管理 CheckLists(20) -项目利益相关者责任开发管理 CheckLists(19) -选择合适的团队成员开发管理 CheckLists(18) -敏捷开发 Scrum Master 工作开发管理 C</div>
                                </li>
                                <li><a href="/article/1239.htm"
                                       title="js实现切换" target="_blank">js实现切换</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/%E6%A0%8F%E7%9B%AE%E5%88%87%E6%8D%A2/1.htm">栏目切换</a>
                                    <div>js主要功能之一就是实现页面的特效,窗体的切换可以减少页面的大小,被门户网站大量应用思路: 
   1,先将要显示的设置为display:bisible  否则设为none
    2,设置栏目的id  ,js获取栏目的id,如果id为Null就设置为显示
    3,判断js获取的id名字;再设置是否显示
 
  
代码实现: 
  
html代码: 
  <di</div>
                                </li>
                                <li><a href="/article/1366.htm"
                                       title="周鸿祎在360新员工入职培训上的讲话" target="_blank">周鸿祎在360新员工入职培训上的讲话</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/%E6%84%9F%E6%82%9F/1.htm">感悟</a><a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86/1.htm">项目管理</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E7%94%9F/1.htm">人生</a><a class="tag" taget="_blank" href="/search/%E8%81%8C%E5%9C%BA/1.htm">职场</a>
                                    <div>        这篇文章也是最近偶尔看到的,考虑到原博客发布者可能将其删除等原因,也更方便个人查找,特将原文拷贝再发布的。“学东西是为自己的,不要整天以混的姿态来跟公司博弈,就算是混,我觉得你要是能在混的时间里,收获一些别的有利于人生发展的东西,也是不错的,看你怎么把握了”,看了之后,对这句话记忆犹新。  &</div>
                                </li>
                                <li><a href="/article/1493.htm"
                                       title="前端Web开发的页面效果" target="_blank">前端Web开发的页面效果</a>
                                    <span class="text-muted">Bill_chen</span>
<a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/Microsoft/1.htm">Microsoft</a>
                                    <div>1.IE6下png图片的透明显示: 
<img src="图片地址" border="0" style="Filter.Alpha(Opacity)=数值(100),style=数值(3)"/> 
或在<head></head>间加一段JS代码让透明png图片正常显示。 
 
2.<li>标</div>
                                </li>
                                <li><a href="/article/1620.htm"
                                       title="【JVM五】老年代垃圾回收:并发标记清理GC(CMS GC)" target="_blank">【JVM五】老年代垃圾回收:并发标记清理GC(CMS GC)</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/1.htm">垃圾回收</a>
                                    <div>  CMS概述 
并发标记清理垃圾回收(Concurrent Mark and Sweep GC)算法的主要目标是在GC过程中,减少暂停用户线程的次数以及在不得不暂停用户线程的请夸功能,尽可能短的暂停用户线程的时间。这对于交互式应用,比如web应用来说,是非常重要的。 
  
CMS垃圾回收针对新生代和老年代采用不同的策略。相比同吞吐量垃圾回收,它要复杂的多。吞吐量垃圾回收在执</div>
                                </li>
                                <li><a href="/article/1747.htm"
                                       title="Struts2技术总结" target="_blank">Struts2技术总结</a>
                                    <span class="text-muted">白糖_</span>
<a class="tag" taget="_blank" href="/search/struts2/1.htm">struts2</a>
                                    <div>  
 
 必备jar文件 
   
 早在struts2.0.*的时候,struts2的必备jar包需要如下几个: 
commons-logging-*.jar   Apache旗下commons项目的log日志包 
freemarker-*.jar          </div>
                                </li>
                                <li><a href="/article/1874.htm"
                                       title="Jquery easyui layout应用注意事项" target="_blank">Jquery easyui layout应用注意事项</a>
                                    <span class="text-muted">bozch</span>
<a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a><a class="tag" taget="_blank" href="/search/easyui/1.htm">easyui</a><a class="tag" taget="_blank" href="/search/layout/1.htm">layout</a>
                                    <div>在jquery easyui中提供了easyui-layout布局,他的布局比较局限,类似java中GUI的border布局。下面对其使用注意事项作简要介绍: 
     如果在现有的工程中前台界面均应用了jquery easyui,那么在布局的时候最好应用jquery eaysui的layout布局,否则在表单页面(编辑、查看、添加等等)在不同的浏览器会出</div>
                                </li>
                                <li><a href="/article/2001.htm"
                                       title="java-拷贝特殊链表:有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何拷贝这个特殊链表?" target="_blank">java-拷贝特殊链表:有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何拷贝这个特殊链表?</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>
public class CopySpecialLinkedList {

	/**
	 * 题目:有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何拷贝这个特殊链表?
拷贝pNext指针非常容易,所以题目的难点是如何拷贝pRand指针。
假设原来链表为A1 -> A2 ->... -> An,新拷贝</div>
                                </li>
                                <li><a href="/article/2128.htm"
                                       title="color" target="_blank">color</a>
                                    <span class="text-muted">Chen.H</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a>
                                    <div><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd">    <HTML>    <HEAD>&nbs</div>
                                </li>
                                <li><a href="/article/2255.htm"
                                       title="[信息与战争]移动通讯与网络" target="_blank">[信息与战争]移动通讯与网络</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a>
                                    <div>      两个坚持:手机的电池必须可以取下来 
               光纤不能够入户,只能够到楼宇 
 
      建议大家找这本书看看:<&</div>
                                </li>
                                <li><a href="/article/2382.htm"
                                       title="oracle flashback query(闪回查询)" target="_blank">oracle flashback query(闪回查询)</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/flashback+query/1.htm">flashback query</a><a class="tag" taget="_blank" href="/search/flashback+table/1.htm">flashback table</a>
                                    <div>在Oracle 10g中,Flash back家族分为以下成员: 
Flashback Database 
Flashback Drop 
Flashback Table 
Flashback Query(分Flashback Query,Flashback Version Query,Flashback Transaction Query) 
下面介绍一下Flashback Drop 和Flas</div>
                                </li>
                                <li><a href="/article/2509.htm"
                                       title="zeus持久层DAO单元测试" target="_blank">zeus持久层DAO单元测试</a>
                                    <span class="text-muted">deng520159</span>
<a class="tag" taget="_blank" href="/search/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/1.htm">单元测试</a>
                                    <div>zeus代码测试正紧张进行中,但由于工作比较忙,但速度比较慢.现在已经完成读写分离单元测试了,现在把几种情况单元测试的例子发出来,希望有人能进出意见,让它走下去. 
本文是zeus的dao单元测试: 
1.单元测试直接上代码 
  
package com.dengliang.zeus.webdemo.test;


import org.junit.Test;
import o</div>
                                </li>
                                <li><a href="/article/2636.htm"
                                       title="C语言学习三printf函数和scanf函数学习" target="_blank">C语言学习三printf函数和scanf函数学习</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/printf/1.htm">printf</a><a class="tag" taget="_blank" href="/search/scanf/1.htm">scanf</a><a class="tag" taget="_blank" href="/search/language/1.htm">language</a>
                                    <div>printf函数 
/*
	2013年3月10日20:42:32
	地点:北京潘家园
	功能:
	目的:
		测试%x %X %#x %#X的用法
 */

# include <stdio.h>

int main(void)
{

	printf("哈哈!\n");  // \n表示换行

	int i = 10;
	printf</div>
                                </li>
                                <li><a href="/article/2763.htm"
                                       title="那你为什么小时候不好好读书?" target="_blank">那你为什么小时候不好好读书?</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/life/1.htm">life</a>
                                    <div>dady, 我今天捡到了十块钱, 不过我还给那个人了 
good girl! 那个人有没有和你讲thank you啊 
没有啦....他拉我的耳朵我才把钱还给他的, 他哪里会和我讲thank you 
  
爸爸, 如果地上有一张5块一张10块你拿哪一张呢.... 
当然是拿十块的咯... 
爸爸你很笨的, 你不会两张都拿 
  
爸爸为什么上个月那个人来跟你讨钱, 你告诉他没</div>
                                </li>
                                <li><a href="/article/2890.htm"
                                       title="iptables开放端口" target="_blank">iptables开放端口</a>
                                    <span class="text-muted">Fanyucai</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/iptables/1.htm">iptables</a><a class="tag" taget="_blank" href="/search/%E7%AB%AF%E5%8F%A3/1.htm">端口</a>
                                    <div>1,找到配置文件 
vi /etc/sysconfig/iptables   
  
2,添加端口开放,增加一行,开放18081端口 
-A INPUT -m state --state NEW -m tcp -p tcp --dport 18081 -j ACCEPT 
  
3,保存 
ESC
:wq! 
  
4,重启服务 
service iptables </div>
                                </li>
                                <li><a href="/article/3017.htm"
                                       title="Ehcache(05)——缓存的查询" target="_blank">Ehcache(05)——缓存的查询</a>
                                    <span class="text-muted">234390216</span>
<a class="tag" taget="_blank" href="/search/%E6%8E%92%E5%BA%8F/1.htm">排序</a><a class="tag" taget="_blank" href="/search/ehcache/1.htm">ehcache</a><a class="tag" taget="_blank" href="/search/%E7%BB%9F%E8%AE%A1/1.htm">统计</a><a class="tag" taget="_blank" href="/search/query/1.htm">query</a>
                                    <div>缓存的查询 
目录 
1.    使Cache可查询 
1.1     基于Xml配置 
1.2     基于代码的配置 
2     指定可搜索的属性 
2.1     可查询属性类型 
2.2 &</div>
                                </li>
                                <li><a href="/article/3144.htm"
                                       title="通过hashset找到数组中重复的元素" target="_blank">通过hashset找到数组中重复的元素</a>
                                    <span class="text-muted">jackyrong</span>
<a class="tag" taget="_blank" href="/search/hashset/1.htm">hashset</a>
                                    <div>  如何在hashset中快速找到重复的元素呢?方法很多,下面是其中一个办法: 
 
 


 int[] array = {1,1,2,3,4,5,6,7,8,8};
         
        Set<Integer> set = new HashSet<Integer>();
         
        for(int i = 0</div>
                                </li>
                                <li><a href="/article/3271.htm"
                                       title="使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL" target="_blank">使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL</a>
                                    <span class="text-muted">lanrikey</span>
<a class="tag" taget="_blank" href="/search/history/1.htm">history</a>
                                    <div>后退时关闭当前页面 
<script type="text/javascript"> 
 jQuery(document).ready(function ($) { 
        if (window.history && window.history.pushState) {</div>
                                </li>
                                <li><a href="/article/3398.htm"
                                       title="应用程序的通信成本" target="_blank">应用程序的通信成本</a>
                                    <span class="text-muted">netkiller.github.com</span>
<a class="tag" taget="_blank" href="/search/%E8%99%9A%E6%8B%9F%E6%9C%BA/1.htm">虚拟机</a><a class="tag" taget="_blank" href="/search/%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">应用服务器</a><a class="tag" taget="_blank" href="/search/%E9%99%88%E6%99%AF%E5%B3%B0/1.htm">陈景峰</a><a class="tag" taget="_blank" href="/search/netkiller/1.htm">netkiller</a><a class="tag" taget="_blank" href="/search/neo/1.htm">neo</a>
                                    <div>应用程序的通信成本  
什么是通信 
一个程序中两个以上功能相互传递信号或数据叫做通信。  
什么是成本 
这是是指时间成本与空间成本。 时间就是传递数据所花费的时间。空间是指传递过程耗费容量大小。  
都有哪些通信方式 
 
 全局变量 
 线程间通信 
 共享内存 
 共享文件 
 管道 
 Socket 
 硬件(串口,USB) 等等 
  
全局变量 
全局变量是成本最低通信方法,通过设置</div>
                                </li>
                                <li><a href="/article/3525.htm"
                                       title="一维数组与二维数组的声明与定义" target="_blank">一维数组与二维数组的声明与定义</a>
                                    <span class="text-muted">恋洁e生</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84/1.htm">二维数组</a><a class="tag" taget="_blank" href="/search/%E4%B8%80%E7%BB%B4%E6%95%B0%E7%BB%84/1.htm">一维数组</a><a class="tag" taget="_blank" href="/search/%E5%AE%9A%E4%B9%89/1.htm">定义</a><a class="tag" taget="_blank" href="/search/%E5%A3%B0%E6%98%8E/1.htm">声明</a><a class="tag" taget="_blank" href="/search/%E5%88%9D%E5%A7%8B%E5%8C%96/1.htm">初始化</a>
                                    <div>/**  *   */ package test20111005; /**  * @author FlyingFire  * @date:2011-11-18 上午04:33:36  * @author :代码整理  * @introduce :一维数组与二维数组的初始化  *summary:  */ public c</div>
                                </li>
                                <li><a href="/article/3652.htm"
                                       title="Spring Mybatis独立事务配置" target="_blank">Spring Mybatis独立事务配置</a>
                                    <span class="text-muted">toknowme</span>
<a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a>
                                    <div>在项目中有很多地方会使用到独立事务,下面以获取主键为例      
(1)修改配置文件spring-mybatis.xml    <!-- 开启事务支持 -->    <tx:annotation-driven transaction-manager="transactionManager" />       &n</div>
                                </li>
                                <li><a href="/article/3779.htm"
                                       title="更新Anadroid SDK Tooks之后,Eclipse提示No update were found" target="_blank">更新Anadroid SDK Tooks之后,Eclipse提示No update were found</a>
                                    <span class="text-muted">xp9802</span>
<a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a>
                                    <div>使用Android SDK Manager 更新了Anadroid SDK Tooks 之后, 
打开eclipse提示 This Android SDK requires Android Developer Toolkit version 23.0.0 or above, 点击Check for Updates  
检测一会后提示 No update were found  </div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>