| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- <template>
- <view class="container" ref="canvas-container">
- <span>组件</span>
- <canvas
- canvas-id="myCanvas"
- id="myCanvas"
- @touchstart="touchStart"
- @touchmove="touchMove"
- @touchend="touchEnd"
- :style="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"
- ></canvas>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- canvasWidth: 300,
- canvasHeight: 279,
- ctx: null,
- bgImage: null,
- imageLoaded: false,
- rectX: 50,
- rectY: 50,
- rectWidth: 100,
- rectHeight: 80,
- lastDistance: 0, // 双指间距离
- scale: 1, // 缩放比例
- lastTouchCenter: { x: 0, y: 0 }, // 上次双指中心点
- translateX: 0, // X轴平移
- translateY: 0, // Y轴平移
- isDragging: false, // 是否正在拖动
- startDragX: 0, // 拖动开始的X坐标
- startDragY: 0 // 拖动开始的Y坐标
- }
- },
- mounted() {
- uni.getSystemInfo({
- success: (res) => {
-
- this.canvasWidth = res.windowWidth
- // this.canvasHeight = res.windowHeight * 0.5
- console.log(this.canvasWidth,this.canvasHeight)
- // 创建canvas上下文
- this.ctx = uni.createCanvasContext('myCanvas', this)
-
- // 加载背景图片
- this.loadImage()
- }
- })
- },
- onReady() {
-
- // 获取系统信息设置canvas尺寸
-
- },
- methods: {
- loadImage() {
- // 加载网络图片示例
- uni.getImageInfo({
- src: 'https://bigdata-image.oss-cn-hangzhou.aliyuncs.com/Basics/cbd/666000000000001/2025/7/11/001.jpg',
- success: (res) => {
- console.log(res)
- this.bgImage = res
- this.imageLoaded = true
- this.drawCanvas()
- },
- fail: (err) => {
- console.error('图片加载失败:', err)
- }
- })
-
- // 或者使用本地临时文件
- // uni.downloadFile({
- // url: 'https://example.com/background.jpg',
- // success: (res) => {
- // this.bgImage = res.tempFilePath
- // this.imageLoaded = true
- // this.drawCanvas()
- // }
- // })
- },
-
- drawCanvas() {
- if (!this.imageLoaded) return
-
- const ctx = this.ctx
- ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
-
- // 绘制背景图片(保持纵横比,适应canvas)
- // const imgRatio = this.bgImage.width / this.bgImage.height
- // const canvasRatio = this.canvasWidth / this.canvasHeight
- // let drawWidth, drawHeight, offsetX = 0, offsetY = 0
-
- // if (imgRatio > canvasRatio) {
- // drawHeight = this.canvasHeight
- // drawWidth = this.bgImage.width * (drawHeight / this.bgImage.height)
- // offsetX = (this.canvasWidth - drawWidth) / 2
- // } else {
- // drawWidth = this.canvasWidth
- // drawHeight = this.bgImage.height * (drawWidth / this.bgImage.width)
- // offsetY = (this.canvasHeight - drawHeight) / 2
- // }
-
- ctx.drawImage(this.bgImage.path, 0, 0, this.bgImage.width, this.bgImage.height)
- let scaleX = this.canvasWidth /this.bgImage.width
- let scaleY = this.canvasHeight /this.bgImage.height
- console.log(scaleX,scaleY,'----',this.translateX, this.translateY)
- // 应用变换(缩放和平移)
- ctx.save()
- ctx.translate(this.translateX, this.translateY)
- ctx.scale(2, 2)
-
- // 绘制矩形
- // ctx.setStrokeStyle('#FF0000')
- // ctx.setLineWidth(2)
- // ctx.strokeRect(this.rectX, this.rectY, this.rectWidth, this.rectHeight)
-
- ctx.restore()
- ctx.draw()
- },
-
- // 处理触摸开始事件
- touchStart(e) {
- const touches = e.touches
-
- if (touches.length === 1) {
- // 单指拖动
- this.isDragging = true
- this.startDragX = this.translateX
- this.startDragY = this.translateY
- this.rectX += e.touches[0].x - this.lastTouchCenter.x
- this.rectY += e.touches[0].y - this.lastTouchCenter.y
- } else if (touches.length === 2) {
- // 双指缩放
- this.isDragging = false
- const dx = touches[0].x - touches[1].x
- const dy = touches[0].y - touches[1].y
- this.lastDistance = Math.sqrt(dx * dx + dy * dy)
- this.lastTouchCenter = {
- x: (touches[0].x + touches[1].x) / 2,
- y: (touches[0].y + touches[1].y) / 2
- }
- }
- },
-
- // 处理触摸移动事件
- touchMove(e) {
- const touches = e.touches
-
- if (this.isDragging && touches.length === 1) {
- // 单指拖动矩形
- this.rectX += e.touches[0].x - this.lastTouchCenter.x
- this.rectY += e.touches[0].y - this.lastTouchCenter.y
- this.lastTouchCenter = {
- x: e.touches[0].x,
- y: e.touches[0].y
- }
- } else if (touches.length === 2) {
- // 双指缩放
- const dx = touches[0].x - touches[1].x
- const dy = touches[0].y - touches[1].y
- const distance = Math.sqrt(dx * dx + dy * dy)
-
- // 计算新的缩放比例
- let newScale = this.scale * (distance / this.lastDistance)
- // 限制最小和最大缩放比例
- newScale = Math.max(0.5, Math.min(3, newScale))
-
- // 计算缩放中心点相对于当前平移后的坐标
- const centerX = this.lastTouchCenter.x
- const centerY = this.lastTouchCenter.y
-
- // 计算相对于当前变换的本地坐标
- // 这部分比较复杂,简化处理
- this.rectX = centerX - (centerX - this.rectX) * (newScale / this.scale)
- this.rectY = centerY - (centerY - this.rectY) * (newScale / this.scale)
- this.rectWidth *= newScale / this.scale
- this.rectHeight *= newScale / this.scale
-
- // 更新缩放和平移
- this.scale = newScale
- this.translateX = this.startDragX + (centerX - this.lastTouchCenter.x) * (this.scale - 1)
- this.translateY = this.startDragY + (centerY - this.lastTouchCenter.y) * (this.scale - 1)
-
- this.lastDistance = distance
- this.lastTouchCenter = {
- x: centerX,
- y: centerY
- }
- }
-
- this.drawCanvas()
- },
-
- // 处理触摸结束事件
- touchEnd(e) {
- this.isDragging = false
- }
- }
- }
- </script>
- <style>
- .container {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- </style>
|