import Line from './line'; import Area from './area'; import Arc from './arc'; import Circle from './circle'; import Rect from './rect'; import PolyLine from './polyLine'; import Sector from './sector'; import Text from './text'; import Image from './image'; import { ShapeOptions, LineOptions, AreaOptions, ArcOptions, CircleOptions, RectOptions, PolyLineOptions, SectorOptions, TextOptions, ImageOptions, } from '../models/painter'; import { Coordinate } from '../coordinate/coordinate'; const shapeNameMap = { Line, Area, Arc, Circle, Rect, PolyLine, Sector, Text, Image, }; export default class Painter { private ctx: CanvasRenderingContext2D; private coord: Coordinate; constructor(ctx: CanvasRenderingContext2D, coord: Coordinate) { this.ctx = ctx; this.coord = coord; } /** *【点坐标转换】 数学坐标系 => web坐标 * @param shapeName * @param rawOptions */ pointMappingHanlder(shapeName, rawOptions: ShapeOptions) { let options = null; switch (shapeName) { case 'Line': { const { x1, y1, x2, y2 } = rawOptions as LineOptions; const startPoint = this.coord.pointMapping({ x: x1, y: y1 }); const endPoint = this.coord.pointMapping({ x: x2, y: y2 }); options = { ...rawOptions, x1: startPoint.x, y1: startPoint.y, x2: endPoint.x, y2: endPoint.y, }; break; } case 'Area': { const { points: rawPoints } = rawOptions as AreaOptions; const points = rawPoints.map(item => this.coord.pointMapping(item)); options = { ...rawOptions, points, }; break; } case 'Arc': { const { x: rawX, y: rawY } = rawOptions as ArcOptions; const { x, y } = this.coord.pointMapping({ x: rawX, y: rawY }); options = { ...rawOptions, x, y, }; break; } case 'Circle': { const { x: rawX, y: rawY } = rawOptions as CircleOptions; const { x, y } = this.coord.pointMapping({ x: rawX, y: rawY }); options = { ...rawOptions, x, y, }; break; } case 'Rect': { const { x: rawX, y: rawY } = rawOptions as RectOptions; const { x, y } = this.coord.pointMapping({ x: rawX, y: rawY }); options = { ...rawOptions, x, y, }; break; } case 'PolyLine': { const { points: rawPoints } = rawOptions as PolyLineOptions; const points = rawPoints.map(item => this.coord.pointMapping(item)); options = { ...rawOptions, rawPoints, // 数学坐标系坐标 points, // web坐标系坐标 }; break; } case 'Sector': { const { x: rawX, y: rawY } = rawOptions as SectorOptions; const { x, y } = this.coord.pointMapping({ x: rawX, y: rawY }); options = { ...rawOptions, x, y, }; break; } case 'Text': { const { x: rawX, y: rawY } = rawOptions as TextOptions; const { x, y } = this.coord.pointMapping({ x: rawX, y: rawY }); options = { ...rawOptions, x, y, }; break; } case 'Image': { const { x: rawX, y: rawY } = rawOptions as ImageOptions; const { x, y } = this.coord.pointMapping({ x: rawX, y: rawY }); options = { ...rawOptions, x, y, }; break; } default: break; } return options || rawOptions; } /** * 绘制图形 * @param shapeName 图形名称 * @param rawOptions 图形参数 * @param enableCoordTransform 是否启用坐标转换 */ draw( shapeName: string, rawOptions: ShapeOptions, enableCoordTransform = true, ) { const options = enableCoordTransform ? this.pointMappingHanlder(shapeName, rawOptions) : rawOptions; const shape = new shapeNameMap[shapeName](this.ctx, options); shape.draw(); } }