| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 | 
							- import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
 
- import { IonicModule } from '@ionic/angular';
 
- import { CommonModule } from '@angular/common';
 
- import { FormsModule } from '@angular/forms';
 
- @Component({
 
-   selector: 'app-drawing',
 
-   templateUrl: './drawing.component.html',
 
-   styleUrls: ['./drawing.component.scss'],
 
-   standalone: true,
 
-   imports: [IonicModule, CommonModule, FormsModule],
 
- })
 
- export class DrawingComponent implements OnInit, AfterViewInit {
 
-   @ViewChild('canvas') canvasRef!: ElementRef<HTMLCanvasElement>;
 
-   private ctx!: CanvasRenderingContext2D;
 
-   private isDrawing = false;
 
-   private lastX = 0;
 
-   private lastY = 0;
 
-   currentColor = '#000000';
 
-   currentWidth = 5;
 
-   customColor = '#000000';
 
-   showGrid = false;
 
-   opacity = 1;
 
-   smoothing = true;
 
-   showLayers = false;
 
-   currentLayer = 'layer1';
 
-   layers = [
 
-     { id: 'layer1', name: '图层 1', visible: true },
 
-     { id: 'layer2', name: '图层 2', visible: true }
 
-   ];
 
-   history: ImageData[] = [];
 
-   historyIndex = -1;
 
-   tools = [
 
-     { id: 'brush', icon: 'brush', name: '画笔' },
 
-     { id: 'eraser', icon: 'trash', name: '橡皮擦' },
 
-     { id: 'line', icon: 'remove', name: '直线' },
 
-     { id: 'rect', icon: 'square-outline', name: '矩形' },
 
-     { id: 'circle', icon: 'ellipse-outline', name: '圆形' },
 
-     { id: 'clear', icon: 'refresh', name: '清空' }
 
-   ];
 
-   colors = [
 
-     '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff',
 
-     '#ffff00', '#00ffff', '#ff00ff', '#808080', '#800000'
 
-   ];
 
-   selectedTool = 'brush';
 
-   constructor() { }
 
-   ngOnInit() { }
 
-   ngAfterViewInit() {
 
-     const canvas = this.canvasRef.nativeElement;
 
-     this.ctx = canvas.getContext('2d')!;
 
-     this.resizeCanvas();
 
-     this.initializeCanvas();
 
-     window.addEventListener('resize', () => {
 
-       this.resizeCanvas();
 
-     });
 
-   }
 
-   private resizeCanvas() {
 
-     const canvas = this.canvasRef.nativeElement;
 
-     canvas.width = window.innerWidth;
 
-     canvas.height = window.innerHeight - 200; // 减去顶部工具栏的高度
 
-   }
 
-   private initializeCanvas() {
 
-     this.ctx.fillStyle = '#ffffff';
 
-     this.ctx.fillRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
 
-   }
 
-   startDrawing(event: TouchEvent | MouseEvent) {
 
-     this.isDrawing = true;
 
-     const pos = this.getPosition(event);
 
-     this.lastX = pos.x;
 
-     this.lastY = pos.y;
 
-   }
 
-   draw(event: TouchEvent | MouseEvent) {
 
-     if (!this.isDrawing) return;
 
-     event.preventDefault();
 
-     const pos = this.getPosition(event);
 
-     switch (this.selectedTool) {
 
-       case 'brush':
 
-       case 'eraser':
 
-         this.drawFreehand(pos);
 
-         break;
 
-       case 'line':
 
-         this.drawLine(pos);
 
-         break;
 
-       case 'rect':
 
-         this.drawRect(pos);
 
-         break;
 
-       case 'circle':
 
-         this.drawCircle(pos);
 
-         break;
 
-     }
 
-   }
 
-   private drawFreehand(pos: { x: number, y: number }) {
 
-     this.ctx.beginPath();
 
-     this.ctx.moveTo(this.lastX, this.lastY);
 
-     this.ctx.lineTo(pos.x, pos.y);
 
-     this.ctx.strokeStyle = this.selectedTool === 'eraser' ? '#ffffff' : this.currentColor;
 
-     this.ctx.lineWidth = this.currentWidth;
 
-     this.ctx.lineCap = 'round';
 
-     this.ctx.stroke();
 
-     this.lastX = pos.x;
 
-     this.lastY = pos.y;
 
-   }
 
-   private drawLine(pos: { x: number, y: number }) {
 
-     const tempCanvas = document.createElement('canvas');
 
-     tempCanvas.width = this.canvasRef.nativeElement.width;
 
-     tempCanvas.height = this.canvasRef.nativeElement.height;
 
-     const tempCtx = tempCanvas.getContext('2d')!;
 
-     tempCtx.drawImage(this.canvasRef.nativeElement, 0, 0);
 
-     tempCtx.beginPath();
 
-     tempCtx.moveTo(this.lastX, this.lastY);
 
-     tempCtx.lineTo(pos.x, pos.y);
 
-     tempCtx.strokeStyle = this.currentColor;
 
-     tempCtx.lineWidth = this.currentWidth;
 
-     tempCtx.stroke();
 
-     this.ctx.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
 
-     this.ctx.drawImage(tempCanvas, 0, 0);
 
-   }
 
-   private drawRect(pos: { x: number, y: number }) {
 
-     const tempCanvas = document.createElement('canvas');
 
-     tempCanvas.width = this.canvasRef.nativeElement.width;
 
-     tempCanvas.height = this.canvasRef.nativeElement.height;
 
-     const tempCtx = tempCanvas.getContext('2d')!;
 
-     tempCtx.drawImage(this.canvasRef.nativeElement, 0, 0);
 
-     tempCtx.beginPath();
 
-     tempCtx.rect(this.lastX, this.lastY, pos.x - this.lastX, pos.y - this.lastY);
 
-     tempCtx.strokeStyle = this.currentColor;
 
-     tempCtx.lineWidth = this.currentWidth;
 
-     tempCtx.stroke();
 
-     this.ctx.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
 
-     this.ctx.drawImage(tempCanvas, 0, 0);
 
-   }
 
-   private drawCircle(pos: { x: number, y: number }) {
 
-     const tempCanvas = document.createElement('canvas');
 
-     tempCanvas.width = this.canvasRef.nativeElement.width;
 
-     tempCanvas.height = this.canvasRef.nativeElement.height;
 
-     const tempCtx = tempCanvas.getContext('2d')!;
 
-     const radius = Math.sqrt(
 
-       Math.pow(pos.x - this.lastX, 2) + Math.pow(pos.y - this.lastY, 2)
 
-     );
 
-     tempCtx.drawImage(this.canvasRef.nativeElement, 0, 0);
 
-     tempCtx.beginPath();
 
-     tempCtx.arc(this.lastX, this.lastY, radius, 0, Math.PI * 2);
 
-     tempCtx.strokeStyle = this.currentColor;
 
-     tempCtx.lineWidth = this.currentWidth;
 
-     tempCtx.stroke();
 
-     this.ctx.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
 
-     this.ctx.drawImage(tempCanvas, 0, 0);
 
-   }
 
-   stopDrawing() {
 
-     if (this.isDrawing) {
 
-       this.isDrawing = false;
 
-       this.saveToHistory();
 
-     }
 
-   }
 
-   private getPosition(event: TouchEvent | MouseEvent) {
 
-     const canvas = this.canvasRef.nativeElement;
 
-     const rect = canvas.getBoundingClientRect();
 
-     let x, y;
 
-     if (event instanceof TouchEvent) {
 
-       x = event.touches[0].clientX - rect.left;
 
-       y = event.touches[0].clientY - rect.top;
 
-     } else {
 
-       x = event.clientX - rect.left;
 
-       y = event.clientY - rect.top;
 
-     }
 
-     return { x, y };
 
-   }
 
-   selectTool(toolId: string) {
 
-     this.selectedTool = toolId;
 
-     if (toolId === 'clear') {
 
-       this.clearCanvas();
 
-     }
 
-   }
 
-   selectColor(color: string) {
 
-     this.currentColor = color;
 
-     this.selectedTool = 'brush';
 
-   }
 
-   clearCanvas() {
 
-     this.ctx.fillStyle = '#ffffff';
 
-     this.ctx.fillRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
 
-   }
 
-   async saveDrawing() {
 
-     const canvas = this.canvasRef.nativeElement;
 
-     try {
 
-       const dataUrl = canvas.toDataURL('image/png');
 
-       const response = await fetch(dataUrl);
 
-       const blob = await response.blob();
 
-       const url = window.URL.createObjectURL(blob);
 
-       const a = document.createElement('a');
 
-       a.href = url;
 
-       a.download = `绘画_${new Date().getTime()}.png`;
 
-       document.body.appendChild(a);
 
-       a.click();
 
-       window.URL.revokeObjectURL(url);
 
-       document.body.removeChild(a);
 
-       this.showToast('保存成功');
 
-     } catch (error) {
 
-       this.showToast('保存失败,请重试');
 
-     }
 
-   }
 
-   private async showToast(message: string) {
 
-     const toast = document.createElement('ion-toast');
 
-     toast.message = message;
 
-     toast.duration = 2000;
 
-     toast.position = 'top';
 
-     document.body.appendChild(toast);
 
-     await toast.present();
 
-   }
 
-   undo() {
 
-     if (this.historyIndex > 0) {
 
-       this.historyIndex--;
 
-       const imageData = this.history[this.historyIndex];
 
-       this.ctx.putImageData(imageData, 0, 0);
 
-     }
 
-   }
 
-   redo() {
 
-     if (this.historyIndex < this.history.length - 1) {
 
-       this.historyIndex++;
 
-       const imageData = this.history[this.historyIndex];
 
-       this.ctx.putImageData(imageData, 0, 0);
 
-     }
 
-   }
 
-   saveToHistory() {
 
-     this.historyIndex++;
 
-     this.history = this.history.slice(0, this.historyIndex);
 
-     this.history.push(this.ctx.getImageData(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height));
 
-   }
 
-   toggleGrid() {
 
-     this.showGrid = !this.showGrid;
 
-   }
 
-   toggleOpacity() {
 
-     this.opacity = this.opacity === 1 ? 0.5 : 1;
 
-     this.ctx.globalAlpha = this.opacity;
 
-   }
 
-   toggleSmooth() {
 
-     this.smoothing = !this.smoothing;
 
-     this.ctx.imageSmoothingEnabled = this.smoothing;
 
-   }
 
-   toggleLayers() {
 
-     this.showLayers = !this.showLayers;
 
-   }
 
-   addLayer() {
 
-     const newId = `layer${this.layers.length + 1}`;
 
-     this.layers.push({
 
-       id: newId,
 
-       name: `图层 ${this.layers.length + 1}`,
 
-       visible: true
 
-     });
 
-     this.currentLayer = newId;
 
-   }
 
-   deleteLayer(layerId: string) {
 
-     if (this.layers.length > 1) {
 
-       this.layers = this.layers.filter(layer => layer.id !== layerId);
 
-       if (this.currentLayer === layerId) {
 
-         this.currentLayer = this.layers[0].id;
 
-       }
 
-     }
 
-   }
 
- }
 
 
  |