模糊滤镜补间教程
如需使用 Konva 对滤镜执行补间,只需对与该滤镜关联的属性执行补间。
本教程将对 blurRadius 属性执行补间。该属性控制应用于图像的模糊程度。
操作说明:将鼠标移到图像上或触摸图像,使图像变清晰(减少模糊)。
- 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();
// create image
const imageObj = new Image();
imageObj.onload = () => {
const lion = new Konva.Image({
x: 50,
y: 50,
image: imageObj,
draggable: true,
});
layer.add(lion);
// add blur filter
lion.cache();
lion.filters([Konva.Filters.Blur]);
lion.blurRadius(10);
// create blur tween
const tween = new Konva.Tween({
node: lion,
duration: 0.5,
blurRadius: 0,
easing: Konva.Easings.EaseInOut,
});
// bind events
lion.on('mouseenter touchstart', () => {
tween.play();
});
lion.on('mouseleave touchend', () => {
tween.reverse();
});
};
imageObj.src = '/assets/lion.png';
imageObj.crossOrigin = 'anonymous';
stage.add(layer);
import Konva from 'konva';
import { Stage, Layer, Image } from 'react-konva';
import { useEffect, useRef, useState } from 'react';
import useImage from 'use-image';
const App = () => {
const imageRef = useRef();
const [image] = useImage('/assets/lion.png');
const tweenRef = useRef();
const [position, setPosition] = useState({ x: 50, y: 50 });
useEffect(() => {
if (!image || !imageRef.current) return;
const node = imageRef.current;
node.cache();
node.filters([Konva.Filters.Blur]);
node.blurRadius(10);
const tween = new Konva.Tween({
node: node,
duration: 0.5,
blurRadius: 0,
easing: Konva.Easings.EaseInOut,
});
tweenRef.current = tween;
return () => {
tween.destroy();
if (tweenRef.current === tween) tweenRef.current = null;
};
}, [image]);
const handleMouseEnter = () => {
tweenRef.current?.play();
};
const handleMouseLeave = () => {
tweenRef.current?.reverse();
};
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Image
ref={imageRef}
x={position.x}
y={position.y}
image={image}
draggable
onDragEnd={(e) => {
setPosition({ x: e.target.x(), y: e.target.y() });
}}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onTouchStart={handleMouseEnter}
onTouchEnd={handleMouseLeave}
/>
</Layer>
</Stage>
);
};
export default App;
<template>
<v-stage :config="stageSize">
<v-layer>
<v-image
v-if="image"
:config="imageConfig"
@mouseenter="handleMouseEnter"
@mouseleave="handleMouseLeave"
@touchstart="handleMouseEnter"
@touchend="handleMouseLeave"
ref="imageRef"
/>
</v-layer>
</v-stage>
</template>
<script setup>
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
import Konva from 'konva';
const stageSize = {
width: window.innerWidth,
height: window.innerHeight
};
const image = ref(null);
const imageRef = ref(null);
let tween = null;
// Load image
const img = new Image();
img.onload = () => {
image.value = img;
};
img.src = '/assets/lion.png';
const imageConfig = computed(() => ({
x: 50,
y: 50,
image: image.value,
draggable: true
}));
watch(image, async (loadedImage) => {
if (!loadedImage) return;
await nextTick();
const node = imageRef.value.getNode();
node.cache();
node.filters([Konva.Filters.Blur]);
node.blurRadius(10);
tween = new Konva.Tween({
node: node,
duration: 0.5,
blurRadius: 0,
easing: Konva.Easings.EaseInOut,
});
});
const handleMouseEnter = () => {
tween?.play();
};
const handleMouseLeave = () => {
tween?.reverse();
};
onUnmounted(() => tween?.destroy());
</script>