| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // import { throttle } from "@pureadmin/utils";
- import { emitter } from "@/utils/mitt";
- export class CanvasRenderer {
- private canvas: HTMLCanvasElement;
- private ctx: CanvasRenderingContext2D;
- private images: {
- img: HTMLImageElement;
- x: number;
- y: number;
- width: number;
- height: number;
- }[];
- private container: HTMLElement;
- private positionX: number;
- private isDragging: boolean;
- private startX: number;
- constructor(containerId: string) {
- this.canvas = document.createElement("canvas");
- this.ctx = this.canvas.getContext("2d")!;
- this.images = [];
- this.positionX = 0;
- this.isDragging = false;
- this.startX = 0;
- this.container = document.getElementById(containerId);
- if (this.container) {
- this.container.appendChild(this.canvas);
- this.canvas.width = this.container.clientWidth;
- this.canvas.height = this.container.clientHeight;
- }
- }
- public addImage(
- url: string,
- x: number,
- y: number,
- width: number,
- height: number
- ) {
- const img = new Image();
- img.src = url;
- this.images.push({
- img,
- x,
- y,
- width,
- height
- });
- this.render();
- }
- public render() {
- this.clearRect();
- this.images.forEach(imgProps => {
- const x = imgProps.x + this.positionX;
- this.ctx.drawImage(
- imgProps.img,
- x,
- imgProps.y,
- imgProps.width,
- imgProps.height
- );
- });
- }
- public clearImages() {
- this.images = [];
- }
- public clearRect() {
- this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
- }
- public drawTick(event) {
- this.render();
- // 当前勾选图片的索引
- const index =
- Math.ceil(
- (Math.abs(this.positionX) + event.offsetX) / this.images[0].width
- ) - 1;
- const x = event.offsetX;
- const y = event.offsetY;
- // 绘制样式
- this.ctx.strokeStyle = "red";
- this.ctx.lineWidth = 4;
- this.ctx.lineCap = "round";
- // 绘制对勾
- this.ctx.beginPath();
- this.ctx.moveTo(x - 10, y);
- this.ctx.lineTo(x, y + 10);
- this.ctx.lineTo(x + 15, y - 10);
- this.ctx.stroke();
- emitter.emit("imageInfo", this.images[index]);
- }
- public addListener() {
- if (!this.canvas) return;
- this.canvas.addEventListener("click", this.handleClick);
- this.canvas.addEventListener("mousedown", this.handleMouseDown);
- this.canvas.addEventListener("mousemove", this.handleMouseMove);
- this.canvas.addEventListener("mouseup", this.handleMouseUp);
- this.canvas.addEventListener("touchstart", this.handleTouchStart);
- this.canvas.addEventListener("touchmove", this.handleTouchMove);
- this.canvas.addEventListener("touchend", this.handleTouchEnd);
- // window.addEventListener("resize", throttle(this.handleWindowResize, 200));
- }
- private handleClick = (event: MouseEvent) => {
- this.drawTick(event);
- };
- private handleMouseDown = (event: MouseEvent) => {
- this.startDrag(event.clientX);
- };
- private handleMouseMove = (event: MouseEvent) => {
- this.drag(event.clientX);
- };
- private handleMouseUp = () => {
- this.endDrag();
- };
- private handleTouchStart = (event: TouchEvent) => {
- if (event.touches.length === 1) {
- event.preventDefault();
- this.startDrag(event.touches[0].clientX);
- }
- };
- private handleTouchMove = (event: TouchEvent) => {
- if (event.touches.length === 1) {
- event.preventDefault();
- this.drag(event.touches[0].clientX);
- }
- };
- private handleTouchEnd = () => {
- this.endDrag();
- };
- private startDrag(clientX: number) {
- this.canvas.style.cursor = "grabbing";
- this.canvas.style.userSelect = "none";
- this.startX = clientX;
- this.isDragging = true;
- }
- private drag(clientX: number) {
- if (!this.isDragging) return;
- const deltaX = clientX - this.startX;
- const maxPositionX =
- this.images.length * this.images[0].width - this.container.clientWidth;
- this.positionX = Math.max(
- Math.min(this.positionX + deltaX, 0),
- -maxPositionX
- );
- this.startX = clientX;
- this.render();
- }
- private endDrag() {
- this.canvas.style.cursor = "grab";
- this.canvas.style.userSelect = "auto";
- this.isDragging = false;
- }
- // private handleWindowResize = () => {
- // this.canvas.width = this.container.clientWidth;
- // this.canvas.height = this.container.clientHeight;
- // this.render();
- // };
- }
|