zoukankan      html  css  js  c++  java
  • canvas画以中心点旋转的矩形

    <template>
      <canvas
        id="cvs"
        width="600"
        height="600"
        style="background-color: rgba(0, 0, 0, 0.1); outline: none"
        tabindex="0"
      ></canvas>
    </template>
    
    <script lang="ts">
    import { Options, Vue } from "vue-class-component";
    
    @Options({
      components: {},
    })
    export default class Home extends Vue {
      private rectangle: Array<Array<number>> = [];
    
      mounted(): void {
        let cvs = document.getElementById("cvs") as HTMLCanvasElement;
        let ctx = cvs.getContext("2d") as CanvasRenderingContext2D;
    
        cvs.onmousedown = (ev) => {
          this.rectangle = [];
          let onkeyDownMousePosition: Array<number> = [];
          let onkeyDownRectPosition: Array<Array<number>> = [];
          let onkeyDownStatus = false;
    
          cvs.onmousemove = (event) => {
            if (onkeyDownStatus) {
              // 旋转
              let angle = this.point3_angle(
                [ev.offsetX, ev.offsetY],
                onkeyDownMousePosition,
                [event.offsetX, event.offsetY]
              );
    
              this.rectangle = [
                this.point2angle_point(
                  [ev.offsetX, ev.offsetY],
                  onkeyDownRectPosition[0],
                  angle
                ),
                this.point2angle_point(
                  [ev.offsetX, ev.offsetY],
                  onkeyDownRectPosition[1],
                  angle
                ),
                this.point2angle_point(
                  [ev.offsetX, ev.offsetY],
                  onkeyDownRectPosition[2],
                  angle
                ),
                this.point2angle_point(
                  [ev.offsetX, ev.offsetY],
                  onkeyDownRectPosition[3],
                  angle
                ),
              ];
            } else {
              // 缩放
              const x = event.offsetX - ev.offsetX;
              const y = event.offsetY - ev.offsetY;
              this.rectangle = [
                [ev.offsetX + x, ev.offsetY + y],
                [ev.offsetX - x, ev.offsetY + y],
                [ev.offsetX - x, ev.offsetY - y],
                [ev.offsetX + x, ev.offsetY - y],
              ];
              onkeyDownMousePosition = [event.offsetX, event.offsetY];
              onkeyDownRectPosition = [...this.rectangle];
            }
            this.drawerCanvas(ctx, [ev.offsetX, ev.offsetY]);
          };
    
          cvs.onkeydown = (event) => {
            onkeyDownStatus = event.shiftKey;
          };
    
          cvs.onkeyup = (event) => {
            onkeyDownStatus = event.shiftKey;
          };
        };
    
        cvs.onmouseup = () => {
          cvs.onkeydown = null;
          cvs.onkeyup = null;
          cvs.onmousemove = null;
        };
      }
    
      // 根据中心点、起点、终点算弧度
      private point3_angle(
        center: Array<number>,
        start: Array<number>,
        end: Array<number>
      ): number {
        let endAngle = Math.atan2(end[1] - center[1], end[0] - center[0]);
        let startAngle = Math.atan2(start[1] - center[1], start[0] - center[0]);
        return endAngle - startAngle;
      }
    
      // 根据中心点、起点、旋转弧度算终点
      private point2angle_point(
        center: Array<number>,
        start: Array<number>,
        angle: number
      ): Array<number> {
        const r = Math.sqrt(
          Math.pow(start[0] - center[0], 2) + Math.pow(start[1] - center[1], 2)
        );
        const endAngle =
          this.point3_angle(center, [center[0] + 1, center[1]], start) + angle;
    
        let cosVal = Math.cos(endAngle);
        let sinVal = Math.sin(endAngle);
        if (cosVal > 1 || cosVal < -1) {
          cosVal = 0;
        }
        if (sinVal > 1 || sinVal < -1) {
          sinVal = 0;
        }
        return [cosVal * r + center[0], sinVal * r + center[1]];
      }
    
      private drawerCanvas(ctx: CanvasRenderingContext2D, center: Array<number>) {
        const r = 3;
        ctx.clearRect(0, 0, 600, 600);
        ctx.lineWidth = 1;
        ctx.strokeStyle = "rgb(0,255,0)";
    
        ctx.setLineDash([3, 3]);
        ctx.beginPath();
        this.rectangle.forEach((li) => {
          ctx.lineTo(li[0], li[1]);
        });
        ctx.closePath();
        ctx.lineTo(center[0], center[1]);
        ctx.stroke();
        ctx.setLineDash([]);
        this.rectangle.forEach((li) => {
          ctx.clearRect(li[0] - r, li[1] - r, 2 * r, 2 * r);
          ctx.beginPath();
          ctx.arc(li[0], li[1], r, 0, 2 * Math.PI, true);
          ctx.stroke();
        });
      }
    }
    </script>
    
  • 相关阅读:
    [转]Worksheet.Change Event (Excel)
    [转]EXCEL如何使用动态公式
    [转]用NPOI操作EXCEL--数据有效性
    [转]How to insert a row between two rows in an existing excel with HSSF (Apache POI)
    [转]Excel
    [转]asp.net解决高并发的方案.
    [转]ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调
    Programming ActionScript 3.0 for Flash
    页游 《大皇帝》
    [转]Flash ActionScript2.0面向对象游戏开发-推箱子
  • 原文地址:https://www.cnblogs.com/linding/p/15405807.html
Copyright © 2011-2022 走看看