diff --git a/package/cpp/rnskia/dom/base/DrawingContext.cpp b/package/cpp/rnskia/dom/base/DrawingContext.cpp index 32e39ee96a..f8ad90e905 100644 --- a/package/cpp/rnskia/dom/base/DrawingContext.cpp +++ b/package/cpp/rnskia/dom/base/DrawingContext.cpp @@ -179,8 +179,12 @@ double DrawingContext::getOpacity() { Sets the opacity value */ void DrawingContext::setOpacity(double opacity) { - getMutablePaint()->setAlphaf(_opacity); - _opacity = opacity; + auto currentOpacity = opacity; + if (_parent != nullptr) { + currentOpacity *= _parent->getOpacity(); + } + getMutablePaint()->setAlphaf(currentOpacity); + _opacity = currentOpacity; } /** diff --git a/package/cpp/rnskia/dom/props/PaintProps.h b/package/cpp/rnskia/dom/props/PaintProps.h index 94a0a3b2ce..3b44227ad7 100644 --- a/package/cpp/rnskia/dom/props/PaintProps.h +++ b/package/cpp/rnskia/dom/props/PaintProps.h @@ -93,8 +93,7 @@ class PaintProps : public BaseDerivedProp { // Opacity if (_opacity->isChanged() || context->isChanged()) { if (_opacity->isSet()) { - context->setOpacity(context->getOpacity() * - _opacity->value().getAsNumber()); + context->setOpacity(_opacity->value().getAsNumber()); } else { context->clearOpacity(); } diff --git a/package/src/__tests__/setup.ts b/package/src/__tests__/setup.ts index 4115a07be5..a203eb109e 100644 --- a/package/src/__tests__/setup.ts +++ b/package/src/__tests__/setup.ts @@ -35,13 +35,27 @@ export const processResult = ( ckSurface.getCanvas().clear(Float32Array.of(0, 0, 0, 0)); }; +interface CheckImageOptions { + maxPixelDiff?: number; + threshold?: number; + overwrite?: boolean; + mute?: boolean; +} + +const defaultCheckImageOptions = { + maxPixelDiff: 0, + threshold: 0.1, + overwrite: false, + mute: false, +}; + export const checkImage = ( image: SkImage, relPath: string, - overwrite = false, - mute = false, - threshold = 0.1 + opts?: CheckImageOptions ) => { + const options = { ...defaultCheckImageOptions, ...opts }; + const { overwrite, threshold, mute, maxPixelDiff } = options; const png = image.encodeToBytes(); const p = path.resolve(__dirname, relPath); if (fs.existsSync(p) && !overwrite) { @@ -61,11 +75,11 @@ export const checkImage = ( { threshold } ); if (!mute) { - if (diffPixelsCount !== 0) { + if (diffPixelsCount > maxPixelDiff) { fs.writeFileSync(`${p}.test.png`, PNG.sync.write(toTest)); - // fs.writeFileSync(`${p}-diff-test.png`, PNG.sync.write(diffImage)); + fs.writeFileSync(`${p}-diff-test.png`, PNG.sync.write(diffImage)); } - expect(diffPixelsCount).toBe(0); + expect(diffPixelsCount).toBeLessThanOrEqual(maxPixelDiff); } return diffPixelsCount; } else { diff --git a/package/src/__tests__/snapshots/drawings/violet.png b/package/src/__tests__/snapshots/drawings/violet.png new file mode 100644 index 0000000000..02b2689629 Binary files /dev/null and b/package/src/__tests__/snapshots/drawings/violet.png differ diff --git a/package/src/dom/nodes/RenderNode.ts b/package/src/dom/nodes/RenderNode.ts index 32db2e9182..d5908da609 100644 --- a/package/src/dom/nodes/RenderNode.ts +++ b/package/src/dom/nodes/RenderNode.ts @@ -208,27 +208,19 @@ export abstract class JsiRenderNode
const { invertClip, layer, matrix, transform } = this.props; const { canvas } = parentCtx; - const opacity = - this.props.opacity !== undefined - ? parentCtx.paint.getAlphaf() * this.props.opacity - : parentCtx.paint.getAlphaf(); - if ( this.paintCache === null || this.paintCache.parent !== parentCtx.paint ) { const paintCtx = this.getPaintCtx(); - if (paintCtx) { - paintCtx.opacity = opacity; - } const child = paintCtx - ? concatPaint(parentCtx.paint, paintCtx) + ? concatPaint(parentCtx.paint.copy(), paintCtx) : parentCtx.paint; this.paintCache = { parent: parentCtx.paint, child }; } const paint = this.paintCache.child; // TODO: can we only recreate a new context here if needed? - const ctx = { ...parentCtx, opacity, paint }; + const ctx = { ...parentCtx, paint }; const hasTransform = matrix !== undefined || transform !== undefined; const hasClip = this.clipRect !== undefined || @@ -270,7 +262,7 @@ export abstract class JsiRenderNode
}
const concatPaint = (
- parent: SkPaint,
+ paint: SkPaint,
{
color,
strokeWidth,
@@ -288,10 +280,14 @@ const concatPaint = (
style,
}: PaintContext
) => {
- const paint = parent.copy();
+ if (opacity !== undefined) {
+ paint.setAlphaf(paint.getAlphaf() * opacity);
+ }
if (color !== undefined) {
+ const currentOpacity = paint.getAlphaf();
paint.setShader(null);
paint.setColor(color);
+ paint.setAlphaf(currentOpacity * paint.getAlphaf());
}
if (strokeWidth !== undefined) {
paint.setStrokeWidth(strokeWidth);
@@ -329,6 +325,5 @@ const concatPaint = (
if (style !== undefined) {
paint.setStyle(style);
}
- paint.setAlphaf(paint.getAlphaf() * (opacity ?? 1));
return paint;
};
diff --git a/package/src/renderer/__tests__/e2e/Drawings.spec.tsx b/package/src/renderer/__tests__/e2e/Drawings.spec.tsx
index 2b8ab953c1..8dc32420ee 100644
--- a/package/src/renderer/__tests__/e2e/Drawings.spec.tsx
+++ b/package/src/renderer/__tests__/e2e/Drawings.spec.tsx
@@ -50,7 +50,9 @@ describe("Drawings", () => {