理解节点的 zIndex
节点的 zIndex 是什么?
可以通过以下方式获取或设置节点的 zIndex:
// get
const zIndex = shape.zIndex();
// set
shape.zIndex(1);
zIndex 只是节点在其父节点 children 数组中的索引。不要混淆 Konva 中的 zIndex 和 CSS 中的 z-index。
const group = new Konva.Group();
const circle = new Konva.Circle({});
group.add(circle);
// it will log 0
console.log(circle.zIndex());
// the next line will not work because the group has only one child
circle.zIndex(1);
// still logs 0
console.log(circle.zIndex());
// for any node this equation will be true:
console.log(circle.zIndex() === circle.getParent().children.indexOf(circle));
不能像在 CSS 中那样使用 zIndex 设置节点的绝对位置。
Konva 严格按照节点在节点树中的定义顺序绘制节点。
操作说明:尝试使用按钮更改图形的 zIndex。观察图形顺序如何变化。
- Vanilla
- React
- Vue
import Konva from 'konva';
const width = window.innerWidth;
const height = window.innerHeight;
const stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});
const layer = new Konva.Layer();
// first group
const group1 = new Konva.Group();
layer.add(group1);
const blackRect = new Konva.Rect({
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'black',
});
group1.add(blackRect);
const redCircle = new Konva.Circle({
x: 80,
y: 80,
radius: 40,
fill: 'red',
});
group1.add(redCircle);
// second group
const group2 = new Konva.Group();
layer.add(group2);
const greenRect = new Konva.Rect({
x: 50,
y: 50,
width: 100,
height: 100,
fill: 'green',
});
group2.add(greenRect);
stage.add(layer);
// create buttons
const btn1 = document.createElement('button');
btn1.textContent = 'Move red circle to group2';
btn1.addEventListener('click', () => {
redCircle.moveTo(group2);
});
const btn2 = document.createElement('button');
btn2.textContent = 'Move red circle to group1';
btn2.addEventListener('click', () => {
redCircle.moveTo(group1);
});
document.body.appendChild(btn1);
document.body.appendChild(btn2);
import { Stage, Layer, Group, Rect, Circle } from 'react-konva';
import { useState } from 'react';
const App = () => {
const [redCircleGroup, setRedCircleGroup] = useState('group1');
return (
<>
<button onClick={() => setRedCircleGroup('group2')}>
Move red circle to group2
</button>
<button onClick={() => setRedCircleGroup('group1')}>
Move red circle to group1
</button>
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Group>
<Rect
x={10}
y={10}
width={100}
height={100}
fill="black"
/>
{redCircleGroup === 'group1' && (
<Circle
x={80}
y={80}
radius={40}
fill="red"
/>
)}
</Group>
<Group>
<Rect
x={50}
y={50}
width={100}
height={100}
fill="green"
/>
{redCircleGroup === 'group2' && (
<Circle
x={80}
y={80}
radius={40}
fill="red"
/>
)}
</Group>
</Layer>
</Stage>
</>
);
};
export default App;
<template>
<div>
<button @click="moveToGroup2">Move red circle to group2</button>
<button @click="moveToGroup1">Move red circle to group1</button>
<v-stage :config="stageSize">
<v-layer>
<v-group>
<v-rect :config="blackRectConfig" />
<v-circle v-if="redCircleGroup === 'group1'" :config="redCircleConfig" />
</v-group>
<v-group>
<v-rect :config="greenRectConfig" />
<v-circle v-if="redCircleGroup === 'group2'" :config="redCircleConfig" />
</v-group>
</v-layer>
</v-stage>
</div>
</template>
<script setup>
import { ref } from 'vue';
const stageSize = {
width: window.innerWidth,
height: window.innerHeight
};
const redCircleGroup = ref('group1');
const blackRectConfig = {
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'black'
};
const greenRectConfig = {
x: 50,
y: 50,
width: 100,
height: 100,
fill: 'green'
};
const redCircleConfig = {
x: 80,
y: 80,
radius: 40,
fill: 'red'
};
const moveToGroup2 = () => {
redCircleGroup.value = 'group2';
};
const moveToGroup1 = () => {
redCircleGroup.value = 'group1';
};
</script>