Eliminate stroke commit flicker with pending path overlay
When the pen lifts, the in-progress path was cleared immediately but the completed stroke didn't appear on the backing bitmap until the async DB save completed — creating a visible flash where the stroke vanished for several frames. Fix: transfer the completed path to a "pending" overlay that stays visible in the dynamic layer until addCompletedStroke() confirms the stroke is on the backing bitmap. The stroke is now visible continuously from pen-down through commit with no gap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -58,6 +58,12 @@ class PadCanvasView(context: Context) : View(context) {
|
||||
private var currentPaint: Paint? = null
|
||||
private val currentPoints = mutableListOf<Float>()
|
||||
|
||||
// --- Pending stroke: keeps the last completed stroke visible until
|
||||
// the backing bitmap confirms it, preventing the flash where the
|
||||
// stroke disappears between pen-up and DB save completion ---
|
||||
private var pendingPath: Path? = null
|
||||
private var pendingPaint: Paint? = null
|
||||
|
||||
// --- Line snap ---
|
||||
private var strokeOriginX = 0f
|
||||
private var strokeOriginY = 0f
|
||||
@@ -255,6 +261,9 @@ class PadCanvasView(context: Context) : View(context) {
|
||||
} else {
|
||||
bitmapDirty = true
|
||||
}
|
||||
// Stroke is now on the backing bitmap — clear the pending overlay
|
||||
pendingPath = null
|
||||
pendingPaint = null
|
||||
invalidate()
|
||||
}
|
||||
|
||||
@@ -310,6 +319,13 @@ class PadCanvasView(context: Context) : View(context) {
|
||||
|
||||
// Dynamic elements
|
||||
c.withMatrix(viewMatrix) {
|
||||
// Pending stroke (visible until backing bitmap confirms it)
|
||||
pendingPath?.let { path ->
|
||||
pendingPaint?.let { paint ->
|
||||
drawPath(path, paint)
|
||||
}
|
||||
}
|
||||
// In-progress stroke
|
||||
currentPath?.let { path ->
|
||||
currentPaint?.let { paint ->
|
||||
drawPath(path, paint)
|
||||
@@ -581,6 +597,10 @@ class PadCanvasView(context: Context) : View(context) {
|
||||
isSnappedToLine = false
|
||||
if (currentPoints.size >= 4) {
|
||||
val points = currentPoints.toFloatArray()
|
||||
// Keep the path visible as "pending" until the backing
|
||||
// bitmap confirms the stroke (prevents flash on commit)
|
||||
pendingPath = currentPath
|
||||
pendingPaint = currentPaint
|
||||
onStrokeCompleted?.invoke(canvasState.penWidthPt, Color.BLACK, points, Stroke.STYLE_PLAIN)
|
||||
}
|
||||
currentPath = null
|
||||
|
||||
Reference in New Issue
Block a user