最新demo

HTML5高级特性:Canvas绘图与本地存储

5月 2025
Updated 5月 2025

HTML5高级特性:Canvas绘图与本地存储

HTML5带来了许多革命性的新特性,使Web应用程序能够实现以前只有原生应用才能实现的功能。本文将深入探讨两个强大的HTML5功能:Canvas绘图API和本地存储技术。

Canvas绘图API

Canvas是HTML5引入的一个强大元素,它提供了一个可编程的绘图区域,允许开发者使用JavaScript动态生成和渲染图形、图表、图像和动画。

基础用法

首先,在HTML中创建一个Canvas元素:

1
<canvas id="myCanvas" width="600" height="400"></canvas>

然后,使用JavaScript获取Canvas上下文并开始绘图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 绘制一个红色矩形
ctx.fillStyle = 'red';
ctx.fillRect(50, 50, 100, 75);

// 绘制一条线
ctx.beginPath();
ctx.moveTo(200, 50);
ctx.lineTo(300, 150);
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.stroke();

// 绘制一个圆
ctx.beginPath();
ctx.arc(400, 100, 50, 0, Math.PI * 2);
ctx.fillStyle = 'green';
ctx.fill();

绘制图像

Canvas可以绘制和操作图像:

1
2
3
4
5
6
7
8
9
const img = new Image();
img.src = 'example.jpg';
img.onload = function() {
// 绘制原始图像
ctx.drawImage(img, 50, 200);

// 绘制缩放的图像
ctx.drawImage(img, 300, 200, 150, 100);
};

动画效果

结合requestAnimationFrame,可以创建流畅的动画:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let x = 0;
function animate() {
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);

// 绘制移动的圆
ctx.beginPath();
ctx.arc(x, 100, 20, 0, Math.PI * 2);
ctx.fillStyle = 'purple';
ctx.fill();

// 更新位置
x = (x + 2) % canvas.width;

// 请求下一帧
requestAnimationFrame(animate);
}

animate();

交互功能

Canvas可以响应用户交互:

1
2
3
4
5
6
7
8
9
10
canvas.addEventListener('click', function(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;

ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI * 2);
ctx.fillStyle = 'orange';
ctx.fill();
});

本地存储技术

HTML5提供了多种在客户端存储数据的方法,使Web应用能够在不依赖服务器的情况下保存用户数据和应用状态。

localStorage和sessionStorage

这两个API提供了简单的键值对存储:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 存储数据
localStorage.setItem('username', 'John');
localStorage.setItem('preferences', JSON.stringify({theme: 'dark', fontSize: 'large'}));

// 读取数据
const username = localStorage.getItem('username');
const preferences = JSON.parse(localStorage.getItem('preferences'));

// 删除数据
localStorage.removeItem('username');

// 清除所有数据
localStorage.clear();

sessionStorage的用法与localStorage相同,但数据只在当前会话中有效,关闭标签页后数据会被清除。

IndexedDB

对于更复杂的数据存储需求,IndexedDB提供了一个完整的客户端数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 打开数据库
const request = indexedDB.open('MyDatabase', 1);

request.onupgradeneeded = function(event) {
const db = event.target.result;

// 创建对象存储
const store = db.createObjectStore('notes', { keyPath: 'id', autoIncrement: true });
store.createIndex('title', 'title', { unique: false });
store.createIndex('date', 'date', { unique: false });
};

request.onsuccess = function(event) {
const db = event.target.result;

// 添加数据
const transaction = db.transaction(['notes'], 'readwrite');
const store = transaction.objectStore('notes');

store.add({
title: '购物清单',
content: '牛奶, 面包, 鸡蛋',
date: new Date()
});

// 读取数据
const getRequest = store.get(1);
getRequest.onsuccess = function() {
console.log(getRequest.result);
};
};

应用缓存和Service Workers

HTML5引入了应用缓存(现已被弃用)和Service Workers,使Web应用能够在离线状态下运行:

1
2
3
4
5
6
7
8
9
10
// 注册Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker 注册成功:', registration);
})
.catch(error => {
console.log('Service Worker 注册失败:', error);
});
}

sw.js文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 安装Service Worker
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/',
'/index.html',
'/styles.css',
'/script.js',
'/images/logo.png'
]);
})
);
});

// 从缓存提供资源
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});

实际应用:绘图应用与自动保存

结合Canvas和本地存储,我们可以创建一个简单的绘图应用,自动保存用户的作品:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;
let lastX = 0;
let lastY = 0;

// 设置绘图样式
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.strokeStyle = '#000';

// 绘图功能
function draw(e) {
if (!isDrawing) return;

ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();

[lastX, lastY] = [e.offsetX, e.offsetY];

// 自动保存
saveDrawing();
}

canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
});

canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);

// 保存绘图到localStorage
function saveDrawing() {
localStorage.setItem('savedDrawing', canvas.toDataURL());
}

// 加载保存的绘图
function loadDrawing() {
const savedDrawing = localStorage.getItem('savedDrawing');
if (savedDrawing) {
const img = new Image();
img.src = savedDrawing;
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
}
}

// 页面加载时恢复绘图
window.onload = loadDrawing;

结语

HTML5的Canvas和本地存储功能为Web开发者提供了强大的工具,使Web应用能够提供更丰富的用户体验。Canvas使得复杂的图形和动画成为可能,而本地存储技术则使Web应用能够像原生应用一样保存数据和状态。

随着这些技术的不断发展和浏览器支持的改进,Web应用的功能和性能将继续接近甚至超越传统的原生应用。在下一篇文章中,我们将探讨HTML5的其他高级特性,如WebGL、WebRTC和Web Workers。