or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-management.mdindex.mdinstance-control.mdmomentum-control.mdplugin-system.md

momentum-control.mddocs/

0

# Momentum Control

1

2

Advanced momentum control for natural scrolling physics with customizable easing and momentum manipulation. Provides fine-grained control over scroll momentum for creating smooth, physics-based scrolling experiences.

3

4

## Capabilities

5

6

### Basic Momentum Control

7

8

Methods for directly manipulating scroll momentum during scrolling operations.

9

10

```typescript { .api }

11

/**

12

* Adds momentum to current scroll velocity

13

* @param x - Horizontal momentum to add

14

* @param y - Vertical momentum to add

15

*/

16

addMomentum(x: number, y: number): void;

17

18

/**

19

* Sets scroll momentum directly, replacing current momentum

20

* @param x - Horizontal momentum value

21

* @param y - Vertical momentum value

22

*/

23

setMomentum(x: number, y: number): void;

24

```

25

26

**Usage Examples:**

27

28

```typescript

29

// Add momentum for smooth continuation

30

scrollbar.addMomentum(0, 200); // Add downward momentum

31

32

// Stop all momentum immediately

33

scrollbar.setMomentum(0, 0);

34

35

// Set specific momentum for custom scrolling effects

36

scrollbar.setMomentum(50, -100); // Right and up momentum

37

```

38

39

### Transformable Momentum

40

41

Advanced momentum control that allows event-based momentum transformation with callback support.

42

43

```typescript { .api }

44

/**

45

* Adds momentum that can be transformed by plugins, with callback notification

46

* @param x - Horizontal momentum to add

47

* @param y - Vertical momentum to add

48

* @param fromEvent - Source event that generated the momentum

49

* @param callback - Optional callback function called with scroll decision

50

*/

51

addTransformableMomentum(

52

x: number,

53

y: number,

54

fromEvent: Event,

55

callback?: AddTransformableMomentumCallback

56

): void;

57

```

58

59

**Usage Examples:**

60

61

```typescript

62

// Add momentum from custom gesture

63

const customGestureEvent = new CustomEvent("swipe");

64

scrollbar.addTransformableMomentum(0, 300, customGestureEvent, function(willScroll) {

65

if (willScroll) {

66

console.log("Scrolling will occur");

67

// Add visual feedback

68

this.containerEl.classList.add("scrolling");

69

} else {

70

console.log("Scroll was prevented by plugin");

71

}

72

});

73

74

// Custom momentum with mouse wheel simulation

75

const wheelEvent = new WheelEvent("wheel", { deltaY: 120 });

76

scrollbar.addTransformableMomentum(0, 120, wheelEvent, function(willScroll) {

77

// Track scroll analytics

78

analytics.track("custom_scroll", { willScroll, momentum: 120 });

79

});

80

```

81

82

### Momentum Physics Configuration

83

84

Configuration options that affect momentum behavior and physics calculations.

85

86

```typescript { .api }

87

interface ScrollbarOptions {

88

/**

89

* Momentum reduction damping factor, float between (0, 1)

90

* Lower values = more smooth scrolling (more frames)

91

* Higher values = quicker momentum decay

92

*/

93

damping: number;

94

95

/**

96

* Render every frame in integer pixel values

97

* Improves performance by avoiding sub-pixel rendering

98

*/

99

renderByPixels: boolean;

100

101

/**

102

* Allow outer scrollbars to continue scrolling when this reaches edge

103

* Affects momentum transfer to parent scrollable elements

104

*/

105

continuousScrolling: boolean;

106

}

107

```

108

109

**Usage Examples:**

110

111

```typescript

112

// Ultra-smooth momentum (more CPU intensive)

113

const smoothScrollbar = Scrollbar.init(container, {

114

damping: 0.05, // Very low damping for long momentum

115

renderByPixels: false // Sub-pixel rendering for smoothness

116

});

117

118

// Performance-optimized momentum

119

const fastScrollbar = Scrollbar.init(container, {

120

damping: 0.2, // Higher damping for quicker stops

121

renderByPixels: true, // Integer pixels for performance

122

continuousScrolling: false // Contain momentum within this scrollbar

123

});

124

```

125

126

## Advanced Momentum Patterns

127

128

### Custom Momentum Easing

129

130

Creating custom momentum behavior through easing functions and momentum manipulation.

131

132

```typescript

133

// Custom elastic momentum effect

134

function addElasticMomentum(scrollbar, targetY, elasticity = 0.8) {

135

const currentY = scrollbar.scrollTop;

136

const distance = targetY - currentY;

137

138

// Apply elastic easing

139

const momentum = distance * elasticity;

140

141

scrollbar.addTransformableMomentum(0, momentum, new Event("custom"), function(willScroll) {

142

if (willScroll && Math.abs(distance) > 1) {

143

// Continue elastic animation

144

setTimeout(() => {

145

addElasticMomentum(scrollbar, targetY, elasticity * 0.9);

146

}, 16);

147

}

148

});

149

}

150

151

// Usage

152

addElasticMomentum(scrollbar, 500);

153

```

