拖放多个带边框突出显示的图像
此示例展示如何为图像实现突出显示效果。将鼠标悬停在图像上时,边框会消失。将鼠标移开后,边框会再次出现。
**操作说明:**将鼠标悬停在图像上以隐藏边框,并在舞台上拖动图像
- Vanilla
- React
- Vue
import Konva from 'konva';
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
});
const layer = new Konva.Layer();
stage.add(layer);
// Create Darth Vader image
const darthVaderImg = new Konva.Image({
x: 20,
y: 20,
width: 200,
height: 137,
stroke: 'red',
strokeWidth: 10,
draggable: true,
});
layer.add(darthVaderImg);
// Create Yoda image
const yodaImg = new Konva.Image({
x: 240,
y: 20,
width: 93,
height: 104,
draggable: true,
stroke: 'red',
strokeWidth: 10,
});
layer.add(yodaImg);
// Load Darth Vader image
const imageObj1 = new Image();
imageObj1.onload = function () {
darthVaderImg.image(imageObj1);
};
imageObj1.src = 'https://konvajs.org/assets/darth-vader.jpg';
// Load Yoda image
const imageObj2 = new Image();
imageObj2.onload = function () {
yodaImg.image(imageObj2);
};
imageObj2.src = 'https://konvajs.org/assets/yoda.jpg';
// Use event delegation to update pointer style and borders
layer.on('mouseover', function (evt) {
const shape = evt.target;
document.body.style.cursor = 'pointer';
shape.strokeEnabled(false);
});
layer.on('mouseout', function (evt) {
const shape = evt.target;
document.body.style.cursor = 'default';
shape.strokeEnabled(true);
});
import { useState } from 'react';
import { Stage, Layer, Image } from 'react-konva';
import { useImage } from 'react-konva-utils';
const DraggableImage = ({ src, x, y, width, height }) => {
const [image] = useImage(src);
const [isHovered, setIsHovered] = useState(false);
const [position, setPosition] = useState({ x, y });
return (
<Image
image={image}
x={position.x}
y={position.y}
width={width}
height={height}
stroke="red"
strokeWidth={10}
strokeEnabled={!isHovered}
draggable
onDragMove={(e) => setPosition(e.target.position())}
onMouseEnter={() => {
setIsHovered(true);
document.body.style.cursor = 'pointer';
}}
onMouseLeave={() => {
setIsHovered(false);
document.body.style.cursor = 'default';
}}
/>
);
};
const App = () => {
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<DraggableImage
src="https://konvajs.org/assets/darth-vader.jpg"
x={20}
y={20}
width={200}
height={137}
/>
<DraggableImage
src="https://konvajs.org/assets/yoda.jpg"
x={240}
y={20}
width={93}
height={104}
/>
</Layer>
</Stage>
);
};
export default App;
<template>
<v-stage :config="stageConfig">
<v-layer ref="layerRef">
<v-image
v-for="(img, index) in images"
:key="index"
:config="getImageConfig(img, index)"
@mouseenter="handleMouseEnter(index)"
@mouseleave="handleMouseLeave(index)"
/>
</v-layer>
</v-stage>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue';
const stageConfig = {
width: window.innerWidth,
height: window.innerHeight
};
const layerRef = ref(null);
const hoveredIndex = ref(null);
const loadedImages = ref({});
// Define image data
const images = ref([
{
src: 'https://konvajs.org/assets/darth-vader.jpg',
x: 20,
y: 20,
width: 200,
height: 137
},
{
src: 'https://konvajs.org/assets/yoda.jpg',
x: 240,
y: 20,
width: 93,
height: 104
}
]);
// Load images
onMounted(() => {
images.value.forEach((img, index) => {
const imageObj = new Image();
imageObj.onload = () => {
loadedImages.value = {
...loadedImages.value,
[index]: imageObj
};
};
imageObj.src = img.src;
});
});
// Get configuration for each image
const getImageConfig = (img, index) => {
const isHovered = hoveredIndex.value === index;
return {
image: loadedImages.value[index],
x: img.x,
y: img.y,
width: img.width,
height: img.height,
stroke: 'red',
strokeWidth: 10,
strokeEnabled: !isHovered,
draggable: true
};
};
// Mouse event handlers
const handleMouseEnter = (index) => {
hoveredIndex.value = index;
document.body.style.cursor = 'pointer';
};
const handleMouseLeave = () => {
hoveredIndex.value = null;
document.body.style.cursor = 'default';
};
</script>