"use strict"; class Matrix3 { constructor() { this.elements = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; } multiply(m) { const a = this.elements; const b = m.elements; return new Matrix3().set([ a[0] * b[0] + a[1] * b[3] + a[2] * b[6], a[0] * b[1] + a[1] * b[4] + a[2] * b[7], a[0] * b[2] + a[1] * b[5] + a[2] * b[8], a[3] * b[0] + a[4] * b[3] + a[5] * b[6], a[3] * b[1] + a[4] * b[4] + a[5] * b[7], a[3] * b[2] + a[4] * b[5] + a[5] * b[8], a[6] * b[0] + a[7] * b[3] + a[8] * b[6], a[6] * b[1] + a[7] * b[4] + a[8] * b[7], a[6] * b[2] + a[7] * b[5] + a[8] * b[8], ]); } translate(tx, ty) { return this.multiply(new Matrix3().set([ 1, 0, tx, 0, 1, ty, 0, 0, 1 ])); } scale(sx, sy) { return this.multiply(new Matrix3().set([ sx, 0, 0, 0, sy, 0, 0, 0, 1 ])); } rotate(angle) { const c = Math.cos(angle); const s = Math.sin(angle); return this.multiply(new Matrix3().set([ c, -s, 0, s, c, 0, 0, 0, 1 ])); } set(values) { this.elements = [...values]; return this; } transform(ctx) { const [a, b, c, d, e, f] = [ this.elements[0], this.elements[3], this.elements[1], this.elements[4], this.elements[2], this.elements[5] ]; //console.log('Applying transform:', { a, b, c, d, e, f }); ctx.transform(a, b, c, d, e, f); } } class MapDemo { constructor() { this.matrix = new Matrix3(); this.canvas = document.createElement('canvas'); this.ctx = this.canvas.getContext('2d'); this.initCanvas(); this.initControls(); this.draw(); } initCanvas() { this.canvas.width = 800; this.canvas.height = 600; this.canvas.style.border = '1px solid black'; document.body.appendChild(this.canvas); const dpr = window.devicePixelRatio || 1; this.canvas.width *= dpr; this.canvas.height *= dpr; this.ctx.scale(dpr, dpr); } initControls() { document.addEventListener('keydown', (e) => { //console.log('Key pressed:', e.key); const step = 20; const scaleFactor = 0.1; const rotateAngle = Math.PI / 18; //console.log('Before transform - Matrix:', this.matrix); switch (e.key.toLowerCase()) { case 'w': case 'arrowup': this.matrix = this.matrix.translate(0, -step); break; case 's': case 'arrowdown': this.matrix = this.matrix.translate(0, step); break; case 'a': case 'arrowleft': this.matrix = this.matrix.translate(-step, 0); break; case 'd': case 'arrowright': this.matrix = this.matrix.translate(step, 0); break; case 'z': this.matrix = this.matrix.scale(1 + scaleFactor, 1 + scaleFactor); break; case 'x': this.matrix = this.matrix.scale(1 - scaleFactor, 1 - scaleFactor); break; case 'q': this.matrix = this.matrix.rotate(-rotateAngle); break; case 'e': this.matrix = this.matrix.rotate(rotateAngle); break; } //console.log('After transform - Matrix:', this.matrix); e.preventDefault(); this.draw(); }); } drawGrid() { const ctx = this.ctx; ctx.strokeStyle = '#ddd'; ctx.lineWidth = 1; // 绘制网格 for (let x = -500; x <= 500; x += 50) { ctx.beginPath(); ctx.moveTo(x, -500); ctx.lineTo(x, 500); ctx.stroke(); ctx.beginPath(); ctx.moveTo(-500, x); ctx.lineTo(500, x); ctx.stroke(); } // 绘制坐标轴 ctx.strokeStyle = 'black'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(-500, 0); ctx.lineTo(500, 0); ctx.moveTo(0, -500); ctx.lineTo(0, 500); ctx.stroke(); // 绘制坐标标签 ctx.fillStyle = 'black'; ctx.font = '12px Arial'; for (let x = -500; x <= 500; x += 100) { ctx.fillText(x.toString(), x + 5, 15); ctx.fillText(x.toString(), 5, -x + 5); } } draw() { const ctx = this.ctx; // 保存当前状态并重置变换 ctx.save(); ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); ctx.restore(); // 应用当前矩阵变换 ctx.save(); this.matrix.transform(ctx); // 绘制内容 this.drawGrid(); ctx.restore(); } } // 初始化代码 document.addEventListener('DOMContentLoaded', () => { new MapDemo(); const info = document.createElement('div'); info.innerHTML = `
平移: W/A/S/D 或 方向键
缩放: Z/X
旋转: Q/E
`; document.body.appendChild(info); }); //# sourceMappingURL=matrix-demo.js.map