Skip to content

Commit

Permalink
feat: FeDropShadow (#2514)
Browse files Browse the repository at this point in the history
# Summary

Continuation of #2362 introducing highly requested ✨ `FeDropShadow` ✨
filter. This addition is straightforward since it's essentially a
shorthand (as specified in the spec) for filters that are already
implemented: https://www.w3.org/TR/filter-effects-1/#feDropShadowElement

<img width="532" alt="image"
src="https://github.com/user-attachments/assets/b221ee4c-d8b0-469b-acb0-71224fb2b1e0">

## Test Plan

Example app -> Filters -> FeDropShadow

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |    ✅      |
| macOS   |    ✅      |
| Android |    ✅      |
| Web     |    ✅      |
  • Loading branch information
jakex7 authored Oct 28, 2024
1 parent 36ca5c4 commit e6a27f8
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
4 changes: 2 additions & 2 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,9 @@ Filter effects are a way of processing an element’s rendering before it is dis
The following filters have been implemented:

- FeBlend
- FeComposite
- FeColorMatrix
- FeDropShadow
- FeFlood
- FeGaussianBlur
- FeMerge
Expand All @@ -1310,11 +1312,9 @@ The following filters have been implemented:
Not supported yet:

- FeComponentTransfer
- FeComposite
- FeConvolveMatrix
- FeDiffuseLighting
- FeDisplacementMap
- FeDropShadow
- FeFuncA
- FeFuncB
- FeFuncG
Expand Down
59 changes: 59 additions & 0 deletions apps/common/example/examples/Filters/FeDropShadow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import {
Circle,
FeDropShadow,
FeFlood,
Filter,
Rect,
Svg,
} from 'react-native-svg';

BasicMDN.title = 'Basic MDN example';
function BasicMDN() {
return (
<Svg viewBox="0 0 30 10" width="300" height="100">
<Filter id="shadow">
<FeDropShadow dx="0.2" dy="0.4" stdDeviation="0.2" />
</Filter>
<Filter id="shadow2">
<FeDropShadow dx="0" dy="0" stdDeviation="5" floodColor="cyan" />
</Filter>
<Filter id="shadow3">
<FeDropShadow
dx="-0.8"
dy="-0.8"
stdDeviation="0"
floodColor="pink"
floodOpacity="0.5"
/>
</Filter>
<Circle cx="5" cy="50%" r="4" fill="pink" filter="url(#shadow)" />
<Circle cx="15" cy="50%" r="4" fill="pink" filter="url(#shadow2)" />
<Circle cx="25" cy="50%" r="4" fill="pink" filter="url(#shadow3)" />
</Svg>
);
}

const icon = (
<Svg height="30" width="30" viewBox="0 0 140 140">
<Filter
id="floodFilterIcon"
x="50%"
filterUnits="userSpaceOnUse"
primitiveUnits="userSpaceOnUse">
<FeFlood
y="-10%"
x="10%"
width="50%"
height="50%"
floodColor="yellow"
floodOpacity="0.5"
/>
</Filter>
<Rect x="0" y="0" width="100" height="100" fill="blue" />
<Circle cx="50" cy="50" r="40" filter="url(#floodFilterIcon)" />
</Svg>
);
const samples = [BasicMDN];

export {icon, samples};
2 changes: 2 additions & 0 deletions apps/common/example/examples/Filters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Svg, {Circle} from 'react-native-svg';
import * as FeBlend from './FeBlend';
import * as FeColorMatrix from './FeColorMatrix';
import * as FeComposite from './FeComposite';
import * as FeDropShadow from './FeDropShadow';
import * as FeFlood from './FeFlood';
import * as FeGaussianBlur from './FeGaussianBlur';
import * as FeMerge from './FeMerge';
Expand All @@ -13,6 +14,7 @@ const samples = {
FeBlend,
FeColorMatrix,
FeComposite,
FeDropShadow,
FeFlood,
FeGaussianBlur,
FeMerge,
Expand Down
28 changes: 25 additions & 3 deletions src/elements/filters/FeDropShadow.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { ColorValue } from 'react-native';
import { NumberArray, NumberProp } from '../../lib/extract/types';
import { warnUnimplementedFilter } from '../../lib/util';
import FeFlood from './FeFlood';
import FeGaussianBlur from './FeGaussianBlur';
import FeMerge from './FeMerge';
import FeMergeNode from './FeMergeNode';
import FeOffset from './FeOffset';
import FilterPrimitive from './FilterPrimitive';
import FeComposite from './FeComposite';

export interface FeDropShadowProps {
in?: string;
stdDeviation?: NumberArray;
dx?: NumberProp;
dy?: NumberProp;
floodColor?: ColorValue;
floodOpacity?: NumberProp;
}

export default class FeDropShadow extends FilterPrimitive<FeDropShadowProps> {
Expand All @@ -17,7 +25,21 @@ export default class FeDropShadow extends FilterPrimitive<FeDropShadowProps> {
};

render() {
warnUnimplementedFilter();
return null;
const { stdDeviation, in: in1 = 'SourceGraphic', dx, dy } = this.props;
return (
<>
<FeGaussianBlur in={in1} stdDeviation={stdDeviation} />
<FeOffset dx={dx} dy={dy} result="offsetblur" />
<FeFlood
floodColor={this.props.floodColor}
floodOpacity={this.props.floodOpacity}
/>
<FeComposite in2="offsetblur" operator="in" />
<FeMerge>
<FeMergeNode />
<FeMergeNode in={in1} />
</FeMerge>
</>
);
}
}

0 comments on commit e6a27f8

Please sign in to comment.