前端Canvas:让你的网站更具视觉冲击力

前端Canvas:让你的网站更具视觉冲击力

毒舌时刻

前端Canvas?这不是游戏开发才用的吗?

"Canvas性能差,我不用"——结果错过了丰富的视觉效果,
"Canvas太复杂了,我学不会"——结果只能用静态图片,
"我用CSS就够了,要Canvas干嘛"——结果无法实现复杂的动画效果。

醒醒吧,Canvas不是游戏开发的专利,前端也可以用它来创建丰富的视觉效果!

为什么你需要这个?

  • 丰富的视觉效果:创建动态图形、动画和游戏
  • 高性能:直接操作像素,性能优异
  • 交互性:支持鼠标、触摸等交互
  • 数据可视化:绘制图表、仪表盘等
  • 跨平台:在所有现代浏览器中运行

反面教材

// 反面教材:简单的Canvas绘制 function drawCircle() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // 绘制一个简单的圆形 ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); ctx.stroke(); } // 反面教材:没有优化的动画 function animate() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let x = 0; setInterval(() => { // 每次都清除整个画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制移动的矩形 ctx.fillStyle = 'blue'; ctx.fillRect(x, 50, 50, 50); x += 1; if (x > canvas.width) { x = 0; } }, 16); } 

正确的做法

// 正确的做法:Canvas基础绘制 function basicDrawing() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // 设置画布尺寸 canvas.width = 800; canvas.height = 600; // 绘制矩形 ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 100, 100); // 绘制圆形 ctx.beginPath(); ctx.arc(250, 100, 50, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); // 绘制路径 ctx.beginPath(); ctx.moveTo(350, 50); ctx.lineTo(450, 150); ctx.lineTo(350, 150); ctx.closePath(); ctx.strokeStyle = 'green'; ctx.lineWidth = 2; ctx.stroke(); // 绘制文本 ctx.font = '24px Arial'; ctx.fillStyle = 'black'; ctx.textAlign = 'center'; ctx.fillText('Canvas绘制示例', canvas.width / 2, 30); } // 正确的做法:Canvas动画 function canvasAnimation() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 800; canvas.height = 600; let x = 0; let y = canvas.height / 2; let dx = 2; let dy = 2; const radius = 20; function animate() { // 清除画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制移动的圆形 ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2); ctx.fillStyle = 'purple'; ctx.fill(); // 边界检测 if (x + radius > canvas.width || x - radius < 0) { dx = -dx; } if (y + radius > canvas.height || y - radius < 0) { dy = -dy; } // 更新位置 x += dx; y += dy; // 使用requestAnimationFrame requestAnimationFrame(animate); } animate(); } // 正确的做法:Canvas交互 function canvasInteraction() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 800; canvas.height = 600; let isDrawing = false; let lastX = 0; let lastY = 0; // 鼠标按下事件 canvas.addEventListener('mousedown', (e) => { isDrawing = true; [lastX, lastY] = [e.offsetX, e.offsetY]; }); // 鼠标移动事件 canvas.addEventListener('mousemove', (e) => { if (!isDrawing) return; ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(e.offsetX, e.offsetY); ctx.strokeStyle = 'black'; ctx.lineWidth = 2; ctx.stroke(); [lastX, lastY] = [e.offsetX, e.offsetY]; }); // 鼠标释放事件 canvas.addEventListener('mouseup', () => { isDrawing = false; }); // 鼠标离开事件 canvas.addEventListener('mouseout', () => { isDrawing = false; }); } // 正确的做法:Canvas数据可视化 function canvasChart() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 800; canvas.height = 600; // 数据 const data = [12, 19, 3, 5, 2, 3, 7, 11, 15, 18, 10, 6]; const labels = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']; // 绘制坐标系 const padding = 50; const chartWidth = canvas.width - padding * 2; const chartHeight = canvas.height - padding * 2; // X轴 ctx.beginPath(); ctx.moveTo(padding, canvas.height - padding); ctx.lineTo(canvas.width - padding, canvas.height - padding); ctx.stroke(); // Y轴 ctx.beginPath(); ctx.moveTo(padding, padding); ctx.lineTo(padding, canvas.height - padding); ctx.stroke(); // 绘制数据 const maxValue = Math.max(...data); const barWidth = chartWidth / data.length; data.forEach((value, index) => { const barHeight = (value / maxValue) * chartHeight; const x = padding + index * barWidth; const y = canvas.height - padding - barHeight; // 绘制柱子 ctx.fillStyle = 'rgba(54, 162, 235, 0.6)'; ctx.fillRect(x + 5, y, barWidth - 10, barHeight); // 绘制标签 ctx.font = '12px Arial'; ctx.fillStyle = 'black'; ctx.textAlign = 'center'; ctx.fillText(labels[index], x + barWidth / 2, canvas.height - padding + 15); }); // 绘制标题 ctx.font = '20px Arial'; ctx.fillStyle = 'black'; ctx.textAlign = 'center'; ctx.fillText('月度销售数据', canvas.width / 2, padding / 2); } // 正确的做法:Canvas图像处理 function canvasImageProcessing() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 800; canvas.height = 600; // 加载图像 const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { // 绘制原始图像 ctx.drawImage(img, 0, 0, 400, 300); // 获取图像数据 const imageData = ctx.getImageData(0, 0, 400, 300); const data = imageData.data; // 处理图像(灰度) for (let i = 0; i < data.length; i += 4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; const gray = (r + g + b) / 3; data[i] = gray; data[i + 1] = gray; data[i + 2] = gray; } // 绘制处理后的图像 ctx.putImageData(imageData, 400, 0); }; img.src = 'https://picsum.photos/800/600'; } 

毒舌点评

看看,这才叫前端Canvas!不是简单地绘制几个图形,而是创建丰富的视觉效果、动画和交互。

记住,Canvas是一个强大的工具,它可以让你创建从简单的图表到复杂的游戏等各种视觉效果。合理使用Canvas,可以让你的网站更具视觉冲击力。

所以,别再觉得Canvas复杂了,它是前端视觉效果的重要工具!

总结

  • 基础绘制:矩形、圆形、路径、文本等
  • 动画效果:使用requestAnimationFrame实现流畅动画
  • 交互操作:鼠标、触摸等事件处理
  • 数据可视化:绘制图表、仪表盘等
  • 图像处理:像素级操作,实现滤镜效果
  • 性能优化:合理使用缓存、避免频繁重绘
  • 响应式:根据容器大小调整画布尺寸
  • 工具库:使用Chart.js、Fabric.js等库简化开发

前端Canvas,让你的网站更具视觉冲击力!

Read more

OpenClaw 和 Claude Code、Cursor、Copilot 有什么区别

在了解了 OpenClaw 的基本能力之后,很多人都会产生一个很自然的问题: 它和常见的 AI 编程工具到底有什么区别? 比如: * Claude Code * Cursor * GitHub Copilot 这些工具看起来都能: * 写代码 * 改代码 * 提供建议 但如果你真正用过一段时间,就会发现: 它们解决的问题,其实不在一个层面。 这一篇我们就从实际使用角度,把它们的区别讲清楚。 一、先说结论:它们不是“替代关系” 很多人会下意识认为: OpenClaw 是不是 Cursor / Copilot 的升级版? 其实不是。 更准确的理解是: 它们分属于不同类型的工具,可以配合使用,而不是互相替代。 简单划分一下: * Copilot / Cursor:写代码的助手 * Claude Code:理解和修改代码的助手 * OpenClaw:执行任务的 Agent 接下来我们分别看。 二、

知网AIGC检测算法2026大升级:新规则解读+应对策略

2025年12月,知网悄悄升级了AIGC检测算法。很多同学发现,以前能通过的论文,现在突然被检测出高AI率。 这篇文章帮大家解读一下:新算法到底变了什么?我们应该怎么应对? 算法升级:变了什么 变化一:检测维度增加 旧算法主要看三个维度:词汇特征、句法特征、文本长度分布。 新算法加了两个维度: 语义一致性检测:检测整篇文章的语义是否过于「平滑」。人写东西会有观点碰撞、逻辑跳跃,AI写的东西从头到尾都很顺,太顺了反而可疑。 引用关联度检测:检测参考文献和正文内容的关联程度。AI有时候会「幽灵引用」,就是列了参考文献但正文里没有真正引用,或者引用的内容和文献不对应。 变化二:特征词库更新 知网维护着一个「AI特征词库」,记录AI喜欢用的词汇和表达方式。 2026年的更新重点关注了DeepSeek、豆包、Kimi这几个国产大模型的输出特征。比如: * 「基于……视角」 * 「在此背景下」 * 「通过……发现」 * 「研究表明」用得太频繁 * 「综合来看」「从整体而言」等过渡词 这些词以前不算AI特征,

5分钟搞定!ComfyUI Photoshop插件终极安装指南:让AI绘画直接在PS中完成

5分钟搞定!ComfyUI Photoshop插件终极安装指南:让AI绘画直接在PS中完成 【免费下载链接】Comfy-Photoshop-SDDownload this extension via the ComfyUI manager to establish a connection between ComfyUI and the Auto-Photoshop-SD plugin in Photoshop. https://github.com/AbdullahAlfaraj/Auto-Photoshop-StableDiffusion-Plugin 项目地址: https://gitcode.com/gh_mirrors/co/Comfy-Photoshop-SD 还在为AI绘画的繁琐流程而烦恼吗?每次都要在Photoshop和AI软件之间来回切换,不仅效率低下,还容易打断创作灵感。ComfyUI Photoshop插件完美解决了这一痛点,让你在熟悉的Photoshop环境中直接使用强大的AI功能,实现无缝创作体验。 🎯 为什么你需要ComfyUI Photoshop

Whisper-large-v3内容创作工具:短视频配音自动识别+多语字幕同步

Whisper-large-v3内容创作工具:短视频配音自动识别+多语字幕同步 1. 项目概述:多语言语音识别新选择 如果你正在寻找一个能够自动识别视频配音、生成多语言字幕的工具,那么Whisper-large-v3就是你的理想选择。这个基于OpenAI Whisper Large v3模型构建的语音识别Web服务,支持99种语言的自动检测与转录,专门为内容创作者量身定制。 想象一下这样的场景:你有一段中文讲解的短视频,需要添加英文、日文、法文字幕。传统方法需要逐句翻译、手动打时间轴,耗时又费力。而使用Whisper-large-v3,只需上传音频文件,系统就能自动识别内容并生成准确的字幕文件,支持几乎全球所有主流语言。 这个工具由by113小贝团队二次开发构建,将原本需要复杂技术背景才能使用的语音识别模型,封装成了简单易用的Web服务。无论你是短视频创作者、教育工作者,还是企业培训师,都能快速上手使用。 2. 核心功能特点 2.1 多语言自动识别 Whisper-large-v3最强大的功能是支持99种语言的自动检测。你不需要事先告诉系统音频是什么语言,它能智能识别