第01章:项目规划
在开始编码之前,我们需要做好充分的规划。这一章将带你完成需求分析和技术选型。
📋 本章目标
- ✅ 明确项目需求
- ✅ 分析技术方案
- ✅ 确定技术选型
- ✅ 设计API接口
预计时间:15分钟
1. 需求分析
1.1 什么是水印?
水印(Watermark)是覆盖在内容上的半透明标记,用于:
- 🔒 版权保护 - 标识内容所有者
- 🛡️ 防止泄密 - 追踪信息来源
- 📋 信息展示 - 显示用户信息、时间等
1.2 应用场景
┌─────────────────────────┐
│ 📄 文档预览系统 │
│ - PDF查看器 │
│ - Word在线预览 │
│ - 合同管理系统 │
└─────────────────────────┘
┌─────────────────────────┐
│ 🖼️ 图片/视频平台 │
│ - 图片网站 │
│ - 视频网站 │
│ - 设计作品展示 │
└─────────────────────────┘
┌─────────────────────────┐
│ 🏢 企业管理系统 │
│ - OA系统 │
│ - ERP系统 │
│ - 数据大屏 │
└─────────────────────────┘
1.3 核心需求
| 需求 | 优先级 | 说明 |
|---|---|---|
| 显示水印 | P0 | 必须能在页面显示水印 |
| 自定义内容 | P0 | 可以自定义水印文字 |
| 自定义样式 | P1 | 字体、颜色、大小等 |
| 防删除 | P1 | 防止用户删除水印 |
| 性能优秀 | P1 | 不影响页面性能 |
| TypeScript | P1 | 提供类型支持 |
| 易用性 | P2 | API简单易用 |
| 多框架支持 | P2 | 支持React/Vue/原生JS |
2. 技术方案对比
2.1 方案一:DOM实现
实现方式:
// 创建多个span元素拼成水印
for (let i = 0; i < 100; i++) {
const span = document.createElement('span');
span.textContent = '水印';
span.style.position = 'absolute';
container.appendChild(span);
}
优点:
- ✅ 实现简单
- ✅ 容易理解
- ✅ 兼容性好
缺点:
- ❌ 创建大量DOM节点(100+)
- ❌ 性能开销大
- ❌ 内存占用高
- ❌ 首屏渲染慢
2.2 方案二:Canvas实现 ⭐推荐
实现方式:
// 用Canvas绘制一个水印单元
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.fillText('水印', x, y);
// 转换为图片,通过CSS背景重复
const base64 = canvas.toDataURL();
div.style.backgroundImage = `url(${base64})`;
div.style.backgroundRepeat = 'repeat';
优点:
- ✅ 只创建1个DOM节点
- ✅ 性能优秀
- ✅ 内存占用低
- ✅ 支持复杂图形
缺点:
- ❌ 稍微复杂一点
- ❌ 需要学习Canvas API
2.3 方案三:SVG实现
实现方式:
// 使用SVG绘制水印
const svg = `
<svg>
<text>水印</text>
</svg>
`;
div.style.backgroundImage = `url(data:image/svg+xml,${svg})`;
优点:
- ✅ 矢量图形,清晰
- ✅ 文件小
缺点:
- ❌ 复杂图形性能不如Canvas
- ❌ 兼容性问题
2.4 最终选择
我们选择:Canvas方案 ✅
理由:
- 性能最优
- 功能最强
- 兼容性好
- 行业主流
3. 技术选型
3.1 核心技术栈
| 技术 | 用途 | 为什么选择 |
|---|---|---|
| Canvas API | 绘制水印 | 性能最好 |
| MutationObserver | 防删除 | 原生API,性能好 |
| TypeScript | 类型系统 | 提供类型提示 |
| tsup | 打包工具 | 零配置,速度快 |
| pnpm/npm | 包管理器 | 标准工具 |
3.2 为什么用TypeScript?
// ❌ JavaScript - 没有类型提示
const watermark = new Watermark({
content: '水印',
fontsize: 16 // 拼写错误!运行时才发现
});
// ✅ TypeScript - 编写时就发现错误
const watermark = new Watermark({
content: '水印',
fontsize: 16 // ❌ 编辑器直接提示错误
fontSize: 16 // ✅ 正确
});
3.3 为什么用tsup?
传统方式(Webpack/Rollup):
// webpack.config.js - 100行配置
module.exports = {
entry: './src/index.ts',
output: { /* ... */ },
module: { rules: [/* ... */] },
plugins: [/* ... */],
// 还有很多配置...
};
tsup方式:
{
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts"
}
}
一行搞定!✨
4. API设计
4.1 设计原则
- 简单易用 - 最少配置即可使用
- 灵活强大 - 支持高度自定义
- 类型安全 - TypeScript全面支持
- 符合直觉 - API命名清晰
4.2 API设计
基础使用
// 1. 创建实例
const watermark = new Watermark({
content: '机密文档'
});
// 2. 显示水印
watermark.create();
// 3. 更新水印
watermark.update({ content: '新内容' });
// 4. 移除水印
watermark.remove();
// 5. 销毁实例
watermark.destroy();
配置选项
interface WatermarkOptions {
// 必填
content: string; // 水印内容
// 可选 - 样式
fontSize?: number; // 字体大小,默认14
color?: string; // 颜色,默认rgba(0,0,0,0.15)
fontFamily?: string; // 字体,默认Arial
rotate?: number; // 旋转角度,默认-20
opacity?: number; // 透明度,默认1
// 可选 - 布局
width?: number; // 宽度,默认200
height?: number; // 高度,默认150
gap?: { x: number; y: number }; // 间距
// 可选 - 高级
zIndex?: number; // 层级,默认999999
container?: HTMLElement; // 容器,默认body
observe?: boolean; // 防删除,默认true
}
4.3 使用示例
// 最简单的使用
new Watermark({ content: '水印' }).create();
// 自定义样式
new Watermark({
content: '机密文档',
fontSize: 20,
color: 'rgba(255, 0, 0, 0.2)',
rotate: -30
}).create();
// 多行文本
new Watermark({
content: '机密文档\n请勿外传\n2025-10-21'
}).create();
// 局部水印
const container = document.getElementById('app');
new Watermark({
content: '局部水印',
container: container
}).create();
5. 项目结构
5.1 目录规划
watermark-package/
├── src/ # 源代码
│ ├── index.ts # 入口文件
│ ├── types.ts # 类型定义
│ └── watermark.ts # 核心逻辑
├── examples/ # 使用示例
│ ├── basic.html # HTML示例
│ └── react-demo.tsx # React示例
├── dist/ # 构建产物(自动生成)
│ ├── index.js # CommonJS
│ ├── index.mjs # ES Module
│ └── index.d.ts # 类型定义
├── package.json # npm配置
├── tsconfig.json # TS配置
├── README.md # 文档
└── LICENSE # 开源协议
5.2 为什么这样组织?
src/ → 源代码,开发时编辑
├── index.ts → 统一导出,清晰的API
├── types.ts → 类型定义,便于维护和导出
└── watermark.ts → 核心逻辑,单一职责
examples/ → 使用示例,方便测试和展示
dist/ → 构建产物,发布到npm
6. 开发计划
6.1 开发步骤
第1步:环境准备 (15分钟)
→ 安装Node.js、npm
→ 创建项目目录
→ 初始化package.json
第2步:学习基础 (2-3小时)
→ Canvas API
→ TypeScript基础
→ MutationObserver
第3步:核心开发 (4-6小时)
→ 实现Canvas绘制
→ 实现DOM操作
→ 实现防删除
→ 完善功能
第4步:工程化 (2-3小时)
→ 配置TypeScript
→ 配置打包工具
→ 编写文档
第5步:测试优化 (2-3小时)
→ 本地测试
→ 性能优化
→ 编写示例
第6步:发布 (1-2小时)
→ npm发布
→ 版本管理
6.2 时间规划
| 阶段 | 时间 | 累计 |
|---|---|---|
| 准备阶段 | 30分钟 | 0.5小时 |
| 学习阶段 | 2-3小时 | 3.5小时 |
| 开发阶段 | 4-6小时 | 9.5小时 |
| 工程化 | 2-3小时 | 12.5小时 |
| 测试优化 | 2-3小时 | 15.5小时 |
| 发布维护 | 1-2小时 | 17.5小时 |
总计:17-18小时(分3-5天完成)
7. 成功标准
7.1 功能完成度
- 能够显示水印
- 支持自定义样式
- 支持防删除
- 支持动态更新
- 支持TypeScript
- 性能优秀
7.2 质量标准
- 代码规范
- 类型完整
- 文档齐全
- 示例丰富
- 测试通过
7.3 发布标准
- 可以成功构建
- 可以本地测试
- 可以发布到npm
- 可以被其他项目使用
8. 本章总结
你学到了什么?
✅ 水印的应用场景和需求
✅ DOM vs Canvas vs SVG三种方案对比
✅ 为什么选择Canvas + TypeScript
✅ 如何设计简洁易用的API
✅ 项目目录结构规划
✅ 完整的开发计划
下一步
现在你已经完成了项目规划,接下来我们要准备开发环境。
📝 本章检查清单
完成以下检查:
- 理解了水印的应用场景
- 知道为什么选择Canvas方案
- 了解了API的设计思路
- 清楚项目的目录结构
- 明确了开发步骤和时间
全部完成?继续下一章 → 02-环境准备
💡 思考题
- 除了Canvas,你能想到其他实现水印的方法吗?
- 如果要实现图片水印,应该怎么做?
- 水印能100%防止被删除吗?为什么?
带着这些问题,继续学习!🚀