🎉 Implement inner shadows (wasm) (#5767)

* 🎉 Implement inner shadows (wasm)

* 🐛 Fix reset canvas problem

---------

Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
This commit is contained in:
Belén Albeza 2025-02-14 13:46:30 +01:00 committed by GitHub
parent 2ffb77cb4d
commit 6cbaacf1e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 127 additions and 20 deletions

View file

@ -1,4 +1,4 @@
use skia_safe::{self as skia, image_filters};
use skia_safe::{self as skia, image_filters, ImageFilter};
use super::Color;
@ -26,10 +26,10 @@ impl Default for ShadowStyle {
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Shadow {
color: Color,
blur: f32,
spread: f32,
offset: (f32, f32),
pub color: Color,
pub blur: f32,
pub spread: f32,
pub offset: (f32, f32),
style: ShadowStyle,
hidden: bool,
}
@ -62,8 +62,21 @@ impl Shadow {
self.hidden
}
pub fn to_paint(&self, dilate: bool, scale: f32) -> skia::Paint {
pub fn to_paint(&self, scale: f32) -> skia::Paint {
let mut paint = skia::Paint::default();
let image_filter = match self.style {
ShadowStyle::Drop => self.drop_shadow_filters(scale),
ShadowStyle::Inner => self.inner_shadow_filters(scale),
};
paint.set_image_filter(image_filter);
paint.set_anti_alias(true);
paint
}
fn drop_shadow_filters(&self, scale: f32) -> Option<ImageFilter> {
let mut filter = image_filters::drop_shadow_only(
(self.offset.0 * scale, self.offset.1 * scale),
(self.blur * scale, self.blur * scale),
@ -73,14 +86,41 @@ impl Shadow {
None,
);
if dilate {
if self.spread > 0. {
filter =
image_filters::dilate((self.spread * scale, self.spread * scale), filter, None);
}
paint.set_image_filter(filter);
paint.set_anti_alias(true);
filter
}
paint
fn inner_shadow_filters(&self, scale: f32) -> Option<ImageFilter> {
let sigma = self.blur * 0.5;
let mut filter = skia::image_filters::drop_shadow_only(
(self.offset.0 * scale, self.offset.1 * scale), // DPR?
(sigma * scale, sigma * scale),
skia::Color::BLACK,
None,
None,
None,
);
filter = skia::image_filters::color_filter(
skia::color_filters::blend(self.color, skia::BlendMode::SrcOut).unwrap(),
filter,
None,
);
if self.spread > 0. {
filter = skia::image_filters::dilate(
(self.spread * scale, self.spread * scale),
filter,
None,
);
}
filter = skia::image_filters::blend(skia::BlendMode::SrcIn, None, filter, None);
filter
}
}