perf(canvas): bound blend and text mask layers
This commit is contained in:
parent
f07d26c50b
commit
0d5db35147
|
|
@ -2,6 +2,7 @@
|
|||
import type { Canvas, Path } from 'canvaskit-wasm'
|
||||
|
||||
import { DROP_HIGHLIGHT_ALPHA, DROP_HIGHLIGHT_STROKE, SECTION_CORNER_RADIUS } from '#core/constants'
|
||||
import { computeDescendantVisualBounds } from '#core/geometry'
|
||||
import type { SceneNode, SceneGraph, Fill } from '#core/scene-graph'
|
||||
import type { Color } from '#core/types'
|
||||
import { vectorNetworkToCenterlinePath } from '#core/vector'
|
||||
|
|
@ -212,9 +213,22 @@ export function renderNode(
|
|||
|
||||
const needsNodeLayer = node.opacity < 1 || needsIsolatedBlendLayer(node.blendMode)
|
||||
if (needsNodeLayer) {
|
||||
const bounds = computeDescendantVisualBounds(
|
||||
[nodeId],
|
||||
(id) => graph.getNode(id) ?? undefined,
|
||||
(id) => graph.getAbsolutePosition(id)
|
||||
)
|
||||
const layerBounds = bounds
|
||||
? r.ck.LTRBRect(
|
||||
bounds.minX - absX,
|
||||
bounds.minY - absY,
|
||||
bounds.maxX - absX,
|
||||
bounds.maxY - absY
|
||||
)
|
||||
: r.ck.LTRBRect(0, 0, node.width, node.height)
|
||||
r.opacityPaint.setAlphaf(node.opacity)
|
||||
r.opacityPaint.setBlendMode(figmaBlendModeToSkia(r.ck, node.blendMode))
|
||||
canvas.saveLayer(r.opacityPaint)
|
||||
canvas.saveLayer(r.opacityPaint, layerBounds)
|
||||
}
|
||||
|
||||
const layerBlur = node.effects.find(
|
||||
|
|
@ -589,11 +603,12 @@ function drawGradientText(
|
|||
r.effectLayerPaint.setImageFilter(null)
|
||||
r.effectLayerPaint.setColorFilter(null)
|
||||
r.effectLayerPaint.setBlendMode(r.ck.BlendMode.SrcOver)
|
||||
canvas.saveLayer(r.effectLayerPaint)
|
||||
const bounds = r.ck.LTRBRect(0, paragraphY, node.width, paragraphY + node.height)
|
||||
canvas.saveLayer(r.effectLayerPaint, bounds)
|
||||
canvas.drawParagraph(paragraph, 0, paragraphY)
|
||||
|
||||
r.effectLayerPaint.setBlendMode(r.ck.BlendMode.SrcIn)
|
||||
canvas.saveLayer(r.effectLayerPaint)
|
||||
canvas.saveLayer(r.effectLayerPaint, bounds)
|
||||
canvas.drawRect(r.ck.LTRBRect(0, 0, node.width, node.height), r.fillPaint)
|
||||
canvas.restore()
|
||||
canvas.restore()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { describe, expect, mock, test } from 'bun:test'
|
||||
|
||||
import type { Canvas } from 'canvaskit-wasm'
|
||||
|
||||
import { figmaBlendModeToSkia } from '#core/canvas/blend'
|
||||
|
|
@ -123,7 +124,8 @@ describe('canvas blend modes', () => {
|
|||
|
||||
expect(renderer.opacityPaint.setAlphaf).toHaveBeenCalledWith(1)
|
||||
expect(renderer.opacityPaint.setBlendMode).toHaveBeenCalledWith('Multiply')
|
||||
expect(canvas.saveLayer).toHaveBeenCalledWith(renderer.opacityPaint)
|
||||
expect(canvas.saveLayer).toHaveBeenCalledWith(renderer.opacityPaint, expect.any(Float32Array))
|
||||
expect(renderer.ck.LTRBRect).toHaveBeenCalledWith(0, 0, 100, 100)
|
||||
expect(renderer.renderShape).toHaveBeenCalled()
|
||||
expect(renderer.opacityPaint.setBlendMode).toHaveBeenLastCalledWith('SrcOver')
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue