clip.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <template>
  2. <div>
  3. <canvas :id="id" width="800" height="400" tabindex="0"/>
  4. </div>
  5. </template>
  6. <script lang="ts">
  7. import { Component, Vue } from "vue-property-decorator";
  8. import { v1 as uuid } from "uuid";
  9. import { SCanvasView, SColor, SPainter, SPath } from "@persagy-web/draw/lib";
  10. /**
  11. * 裁剪
  12. *
  13. * @author 郝洁 <haojie@persagy.com>
  14. */
  15. class ClipView extends SCanvasView {
  16. /** 图片的路径 */
  17. img: CanvasImageSource;
  18. /** 圆心 x 坐标*/
  19. arcX = 100;
  20. /** 圆心 y 坐标*/
  21. arcY = 100;
  22. /** 圆心移动 x 坐标*/
  23. stepX = 6;
  24. /** 圆心移动 y 坐标*/
  25. stepY = 8;
  26. /** 定时器 */
  27. timer: any;
  28. /** 图片的url */
  29. _url: string = '';
  30. set url(v: string) {
  31. if (this._url == v) {
  32. return;
  33. }
  34. this._url = v;
  35. // @ts-ignore
  36. this.img.src = v;
  37. }
  38. get url(): string {
  39. return this._url;
  40. }
  41. /** 绘制完成指令 */
  42. isLoadOver: boolean = false;
  43. /**
  44. * 构造函数
  45. * @param id 图 Id
  46. */
  47. constructor(id: string) {
  48. super(id);
  49. this.img = new Image();
  50. this.img.onload = (e) => {
  51. this.isLoadOver = true;
  52. this.update();
  53. };
  54. this.img.onerror = (e) => {
  55. this.isLoadOver = false;
  56. this.update();
  57. console.log("加载图片错误!", e);
  58. };
  59. }
  60. /**
  61. * Item 绘制操作
  62. * @param painter 绘制对象
  63. */
  64. onDraw(painter: SPainter): void {
  65. // @ts-ignore
  66. painter.engine._canvas.save();
  67. // painter.save();
  68. //清空画布
  69. painter.clearRect(0, 0, 800, 400);
  70. clearTimeout(this.timer);
  71. //绘制操作
  72. painter.pen.color = SColor.Black;
  73. painter.brush.color = SColor.Black;
  74. painter.drawRect(0, 0, 800, 400);
  75. painter.brush.color = SColor.Transparent;
  76. let path = new SPath();
  77. path.arc(this.arcX, this.arcY, 100, 0, Math.PI * 2, 1);
  78. painter.clip = path;
  79. //绘制路径
  80. painter.drawPath(path);
  81. // console.log('------->');
  82. if (this.isLoadOver) { // 绘制指令完成时
  83. //绘制图片
  84. painter.drawImage(this.img, 0, 0, 800, 400);
  85. }
  86. // painter.restore();
  87. // @ts-ignore
  88. painter.engine._canvas.restore();
  89. this.timer = setTimeout(() => {
  90. if (this.arcX + 100 >= 800) { // 左移
  91. this.stepX *= -1;
  92. }
  93. if (this.arcX - 100 < 0) { // 右移
  94. this.stepX *= -1;
  95. }
  96. if (this.arcY + 100 >= 400) { // 下移
  97. this.stepY *= -1;
  98. }
  99. if (this.arcY - 100 < 0) { // 上移
  100. this.stepY *= -1;
  101. }
  102. this.arcX += this.stepX;
  103. this.arcY += this.stepY;
  104. this.update()
  105. }, 17);
  106. }
  107. }
  108. @Component
  109. export default class SelectContainerCanvas extends Vue {
  110. /** 图 Id */
  111. id: string = uuid();
  112. /** 实例化 view */
  113. view: ClipView | undefined;
  114. /** 图片 */
  115. img = require('../../public/assets/img/2.jpg');
  116. /**
  117. * 页面挂载
  118. */
  119. mounted(): void {
  120. this.init();
  121. };
  122. /**
  123. * 初始化加载
  124. */
  125. init(): void {
  126. this.view = new ClipView(this.id);
  127. this.view.url = this.img;
  128. };
  129. /**
  130. * 页面销毁前
  131. */
  132. beforeDestroy(): void {
  133. clearTimeout(this.view!!.timer);
  134. }
  135. }
  136. </script>