如何找到相对鼠标位置?
在某些情况下,您可能需要找到相对于某个节点的点的位置。为此,我们可以使用数学的 Konva.Transform
方法。
在本示例中,我们有深层嵌套的变换节点:移动的舞台、缩放的图层、旋转的组。
现在我们想在点击时向组中添加圆圈。但是,如何找到这些圆圈的位置呢?
我们不能直接使用 stage.getPointerPosition()
,因为该方法返回的是相对于舞台左上角的位置。
这个想法很简单。我们只需要使用反转的绝对变换。
- Vanilla
- React
- Vue
import Konva from 'konva'; var width = window.innerWidth; var height = window.innerHeight; var stage = new Konva.Stage({ container: 'container', width: width, height: height, x: 20, y: 50, }); var layer = new Konva.Layer({ scaleX: 1.2, scaleY: 0.8, rotation: 5, }); stage.add(layer); var group = new Konva.Group({ x: 30, rotation: 10, scaleX: 1.5, }); layer.add(group); var text = new Konva.Text({ text: '点击画布以绘制圆圈', fontSize: 20, }); group.add(text); stage.on('click', function () { var pos = group.getRelativePointerPosition(); var shape = new Konva.Circle({ x: pos.x, y: pos.y, fill: 'red', radius: 20, }); group.add(shape); });
import { useState } from 'react'; import { Stage, Layer, Group, Text, Circle } from 'react-konva'; const App = () => { const [circles, setCircles] = useState([]); const handleStageClick = (e) => { // 从konva树中获取组的引用 const group = e.target.getStage().findOne('Group'); if (!group) return; // 获取相对于组的位置 const pos = group.getRelativePointerPosition(); // 添加新圆圈 setCircles([ ...circles, { x: pos.x, y: pos.y, radius: 20, fill: 'red', id: Date.now().toString() } ]); }; return ( <Stage width={window.innerWidth} height={window.innerHeight} x={20} y={50} onClick={handleStageClick} > <Layer scaleX={1.2} scaleY={0.8} rotation={5} > <Group x={30} rotation={10} scaleX={1.5} > <Text text="点击画布以绘制圆圈" fontSize={20} /> {circles.map((circle) => ( <Circle key={circle.id} x={circle.x} y={circle.y} radius={circle.radius} fill={circle.fill} /> ))} </Group> </Layer> </Stage> ); }; export default App;
<template> <v-stage :config="stageConfig" @click="handleStageClick" > <v-layer :config="layerConfig"> <v-group :config="groupConfig"> <v-text :config="textConfig" /> <v-circle v-for="circle in circles" :key="circle.id" :config="circle" /> </v-group> </v-layer> </v-stage> </template> <script setup> import { ref } from 'vue'; const stageConfig = { width: window.innerWidth, height: window.innerHeight, x: 20, y: 50 }; const layerConfig = { scaleX: 1.2, scaleY: 0.8, rotation: 5 }; const groupConfig = { x: 30, rotation: 10, scaleX: 1.5 }; const textConfig = { text: '点击画布以绘制圆圈', fontSize: 20 }; const circles = ref([]); const handleStageClick = (e) => { // 从konva树中获取组的引用 const group = e.target.getStage().findOne('Group'); if (!group) return; // 获取相对于组的位置 const pos = group.getRelativePointerPosition(); // 添加新圆圈 circles.value.push({ x: pos.x, y: pos.y, radius: 20, fill: 'red', id: Date.now().toString() }); }; </script>