Konva - 缩放和旋转后更改偏移位置

问题描述 投票:0回答:1

我正在尝试使用滑块实现旋转和缩放功能。我需要一个图像始终从视口的中心旋转。主要思想是在拖动事件后改变舞台的位置和偏移。这是我尝试过的

const width = window.innerWidth
const height = window.innerHeight

// scale is temp
let stage = new Konva.Stage({
  container: 'canvas',
  width,
  height,
  draggable: true,
  offset: {
    x: width / 2,
    y: height / 2
  },
  x: width / 2,
  y: height / 2
})

let mapLayer = new Konva.Layer()
let imageObj = new Image()

imageObj.onload = function () {
  let map = new Konva.Image({
    image: imageObj,
    prevX: 0,
    prevY: 0
  })

  layer.add(map)
  stage.add(mapLayer)

  stage.on('dragstart', () => {
    map.prevX = map.getAbsolutePosition().x
    map.prevY = map.getAbsolutePosition().y
  })

  stage.on('dragend', () => {
    let curX = map.getAbsolutePosition().x
    let curY = map.getAbsolutePosition().y
    let deltaX = Math.abs(map.prevX - curX)
    let deltaY = Math.abs(map.prevY - curY)

    if (curX > map.prevX) {
      stage.offsetX(stage.offsetX() - deltaX)
      stage.x(stage.x() - deltaX)
    } else {
      stage.offsetX(stage.offsetX() + deltaX)
      stage.x(stage.x() + deltaX)
    }

    if (curY > map.prevY) {
      stage.offsetY(stage.offsetY() - deltaY)
      stage.y(stage.y() - deltaY)
    } else {
      stage.offsetY(stage.offsetY() + deltaY)
      stage.y(stage.y() + deltaY)
    }

    stage.draw()
  })
}

(如果你想要一个完整的源代码,clone it from here并从终端运行yarn run dev,该应用程序存在于localhost:3000

当图像处于正常位置(未进行缩放和旋转)时,它工作正常但是在任何类型的旋转或缩放之后,拖动舞台将导致舞台以奇怪的方式重新定位(尽管偏移仍然是正确的)。如何正确设置位置和偏移?

javascript konvajs
1个回答
0
投票

以下解决您的初始问题。请注意,我将一个圆圈和一个工具提示也放在一个图层上,以便能够将它们作为单个图层拖动。此外,它应该在map之后加入以进行约束性工作。

import Konva from 'konva'
import map from './../resources/unpar.svg'

const width = window.innerWidth
const height = window.innerHeight

// scale is temp
let stage = new Konva.Stage({
  container: 'canvas',
  width,
  height,
  offset: {
    x: width / 2,
    y: height / 2
  },
  x: width / 2,
  y: height / 2
})

let layer = new Konva.Layer({draggable: true})

let testCircle = new Konva.Circle({
  x: 633,
  y: 590,
  radius: 10,
  fill: 'white',
  stroke: 'black'
})

testCircle.on('mousemove', function () {
  tooltip.position({
    x: testCircle.x() - 90,
    y: testCircle.y() - 50
  })
  tooltip.text('Pintu Depan Gedung 10')
  tooltip.show()
  layer.batchDraw()
})

testCircle.on('mouseout', function () {
  tooltip.hide()
  layer.draw()
})

var tooltip = new Konva.Text({
  text: '',
  fontFamily: 'Calibri',
  fontSize: 18,
  padding: 5,
  textFill: 'white',
  fill: 'black',
  alpha: 0.75,
  visible: false
})

let imageObj = new Image()

imageObj.onload = function () {
  const map = new Konva.Image({
    image: imageObj,
  })

  layer.add(map)
  layer.add(testCircle)
  layer.add(tooltip)
  stage.add(layer)
}

imageObj.src = map

export default stage
© www.soinside.com 2019 - 2024. All rights reserved.