feat: unified shell, diagnostics pack, native Office, sticky board
All checks were successful
CI / Windows build (push) Successful in 14m22s
All checks were successful
CI / Windows build (push) Successful in 14m22s
Make Surface remote debugging and classroom workflows viable: always-on structured logs with one-click zip export, a single AppShell chrome, OOXML PPTX/DOCX annotation without LibreOffice, and a first-class sticky board. Also drop spike/legacy ink widgets and tighten pen feel (predictor, PenInfoHistory, page-tile layer). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
56
lib/editor/engine/stroke_predictor.dart
Normal file
56
lib/editor/engine/stroke_predictor.dart
Normal file
@@ -0,0 +1,56 @@
|
||||
// Lightweight stroke prediction — extrapolates the next point from recent
|
||||
// velocity so the live stroke tip leads the digitizer slightly (lower perceived
|
||||
// latency). Not a full ink-stroke-modeler; intentionally small and testable.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
class PredictedPoint {
|
||||
const PredictedPoint(this.offset, this.pressure);
|
||||
final Offset offset;
|
||||
final double pressure;
|
||||
}
|
||||
|
||||
class StrokePredictor {
|
||||
StrokePredictor({this.lookaheadMs = 12});
|
||||
|
||||
/// How far ahead to project, in milliseconds of recent velocity.
|
||||
final double lookaheadMs;
|
||||
|
||||
Offset? _prev;
|
||||
double? _prevPressure;
|
||||
DateTime? _prevAt;
|
||||
Offset _velocity = Offset.zero;
|
||||
|
||||
void reset() {
|
||||
_prev = null;
|
||||
_prevPressure = null;
|
||||
_prevAt = null;
|
||||
_velocity = Offset.zero;
|
||||
}
|
||||
|
||||
/// Feed a real sample; returns an optional predicted tip ahead of [point].
|
||||
PredictedPoint? observe(Offset point, double pressure, {DateTime? at}) {
|
||||
final now = at ?? DateTime.now();
|
||||
if (_prev != null && _prevAt != null) {
|
||||
final dtMs = now.difference(_prevAt!).inMicroseconds / 1000.0;
|
||||
if (dtMs > 0.5 && dtMs < 80) {
|
||||
final raw = (point - _prev!) * (1000.0 / dtMs);
|
||||
// EMA blend to avoid jerky predictions.
|
||||
_velocity = Offset(
|
||||
_velocity.dx * 0.55 + raw.dx * 0.45,
|
||||
_velocity.dy * 0.55 + raw.dy * 0.45,
|
||||
);
|
||||
}
|
||||
}
|
||||
_prev = point;
|
||||
_prevPressure = pressure;
|
||||
_prevAt = now;
|
||||
|
||||
if (_velocity.distance < 40) return null; // idle / slow — no predict
|
||||
final tip = point + _velocity * (lookaheadMs / 1000.0);
|
||||
return PredictedPoint(tip, pressure);
|
||||
}
|
||||
|
||||
/// Last known pressure (for predicted tip).
|
||||
double get lastPressure => _prevPressure ?? 0.5;
|
||||
}
|
||||
Reference in New Issue
Block a user