mark.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <template>
  2. <view class="container" ref="canvas-container">
  3. <span>组件</span>
  4. <canvas
  5. canvas-id="myCanvas"
  6. id="myCanvas"
  7. @touchstart="touchStart"
  8. @touchmove="touchMove"
  9. @touchend="touchEnd"
  10. :style="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"
  11. ></canvas>
  12. </view>
  13. </template>
  14. <script>
  15. export default {
  16. data() {
  17. return {
  18. canvasWidth: 300,
  19. canvasHeight: 279,
  20. ctx: null,
  21. bgImage: null,
  22. imageLoaded: false,
  23. rectX: 50,
  24. rectY: 50,
  25. rectWidth: 100,
  26. rectHeight: 80,
  27. lastDistance: 0, // 双指间距离
  28. scale: 1, // 缩放比例
  29. lastTouchCenter: { x: 0, y: 0 }, // 上次双指中心点
  30. translateX: 0, // X轴平移
  31. translateY: 0, // Y轴平移
  32. isDragging: false, // 是否正在拖动
  33. startDragX: 0, // 拖动开始的X坐标
  34. startDragY: 0 // 拖动开始的Y坐标
  35. }
  36. },
  37. mounted() {
  38. uni.getSystemInfo({
  39. success: (res) => {
  40. this.canvasWidth = res.windowWidth
  41. // this.canvasHeight = res.windowHeight * 0.5
  42. console.log(this.canvasWidth,this.canvasHeight)
  43. // 创建canvas上下文
  44. this.ctx = uni.createCanvasContext('myCanvas', this)
  45. // 加载背景图片
  46. this.loadImage()
  47. }
  48. })
  49. },
  50. onReady() {
  51. // 获取系统信息设置canvas尺寸
  52. },
  53. methods: {
  54. loadImage() {
  55. // 加载网络图片示例
  56. uni.getImageInfo({
  57. src: 'https://bigdata-image.oss-cn-hangzhou.aliyuncs.com/Basics/cbd/666000000000001/2025/7/11/001.jpg',
  58. success: (res) => {
  59. console.log(res)
  60. this.bgImage = res
  61. this.imageLoaded = true
  62. this.drawCanvas()
  63. },
  64. fail: (err) => {
  65. console.error('图片加载失败:', err)
  66. }
  67. })
  68. // 或者使用本地临时文件
  69. // uni.downloadFile({
  70. // url: 'https://example.com/background.jpg',
  71. // success: (res) => {
  72. // this.bgImage = res.tempFilePath
  73. // this.imageLoaded = true
  74. // this.drawCanvas()
  75. // }
  76. // })
  77. },
  78. drawCanvas() {
  79. if (!this.imageLoaded) return
  80. const ctx = this.ctx
  81. ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
  82. // 绘制背景图片(保持纵横比,适应canvas)
  83. // const imgRatio = this.bgImage.width / this.bgImage.height
  84. // const canvasRatio = this.canvasWidth / this.canvasHeight
  85. // let drawWidth, drawHeight, offsetX = 0, offsetY = 0
  86. // if (imgRatio > canvasRatio) {
  87. // drawHeight = this.canvasHeight
  88. // drawWidth = this.bgImage.width * (drawHeight / this.bgImage.height)
  89. // offsetX = (this.canvasWidth - drawWidth) / 2
  90. // } else {
  91. // drawWidth = this.canvasWidth
  92. // drawHeight = this.bgImage.height * (drawWidth / this.bgImage.width)
  93. // offsetY = (this.canvasHeight - drawHeight) / 2
  94. // }
  95. ctx.drawImage(this.bgImage.path, 0, 0, this.bgImage.width, this.bgImage.height)
  96. let scaleX = this.canvasWidth /this.bgImage.width
  97. let scaleY = this.canvasHeight /this.bgImage.height
  98. console.log(scaleX,scaleY,'----',this.translateX, this.translateY)
  99. // 应用变换(缩放和平移)
  100. ctx.save()
  101. ctx.translate(this.translateX, this.translateY)
  102. ctx.scale(2, 2)
  103. // 绘制矩形
  104. // ctx.setStrokeStyle('#FF0000')
  105. // ctx.setLineWidth(2)
  106. // ctx.strokeRect(this.rectX, this.rectY, this.rectWidth, this.rectHeight)
  107. ctx.restore()
  108. ctx.draw()
  109. },
  110. // 处理触摸开始事件
  111. touchStart(e) {
  112. const touches = e.touches
  113. if (touches.length === 1) {
  114. // 单指拖动
  115. this.isDragging = true
  116. this.startDragX = this.translateX
  117. this.startDragY = this.translateY
  118. this.rectX += e.touches[0].x - this.lastTouchCenter.x
  119. this.rectY += e.touches[0].y - this.lastTouchCenter.y
  120. } else if (touches.length === 2) {
  121. // 双指缩放
  122. this.isDragging = false
  123. const dx = touches[0].x - touches[1].x
  124. const dy = touches[0].y - touches[1].y
  125. this.lastDistance = Math.sqrt(dx * dx + dy * dy)
  126. this.lastTouchCenter = {
  127. x: (touches[0].x + touches[1].x) / 2,
  128. y: (touches[0].y + touches[1].y) / 2
  129. }
  130. }
  131. },
  132. // 处理触摸移动事件
  133. touchMove(e) {
  134. const touches = e.touches
  135. if (this.isDragging && touches.length === 1) {
  136. // 单指拖动矩形
  137. this.rectX += e.touches[0].x - this.lastTouchCenter.x
  138. this.rectY += e.touches[0].y - this.lastTouchCenter.y
  139. this.lastTouchCenter = {
  140. x: e.touches[0].x,
  141. y: e.touches[0].y
  142. }
  143. } else if (touches.length === 2) {
  144. // 双指缩放
  145. const dx = touches[0].x - touches[1].x
  146. const dy = touches[0].y - touches[1].y
  147. const distance = Math.sqrt(dx * dx + dy * dy)
  148. // 计算新的缩放比例
  149. let newScale = this.scale * (distance / this.lastDistance)
  150. // 限制最小和最大缩放比例
  151. newScale = Math.max(0.5, Math.min(3, newScale))
  152. // 计算缩放中心点相对于当前平移后的坐标
  153. const centerX = this.lastTouchCenter.x
  154. const centerY = this.lastTouchCenter.y
  155. // 计算相对于当前变换的本地坐标
  156. // 这部分比较复杂,简化处理
  157. this.rectX = centerX - (centerX - this.rectX) * (newScale / this.scale)
  158. this.rectY = centerY - (centerY - this.rectY) * (newScale / this.scale)
  159. this.rectWidth *= newScale / this.scale
  160. this.rectHeight *= newScale / this.scale
  161. // 更新缩放和平移
  162. this.scale = newScale
  163. this.translateX = this.startDragX + (centerX - this.lastTouchCenter.x) * (this.scale - 1)
  164. this.translateY = this.startDragY + (centerY - this.lastTouchCenter.y) * (this.scale - 1)
  165. this.lastDistance = distance
  166. this.lastTouchCenter = {
  167. x: centerX,
  168. y: centerY
  169. }
  170. }
  171. this.drawCanvas()
  172. },
  173. // 处理触摸结束事件
  174. touchEnd(e) {
  175. this.isDragging = false
  176. }
  177. }
  178. }
  179. </script>
  180. <style>
  181. .container {
  182. width: 100%;
  183. height: 100%;
  184. display: flex;
  185. flex-direction: column;
  186. align-items: center;
  187. justify-content: center;
  188. }
  189. </style>