154

155

### Momentum-Based Gestures

156

157

Implementing swipe gestures and momentum-based interactions.

158

159

```typescript

160

class SwipeGestureHandler {

161

private startY = 0;

162

private lastY = 0;

163

private velocity = 0;

164

private lastTime = 0;

165

166

constructor(private scrollbar: Scrollbar) {

167

this.setupGestureListeners();

168

}

169

170

private setupGestureListeners() {

171

const container = this.scrollbar.containerEl;

172

173

container.addEventListener("touchstart", (e) => {

174

this.startY = e.touches[0].clientY;

175

this.lastY = this.startY;

176

this.velocity = 0;

177

this.lastTime = Date.now();

178

});

179

180

container.addEventListener("touchmove", (e) => {

181

const currentY = e.touches[0].clientY;

182

const currentTime = Date.now();

183

const deltaTime = currentTime - this.lastTime;

184

185

if (deltaTime > 0) {

186

this.velocity = (currentY - this.lastY) / deltaTime;

187

}

188

189

this.lastY = currentY;

190

this.lastTime = currentTime;

191

});

192

193

container.addEventListener("touchend", (e) => {

194

// Convert velocity to momentum

195

const momentum = this.velocity * 300; // Scale factor

196

197

this.scrollbar.addTransformableMomentum(0, -momentum, e, function(willScroll) {

198

if (willScroll) {

199

// Add momentum-based visual feedback

200

this.containerEl.style.transition = "transform 0.1s ease-out";

201

this.containerEl.style.transform = `translateY(${momentum > 0 ? -2 : 2}px)`;

202

203

setTimeout(() => {

204

this.containerEl.style.transform = "";

205

this.containerEl.style.transition = "";

206

}, 100);

207

}

208

});

209

});

210

}

211

}

212

213

// Usage

214

const gestureHandler = new SwipeGestureHandler(scrollbar);

215

```

216

217

### Momentum Monitoring

218

219

Tracking and analyzing momentum for performance optimization and user experience.

220

221

```typescript

222

class MomentumMonitor {

223

private momentumHistory: Array<{time: number, momentum: Data2d}> = [];

224

225

constructor(private scrollbar: Scrollbar) {

226

this.setupMonitoring();

227

}

228

229

private setupMonitoring() {

230

// Override addMomentum to track all momentum changes

231

const originalAddMomentum = this.scrollbar.addMomentum.bind(this.scrollbar);

232

233

this.scrollbar.addMomentum = (x: number, y: number) => {

234

this.recordMomentum(x, y);

235

return originalAddMomentum(x, y);

236

};

237

}

238

239

private recordMomentum(x: number, y: number) {

240

this.momentumHistory.push({

241

time: Date.now(),

242

momentum: { x, y }

243

});

244

245

// Keep only recent history

246

if (this.momentumHistory.length > 100) {

247

this.momentumHistory.shift();

248

}

249

}

250

251

getMomentumStats() {

252

if (this.momentumHistory.length === 0) return null;

253

254

const totalMagnitude = this.momentumHistory.reduce((sum, entry) => {

255

return sum + Math.sqrt(entry.momentum.x ** 2 + entry.momentum.y ** 2);

256

}, 0);

257

258

return {

259

averageMagnitude: totalMagnitude / this.momentumHistory.length,

260

peakMomentum: this.momentumHistory.reduce((max, entry) => {

261

const magnitude = Math.sqrt(entry.momentum.x ** 2 + entry.momentum.y ** 2);

262

return Math.max(max, magnitude);

263

}, 0),

264

momentumEvents: this.momentumHistory.length

265

};

266

}

267

}

268

269

// Usage

270

const monitor = new MomentumMonitor(scrollbar);

271

272

// Later, get performance insights

273

setInterval(() => {

274

const stats = monitor.getMomentumStats();

275

console.log("Momentum stats:", stats);

276

}, 5000);

277

```

278

279

## Momentum Callback Types

280

281

```typescript { .api }

282

interface AddTransformableMomentumCallback {

283

/**

284

* Callback function called after momentum transformation

285

* @param willScroll - Whether scrolling will actually occur after transformation

286

*/

287

(this: Scrollbar, willScroll: boolean): void;

288

}

289

290

interface Data2d {

291

/** Horizontal component */

292

x: number;

293

294

/** Vertical component */

295

y: number;

296

}

297

```