I'm trying to replicate a small React Native Skia scene using C++ and Skia directly.
In React Native Skia, I can easily nest <Group> elements with opacity and blendMode, and they seem to composite over the entire canvas (like in Photoshop).
export default function App() {
return (
<Canvas style={{ flex: 1 }}>
<Circle cx={128} cy={160} r={128} color="lightblue" />
<Group opacity={0.8}>
<Circle cx={64} cy={64} r={64} color="red" />
<Group blendMode="multiply">
<Circle cx={160} cy={96} r={96} color="lightgray" />
</Group>
</Group>
</Canvas>
);
}
And here’s my current C++ version:
https://fiddle.skia.org/c/0639d69ea8e19156b7a9d452d896dcb5
void draw(SkCanvas* canvas) {
SkPaint p;
p.setAntiAlias(true);
p.setStyle(SkPaint::kFill_Style);
p.setColor(0xFFADD8E6); // lightblue
canvas->drawCircle(128, 160, 128, p);
// parent group with opacity 0.8
SkPaint parentPaint;
parentPaint.setAlphaf(0.8f);
canvas->saveLayer(nullptr, &parentPaint);
// red circle
p.setColor(SK_ColorRED);
canvas->drawCircle(64, 64, 64, p);
// nested group with blend mode multiply
SkPaint blendPaint;
blendPaint.setBlendMode(SkBlendMode::kMultiply);
canvas->saveLayer(nullptr, &blendPaint);
// lightgray circle
p.setColor(0xFFD3D3D3); // lightgray
canvas->drawCircle(160, 96, 96, p);
canvas->restore(); // nested group (apply multiply)
canvas->restore(); // parent group (apply alpha)
}
The issue is that the blending and opacity results don’t quite match what I get in React Native Skia.
It looks like each layer only composites only over the previous layer, instead of over the entire canvas.
Questions:
How can I make nested saveLayer groups composite over the full canvas (like Photoshop or React Native Skia)?
Is there a recommended way to simulate “groups” with blendMode and opacity applied together in native Skia?
Is this related to backdrop management, or am I misunderstanding how saveLayer works internally?
Any insight would be appreciated!
Thanks,
Thomas Guittonneau