You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-konva实现元素超出容器范围时外部区域模糊效果

React-Konva实现元素超出容器时外部区域模糊效果

核心思路是把目标元素拆成两个部分渲染:容器内的清晰区域,和容器外的模糊区域,通过裁剪路径和滤镜组合实现效果,下面是具体实现步骤和代码:

实现步骤

  • 定义容器的位置与尺寸,作为可视边界
  • 对目标元素做两个副本:
    1. 第一个副本用裁剪路径只保留容器内的部分,不添加滤镜,保持清晰
    2. 第二个副本添加模糊滤镜,并用反向裁剪只保留容器外的部分
  • 绑定拖拽事件,同步两个副本的位置(如果有缩放/旋转也要同步对应属性)

完整代码示例

import React, { useState } from "react";
import { render } from "react-dom";
import { Stage, Layer, Rect, Circle, Transformer } from "react-konva";
import { Blur } from "konva/lib/filters/Blur";

const App = () => {
  const [circlePos, setCirclePos] = useState({ x: 150, y: 150 });
  // 容器的位置和尺寸
  const container = { x: 50, y: 50, width: 200, height: 200 };

  // 裁剪出容器内的区域
  const clipInside = (ctx) => {
    ctx.rect(container.x, container.y, container.width, container.height);
  };

  // 裁剪出容器外的区域(利用evenodd规则实现反向裁剪)
  const clipOutside = (ctx) => {
    // 先画整个舞台范围
    ctx.rect(0, 0, 400, 400);
    // 再画容器范围,evenodd规则会把两个区域的差值保留
    ctx.rect(container.x, container.y, container.width, container.height);
    ctx.clip("evenodd");
  };

  return (
    <Stage width={400} height={400}>
      <Layer>
        {/* 容器背景 */}
        <Rect
          x={container.x}
          y={container.y}
          width={container.width}
          height={container.height}
          fill="#eee"
          stroke="#ddd"
        />

        {/* 下层:模糊的外部区域 */}
        <Circle
          x={circlePos.x}
          y={circlePos.y}
          radius={50}
          fill="red"
          clipFunc={clipOutside}
          filters={[Blur]}
          blurRadius={5}
        />

        {/* 上层:清晰的内部区域,绑定拖拽事件 */}
        <Circle
          className="konva-circle"
          x={circlePos.x}
          y={circlePos.y}
          radius={50}
          fill="red"
          clipFunc={clipInside}
          draggable
          onDragEnd={(e) => {
            setCirclePos({ x: e.target.x(), y: e.target.y() });
          }}
        />

        {/* 拖拽控制器 */}
        <Transformer
          node={document.querySelector(".konva-circle")}
          enabledAnchors={["top-left", "top-right", "bottom-left", "bottom-right"]}
        />
      </Layer>
    </Stage>
  );
};

render(<App />, document.getElementById("root"));

关键细节说明

  • 裁剪路径(clipFunc):通过Canvas的clip方法和evenodd填充规则,实现反向裁剪,精准保留容器外的区域
  • 图层叠加顺序:模糊元素放在下层,清晰元素在上层,视觉上就会呈现“内部清晰、外部模糊”的效果
  • 性能优化提示:模糊滤镜会消耗一定性能,如果是复杂场景,可以考虑只在元素拖拽过程中启用模糊,静止时关闭,或者使用离屏Canvas预渲染模糊区域

内容的提问来源于stack exchange,提问作者thitbachi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:38:00