先做一个简单的绘制: 预载9张图标, 把每个图标按次序排列在 3x3 的空间内。代码如下:
var canvas = document.querySelector('#myCanvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
var ctx = canvas.getContext('2d')
function preload (list) {
var loaded = 0
var total = list.length
for (var i = 0; i < total; i++) {
var img = new Image()
img.src = list[i]
imgList.push(img)
img.onload = (e) => {
loaded ++
if(loaded == total){
start()
}
}
}
}
var preloadList = [
'/static/icon_1.png',
'/static/icon_2.png',
'/static/icon_3.png',
'/static/icon_4.png',
'/static/icon_5.png',
'/static/icon_6.png',
'/static/icon_7.png',
'/static/icon_8.png',
'/static/icon_9.png',
'/static/icon_10.png'
]
var imgList = []
preload(preloadList)
function start() {
imgList.forEach((img, index) => {
var row = index % 3
var col = Math.floor(index / 3)
ctx.drawImage(img, row * 100, col * 100)
})
}
效果如图:
如果只是静态的绘制, 这样完全没有问题。但是如果需要对特定的图标做单独的调整, 因为画布是一个整体, 也并没有记住单独某个图标的状态, 可能需要擦除整个画布, 再重新绘制每个元素, 并且对想要调整位置的图标单独处理
现在把画布作为一个 “容器”(Container). 容器内的每一个独立的视图部分, 称之为 “显示对象”(DisplayObject); 它们每个都有各自的坐标(x, y); 它们都是这个容器的”子元素”(children)。
当我们需要改变画布内容时, 找到想要改变的那个显示对象, 读取并修改相关属性, 最后刷新容器即可
代码如下:
function start() {
imgList.forEach((img, index) => {
var row = index % 3
var col = Math.floor(index / 3)
var bitmap = new DisplayObject(img)
bitmap.x = row * 100
bitmap.y = col * 100
children.push(bitmap)
})
updateView()
}
// 子显示对象合集
var children = []
// 更新视图的方法
function updateView () {
ctx.clearRect(0, 0, canvas.width, canvas.height)
children.forEach((child) => {
child.draw()
})
}
// 显示对象构造方法
var DisplayObject = function (img) {
this.img = img
this.x = 0
this.y = 0
this.draw = function () {
ctx.drawImage(this.img, this.x, this.y)
}
}
在以上的代码中, 9个图标由 9个 DisplayObject 所持有; 只需要改变某个显示对象的相关属性, 并最终刷新视图(updateView), 即可更新画布内容。