首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,206 阅读
2
类的加载
807 阅读
3
Spring Cloud OAuth2.0
773 阅读
4
SpringBoot自动装配原理
711 阅读
5
集合不安全问题
625 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Canvas
Linux
容器
Docker
Containerd
Kubernetes
Python
FastApi
牛牛生活
软考
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Canvas
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
Mybatis
Spring
蘇阿細
累计撰写
408
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Canvas
Linux
容器
Docker
Containerd
Kubernetes
Python
FastApi
牛牛生活
软考
页面
统计
关于
搜索到
408
篇与
的结果
2025-08-31
Typecho Redis缓存插件
这个插件一直断断续续的在写着,功能不多(刚好够用,代码的 java 味儿略重,狗头)github地址:https://github.com/suaxi/TypechoRedisCache已实现功能:首次访问时缓存文章的 cid、标题、分类、创建/修改时间、作者、内容(Redis 数据类型为 Hash)已缓存文章数量统计清除全部缓存清除指定文章缓存(通过文章 cid)禁用插件时清除所有缓存后续计划:优化 Redis 配置选项
2025年08月31日
18 阅读
0 评论
0 点赞
2025-08-14
动画
1. requestAnimationFrame<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>requestAnimationFrame</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') context.fillStyle = 'skyblue' // 画一个方形,使之随时间左右移动 // 调用 requestAnimationFrame 函数,使函数循环执行 let x = 0 function loop() { context.clearRect(0, 0, canvas.width, canvas.height) context.fillRect(x, 100, 100, 100, 100) x += 1 requestAnimationFrame(loop) } requestAnimationFrame(loop) </script> </body> </html>2. 环绕动画 - 行星运动<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>环绕动画-行星运动</title> <style> canvas { background-color: #4d5053; /* color: #4d5053; */ } </style> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 地球旋转的角度 let earthAngle = 0 // 月球旋转的角度 let moonAngle = 0 function loop() { context.save() context.clearRect(0, 0, canvas.width, canvas.height) // 太阳 context.beginPath() context.arc(250, 250, 60, 0, 2 * Math.PI) context.fillStyle = '#f1ce07' context.shadowColor = '#f1ce07' context.shadowBlur = 10 context.fill() context.closePath() // 地球 // 1. 将canvas的原点移至太阳的中心 context.beginPath() context.translate(250, 250) context.rotate(earthAngle * Math.PI / 180) // 2. 将canvas的原点移至地球的中心(使日-地-月的中心在一条水平线上) context.translate(170, 0) context.arc(0, 0, 15, 0, 2 * Math.PI) context.fillStyle = 'blue' context.shadowBlur = 0 context.fill() earthAngle += 0.3 context.closePath() // 月亮 context.beginPath() context.rotate(moonAngle * Math.PI / 180) context.arc(35, 0, 6, 0, 2 * Math.PI) context.fillStyle = 'white' context.shadowBlur = 0 context.fill() moonAngle += 1.3 context.closePath() context.restore() requestAnimationFrame(loop) } requestAnimationFrame(loop) </script> </body> </html>
2025年08月14日
21 阅读
0 评论
0 点赞
2025-08-13
变换
1. translate 位移<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>translate位移</title> <style> canvas { background-color: lightblue; display: block; margin: auto; } </style> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 位移(基于原点的变换) context.translate(100, 100) context.fillRect(10, 10, 100, 100) </script> </body> </html>2. rotate 旋转<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>rotate旋转</title> <style> canvas { background-color: lightblue; } </style> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 位移(基于原点的变换) context.translate(200, 200) context.rotate(45 * Math.PI / 180) context.fillRect(10, 10, 100, 100) </script> </body> </html>3. scale 缩放<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>缩放</title> <style> canvas { background-color: lightblue; } </style> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 缩放 context.scale(1.1, 2) context.fillRect(10, 10, 100, 100) </script> </body> </html>4. transform<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>transform</title> <style> canvas { background-color: lightblue; } </style> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') /* transform(a, b, c, d, e, f) 该方法集位移、旋转、缩放为一体 a 水平缩放 b 垂直倾斜 c 水平倾斜 d 垂直缩放 e 水平移动 f 垂直移动 */ context.transform(1.1, 45 * Math.PI / 180, 30 * Math.PI / 180, 1.4, 100, 100) context.fillRect(10, 10, 100, 100) </script> </body> </html>
2025年08月13日
8 阅读
0 评论
0 点赞
2025-08-13
滤镜
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>滤镜</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 滤镜 // context.filter = 'none' // 默认值 // context.filter = 'blur(5px)' // 模糊 // context.filter = 'brightness(70%)' // 亮度 // context.filter = 'contrast(25%)' // 对比度 // context.filter = 'grayscale(60%)' // 灰度 // context.filter = 'hue-rotate(100deg)' // 色彩旋转 // context.filter = 'invert(60%)' // 透明度 // context.filter = 'opacity(60%)' // 反相 // context.filter = 'saturate(300%)' // 饱和度 context.filter = 'sepia(300%)' // 褐度 const img = new Image() img.src = './images/test.jpg' img.onload = function() { context.drawImage(img, 100, 100) } </script> </body> </html>
2025年08月13日
7 阅读
0 评论
0 点赞
2025-08-12
文字
(1)绘制文字<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>绘制文字</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 文字属性 context.font = '200 16px Arial' // fillText(content, x, y, [maxWidth]) // 注:x, y为文字的左下角初始坐标 context.fillText('孙笑川', 100, 100) // maxWidth 属性一般不使用 context.fillText('孙笑川', 100, 200, 30) // strokeText(content, x, y, [maxWidth]) context.strokeText('孙笑川', 100, 300) </script> </body> </html>(2)绘制渐变的文字<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>绘制渐变的文字</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 文字属性 context.font = 'italic 40px Arial' // 渐变 let gradient = context.createLinearGradient(0, 0, 500, 0) gradient.addColorStop(0, 'yellow') gradient.addColorStop(0.25, 'orange') gradient.addColorStop(0.5, 'skyblue') gradient.addColorStop(0.75, 'purple') gradient.addColorStop(1, 'red') context.fillStyle = gradient // fillText(content, x, y, [maxWidth]) // 注:x, y为文字的左下角初始坐标 context.fillText('孙笑川', 100, 100) // maxWidth 属性一般不使用 context.fillText('孙笑川', 100, 200, 30) context.strokeStyle = gradient // strokeText(content, x, y, [maxWidth]) context.strokeText('孙笑川', 100, 300) </script> </body> </html>(3)文字的横向对齐方式<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>文字的横向对齐方式</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 辅助中线 context.strokeStyle = 'black' context.moveTo(250, 0) context.lineTo(250, 500) context.stroke() // 文字属性 context.font = 'italic 24px Arial' // 方向控制 direction context.direction = 'ltr' // 默认为从左到右 // 对齐方式 textAlign // context.textAlign = 'left' // context.textAlign = 'right' // context.textAlign = 'center' // fillText(content, x, y, [maxWidth]) // 注:x, y为文字的左下角初始坐标 context.fillText('孙笑川', 250, 100) context.direction = 'rtl' // 默认为从左到右 // strokeText(content, x, y, [maxWidth]) context.strokeText('孙笑川', 250, 300) </script> </body> </html>(4)文字的纵向对齐方式<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>文字的纵向对齐方式</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') const baselines = ['top', 'hanging', 'middle', 'alphabetic', 'ideographic'] context.font = '24px Arial' baselines.forEach((baseline, index) => { // 基线 context.textBaseline = baseline const y = 50 + index * 50 context.beginPath() context.moveTo(0, y + 0.5) context.lineTo(500, y + 0.5) context.stroke() context.fillText(`孙笑川(${baseline})`, 0, y) }) </script> </body> </html>
2025年08月12日
10 阅读
0 评论
0 点赞
2025-08-11
图片
1. 绘制图片<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>绘制图片</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 3.1 准备图片 let img = new Image() img.src = './images/test.jpg' // 图片加载时需要一定的时间(该加载过程不会阻塞js进程),需等待加载完成,才能绘制 img.onload = function () { // 3.2 使用 drawImage 方法 // 方法一:传入绘制的坐标,按图片原有的大小绘制 // context.drawImage(img, 100, 100) // 方法二:传入绘制的坐标和渲染的大小(宽、高) // context.drawImage(img, 20, img.height) // 方法三:传入要裁切的区域,渲染到页面上 context.drawImage(img, 10, 20, 15, 25, 100, 100, 100, 100) } </script> </body> </html>2. 动画使用的精灵图素材宽1260,高300,分为7份<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动画</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // 3.1 准备图片 let img = new Image() img.src = './images/sprite.png' // 图片加载时需要一定的时间(该加载过程不会阻塞js进程),需等待加载完成,才能绘制 img.onload = function () { let index = 0 setInterval(() => { context.clearRect(0, 0, canvas.width, canvas.height) context.drawImage(img, 180 * index, 0, 180, 300, 0, 0, 180, 300) index++ index %= 7 }, 100) } </script> </body> </html>
2025年08月11日
12 阅读
0 评论
0 点赞
2025-07-20
贝塞尔曲线
2. 贝塞尔曲线Canvas 提供了二阶和三阶的贝塞尔曲线方法:quadraticCurveTobezierCurveTo(1)二阶、三阶贝塞尔曲线<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>贝塞尔曲线</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // // 二阶贝塞尔曲线(第一个点是控制点) // // 3.1 起始点 // context.moveTo(100, 100) // // 3.2 调用 quadraticCurveTo 绘制二阶路径 // context.quadraticCurveTo(180, 230, 350, 100) // context.stroke() // 三阶贝塞尔曲线(第一、二个点是控制点) // 4.1 起始点 context.moveTo(100, 100) // 4.2 调用bezierCurveTo绘制三阶路径 context.bezierCurveTo(180, 210, 50, 280, 410, 360) context.stroke() </script> </body> </html>(2)使用 arcTo 绘制圆弧<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>arcTo绘制圆弧</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') // arcTo 绘制圆弧 // 3.1 起始点 context.moveTo(100, 100) // 3.2 调用 arcTo 方法,第一、二个参数为控制点,第三个参数为圆弧半径 context.arcTo(180, 100, 180, 180, 50) context.stroke() </script> </body> </html>
2025年07月20日
32 阅读
0 评论
0 点赞
2025-07-09
标准圆弧曲线
Canvas中的曲线分为两种:标准圆弧曲线、贝塞尔曲线1. 标准圆弧曲线(1)弧线<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>弧线</title> </head> <body> <script> // 1. 创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2. 获取 context 对象(画笔) const context = canvas.getContext('2d') // 画圆弧 /* 参数:圆心x, 圆心y, 弧度,圆弧起点,圆弧终点,是否逆时针(默认为false) */ context.arc(200, 200, 50, 90 * (Math.PI / 180), 180 * (Math.PI / 180), true) context.stroke() </script> </body> </html>(2)画一个笑脸<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>笑脸</title> </head> <body> <script> // 1. 创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2. 获取 context 对象(画笔) const context = canvas.getContext('2d') // 3.画笑脸 // 3.1 外圈大圆 context.arc(200, 200, 100, 0, 360 * (Math.PI / 180)) context.stroke() // 3.2 左眼 // 重新生成新的路径(即在两个不相关的图形之间要加上开始路径,闭合路径,取消两个图形之间的连线) context.beginPath() context.arc(150, 150, 20, 0, 360 * (Math.PI / 180)) context.stroke() context.closePath() // 3.3 右眼 context.beginPath() context.arc(250, 150, 20, 0, 360 * (Math.PI / 180)) context.stroke() context.closePath() // 3.4 鼻子 context.beginPath() context.arc(200, 195, 8, 0, 360 * (Math.PI / 180)) context.stroke() context.closePath() // 3.5 嘴巴 context.beginPath() context.arc(200, 200, 80, 0, 180 * (Math.PI / 180)) context.stroke() context.closePath() </script> </body> </html>(3)椭圆<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>椭圆</title> </head> <body> <script> // 1. 创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2. 获取 context 对象(画笔) const context = canvas.getContext('2d') // 画椭圆 /* 参数:圆心x,圆心y,x半径,y半径,椭圆旋转的角度(弧度),圆弧起点,圆弧终点,是否逆时针(默认为false) */ context.ellipse(300, 300, 200, 100, 0, 0, 360 * (Math.PI / 180)) context.stroke() </script> </body> </html>(4)使用fill填充图形<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用fill填充图形</title> </head> <body> <script> // 1. 创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2. 获取 context 对象(画笔) const context = canvas.getContext('2d') // 3.填充 context.moveTo(100, 100) context.lineTo(90, 220) context.lineTo(220, 150) // 调用fill方法时,路径会自动连接起始位置 // context.lineTo(100, 100) // context.fill() // 填充指定颜色 // context.fillStyle = 'lightblue' // context.fill() // 使用线性渐变填充 // const gradient = context.createLinearGradient(0, 0, 500, 500) // gradient.addColorStop(0, 'lightblue') // gradient.addColorStop(1, 'red') // context.fillStyle = gradient // context.fill() // 使用径向渐变填充 const gradient = context.createRadialGradient(150, 150, 0, 150, 150, 100) gradient.addColorStop(0, 'lightblue') gradient.addColorStop(1, 'orange') context.fillStyle = gradient context.fill() </script> </body> </html>(5)五子棋(5)五子棋<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>五子棋</title> <style> canvas { background-color: green; display: block; margin: 0 auto; } #tip { text-align: center; padding: 20px; } </style> </head> <body> <div id="tip">游戏开始</div> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 700 canvas.height = 700 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') const tip = document.getElementById('tip') // 3.棋盘 for (i = 0; i < 14; i++) { context.moveTo(50, 50 * i) context.lineTo(650, 50 * i) context.stroke() context.moveTo(50 * i, 50) context.lineTo(50 * i, 650) context.stroke() } // 5.棋子颜色判断标志位 let isBlackChess = true // 6.使用二维数组存储棋子 let circles = [] for(i = 0; i < 14; i ++) { circles[i] = [] } // 7.游戏结束判断标志位 let gameOver = false // 4.落子 canvas.addEventListener('click', e => { if (gameOver) { return } let { offsetX, offsetY } = e // 判断棋子不超出棋盘 if (offsetX < 25 || offsetY < 25 || offsetX > 675 || offsetY > 675) { return } // 6.1 格子位置 let gridX = Math.floor((offsetX + 25) / 50) let gridY = Math.floor((offsetY + 25) / 50) // 6.3 判断是否重复落子 if (circles[gridX][gridY]) { return } // 4.1 棋子位置 let x = gridX * 50 let y = gridY * 50 context.beginPath() context.arc(x, y, 20, 0, 2 * Math.PI) // 6.2 存储棋子 circles[gridX][gridY] = isBlackChess ? 'black' : 'white' // 5.1 设置棋子颜色 let chessGradientX = isBlackChess ? x - 10 : x + 10 let chessGradientY = isBlackChess ? y - 10 : y + 10 let gradient = context.createRadialGradient(chessGradientX, chessGradientY, 0, chessGradientX, chessGradientY, 30) gradient.addColorStop(0, isBlackChess ? 'gray' : '#666') gradient.addColorStop(1, isBlackChess ? 'black' : 'white') context.fillStyle = gradient // 5.2 设置棋子阴影 context.shadowColor = '#333' context.shadowOffsetX = 2.5 context.shadowOffsetY = 2 context.fill() context.closePath() // 7.判断当前是否有人获胜 gameOver = checkVertical(circles[gridX][gridY], gridX, gridY) || checkHorizontal(circles[gridX][gridY], gridX, gridY) || checkWn2Es(circles[gridX][gridY], gridX, gridY) || checkEn2Ws(circles[gridX][gridY], gridX, gridY) if (gameOver) { tip.innerText = `${isBlackChess ? '黑' : '白'}棋获胜,游戏结束!` //console.log(circles) return } tip.innerText = isBlackChess ? '请白棋落子' : '请黑棋落子' isBlackChess = !isBlackChess }) // 纵向查找是否有五个连续相同的棋子 function checkVertical(currentChess, row, col) { let count = 1 return checkUp(currentChess, row, col, count) + checkDown(currentChess, row, col, count) - 1 >= 5 } function checkUp(currentChess, row, col, count) { // 向上查找的次数 let up = 0 while (true) { // 向上查找 up++ // 角 // 左上角 if (row === 1 && col === 1) { return count } // 右上角 if (row + up === circles.length && col === 1) { return count } // 边 // 上 if (col === 1) { return count } // 右 pass // 下 pass // 左 pass // 超出边界 if (row - up < 0) { return count } if (circles[row][col - up] && circles[row][col - up] === currentChess) { count++ } // 棋子不连续 if (col === 1) { if (count >= 5 || (circles[row][col + up] !== currentChess)) { break } } else if (col + up >= circles.length) { if (count >= 5 || (circles[row][col - up] !== currentChess)) { break } } else { if (count >= 5 || (circles[row][col - up] !== currentChess && circles[row][col + up] !== currentChess)) { break } } } return count } function checkDown(currentChess, row, col, count) { // 向下查找的次数 let down = 0 while (true) { // 向下查找 down++ // 角 // 右下角 if (row + down === circles.length && col + down === circles.length) { return count } // 左下角 if (row === 1 && col + down === circles.length) { return count } // 边 // 上 pass // 右 pass // 下 if (col + down === circles.length) { return count } // 左 pass // 超出边界 if (row + down > circles.length) { return count } if (circles[row][col + down] && circles[row][col + down] === currentChess) { count++ } // 棋子不连续 if (col === 1) { if (count >= 5 || (circles[row][col - down] !== currentChess)) { break } } else if (col + down >= circles.length) { if (count >= 5 || (circles[row][col - down] !== currentChess)) { break } } else { if (count >= 5 || (circles[row][col - down] !== currentChess && circles[row][col + down] !== currentChess)) { break } } } return count } // 横向查找是否有五个连续相同的棋子 function checkHorizontal(currentChess, row, col) { let count = 1 return checkLeft(currentChess, row, col, count) + checkRight(currentChess, row, col, count) - 1 >= 5 } function checkLeft(currentChess, row, col, count) { // 向左查找的次数 let left = 0 while (true) { // 向左查找 left++ // 角 // 左上角 if (row === 1 && col === 1) { return count } // 左下角 if (row === 1 && col + left === circles.length) { return count } // 边 // 上 pass // 右 pass // 下 pass // 左 if (row === 1) { return count } // 超出边界 if (row - left < 0) { return count } if (circles[row - left][col] && circles[row - left][col] === currentChess) { count++ } // 棋子不连续 if (col === 1 && row + left < circles.length) { if (count >= 5 || (circles[row + left][col] !== currentChess)) { break } } else if (row + left >= circles.length) { if (count >= 5 || (circles[row - left][col] !== currentChess)) { break } } else { if (count >= 5 || (circles[row - left][col] !== currentChess && circles[row + left][col] !== currentChess)) { break } } } return count } function checkRight(currentChess, row, col, count) { // 向右查找的次数 let right = 0 while (true) { // 向右查找 right++ // 角 // 右上角 if (row + right === circles.length && col === 1) { return count } // 右下角 if (row + right === circles.length && col + right === circles.length) { return count } // 边 // 上 pass // 右 if (row + right === circles.length) { return count } // 下 pass // 左 pass if (circles[row + right][col] && circles[row + right][col] === currentChess) { count++ } // 超出边界 if (row + right > circles.length) { return count } // 同色棋子大于5 || 棋子不连续 if (col === 1 && row + right < circles.length) { if (count >= 5 || (circles[row + right][col] !== currentChess)) { break } } else if (row + right >= circles.length) { if (count >= 5 || (circles[row - right][col] !== currentChess)) { break } } else { if (count >= 5 || (circles[row - right][col] !== currentChess && circles[row + right][col] !== currentChess)) { break } } } return count } // 左上到右下查找是否有五个连续相同的棋子 function checkWn2Es(currentChess, row, col) { // 连续同色棋子的数量 let count = 1 return checkWn(currentChess, row, col, count) + checkEs(currentChess, row, col, count) - 1 >= 5 } function checkWn(currentChess, row, col, count) { // 左上查找的次数 let leftUp = 0 while (true) { // 向左上查找 leftUp++ // 角 // 左上角 if (row === 1 && col === 1) { return count } // 右上角 if (row + leftUp === circles.length && col === 1) { return count } // 左下角 if (row === 1 && col + leftUp === circles.length) { return count } // 边 // 上 if (col === 1) { return count } // 右 pass // 下 pass // 左 if (row === 1) { return count } // 超出边界 if (row - leftUp < 0 || col - leftUp < 0) { return count } if (circles[row - leftUp][col - leftUp] && circles[row - leftUp][col - leftUp] === currentChess) { count++ } // 同色棋子大于5 || 棋子不连续 if (row === 1 || col === 1) { if (count >= 5 || (circles[row + leftUp][col + leftUp] !== currentChess)) { break } } else if (row + leftUp >= circles.length || col + leftUp >= circles.length) { if (count >= 5 || circles[row - leftUp][col - leftUp] !== currentChess) { break } } else { if (count >= 5 || (circles[row - leftUp][col - leftUp] !== currentChess && circles[row + leftUp][col + leftUp] !== currentChess)) { break } } } return count } function checkEs(currentChess, row, col, count) { // 右下查找的次数 let rightDown = 0 while (true) { // 向右下查找 rightDown++ // 角 // 右上角 if (row + rightDown === circles.length && col === 1) { return count } // 右下角 if (row + rightDown === circles.length && col + rightDown === circles.length) { return count } // 左下角 if (row === 1 && col + rightDown === circles.length) { return count } // 边 // 上 pass // 右 if (row + rightDown === circles.length) { return count } // 下 if (col + rightDown === circles.length) { return count } // 左 pass // 超出边界 if (row + rightDown > circles.length || col + rightDown > circles.length) { return count } if (circles[row + rightDown][col + rightDown] && circles[row + rightDown][col + rightDown] === currentChess) { count++ } // 同色棋子大于5 || 棋子不连续 if (row === 1 || col === 1) { if (count >= 5 || (circles[row + rightDown][col + rightDown] !== currentChess)) { break } } else if (row + rightDown >= circles.length || col + rightDown >= circles.length) { if (count >= 5 || circles[row - rightDown][col - rightDown] !== currentChess) { break } } else { if (count >= 5 || row - rightDown < 0) { break } if (count >= 5 || (circles[row - rightDown][col - rightDown] !== currentChess && circles[row + rightDown][col + rightDown] !== currentChess)) { break } } } return count } // 右上到左下查找是否有五个连续相同的棋子 function checkEn2Ws(currentChess, row, col) { // 连续同色棋子的数量 let count = 1 return checkEn(currentChess, row, col, count) + checkWs(currentChess, row, col, count) - 1 >= 5 } function checkEn(currentChess, row, col, count) { // 右上查找的次数 let rightUp = 0 while (true) { // 向右上查找 rightUp++ // 角 // 左上角 if (row === 1 && col === 1) { return count } // 右上角 if (row + rightUp === circles.length && col === 1) { return count } // 右下角 if (row + rightUp === circles.length && col + rightUp === circles.length) { return count } // 边 // 上 if (col === 1) { return count } // 右 if (row + rightUp >= circles.length) { return count } // 下 pass // 左 pass // 超出边界 if (row + rightUp > circles.length || col - rightUp < 0) { return count } if (circles[row + rightUp][col - rightUp] && circles[row + rightUp][col - rightUp] === currentChess) { count++ } // 同色棋子大于5 || 棋子不连续 if (row === 1 || col + rightUp >= circles.length) { if (count >= 5 || (circles[row + rightUp][col - rightUp] !== currentChess)) { break } } else if (row + rightUp >= circles.length || col === 1) { if (count >= 5 || (circles[row - rightUp][col + rightUp] !== currentChess)) { break } } else { if (count >= 5 || row - rightUp < 0) { break } if (count >= 5 || (circles[row + rightUp][col - rightUp] !== currentChess && circles[row - rightUp][col + rightUp] !== currentChess)) { break } } } return count } function checkWs(currentChess, row, col, count) { // 左下查找的次数 let leftDown = 0 while (true) { // 向左下查找 leftDown++ // 角 // 左上角 if (row === 1 && col === 1) { return count } // 左下角 if (row === 1 && col + leftDown === circles.length) { return count } // 右下角 if (row + leftDown === circles.length && col + leftDown === circles.length) { return count } // 边 // 上 pass // 右 pass // 下 if (col === col + leftDown === circles.length) { return count } // 左 if (row === 1) { return count } // 超出边界 if (row - leftDown < 0 || col + leftDown > circles.length) { return count } if (circles[row - leftDown][col + leftDown] && circles[row - leftDown][col + leftDown] === currentChess) { count++ } // 同色棋子大于5 || 棋子不连续 if (row + leftDown >= circles.length || col === 1) { if (count >= 5 || circles[row - leftDown][col + leftDown] !== currentChess) { break } } else if (row === 1 || col + leftDown >= circles.length) { if (count >= 5 || (circles[row + leftDown][col - leftDown] !== currentChess)) { break } } else { if (count >= 5 || (circles[row - leftDown][col + leftDown] !== currentChess && circles[row + leftDown][col - leftDown] !== currentChess)) { break } } } return count } </script> </body> </html>(6)阴影<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>阴影</title> </head> <body> <script> // 1.创建 canvas 画布 const canvas = document.createElement('canvas') // 设置宽高 canvas.width = 500 canvas.height = 500 document.body.append(canvas) // 2.获取 context 对象(画笔) const context = canvas.getContext('2d') context.strokeStyle = 'green' context.lineWidth = 6 // 设置图像的阴影 context.shadowColor = 'gray' context.shadowOffsetX = 6 context.shadowOffsetY = 3 context.shadowBlur = 5 context.moveTo(100, 100) context.lineTo(260, 260) context.stroke() </script> </body> </html>
2025年07月09日
50 阅读
0 评论
0 点赞
1
2
...
51