@srsergio/taptapp-ar 1.0.28 → 1.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -62,6 +62,7 @@ export class SimpleAR {
62
62
  controller: Controller | null;
63
63
  isTracking: boolean;
64
64
  lastMatrix: any;
65
+ filters: any[];
65
66
  /**
66
67
  * Initialize and start AR tracking
67
68
  */
@@ -1,4 +1,5 @@
1
1
  import { Controller } from "./controller.js";
2
+ import { OneEuroFilter } from "../libs/one-euro-filter.js";
2
3
  /**
3
4
  * 🍦 SimpleAR - Dead-simple vanilla AR for image overlays
4
5
  *
@@ -41,6 +42,7 @@ class SimpleAR {
41
42
  this.controller = null;
42
43
  this.isTracking = false;
43
44
  this.lastMatrix = null;
45
+ this.filters = []; // One filter per target
44
46
  }
45
47
  /**
46
48
  * Initialize and start AR tracking
@@ -126,13 +128,31 @@ class SimpleAR {
126
128
  this.onFound && this.onFound({ targetIndex });
127
129
  }
128
130
  this.lastMatrix = worldMatrix;
129
- this._positionOverlay(modelViewTransform, targetIndex);
131
+ // Smooth the tracking data if filters are initialized
132
+ if (!this.filters[targetIndex]) {
133
+ this.filters[targetIndex] = new OneEuroFilter({ minCutOff: 0.1, beta: 0.01 });
134
+ }
135
+ // Flatten mVT for filtering (3x4 matrix = 12 values)
136
+ const flatMVT = [
137
+ mVT[0][0], mVT[0][1], mVT[0][2], mVT[0][3],
138
+ mVT[1][0], mVT[1][1], mVT[1][2], mVT[1][3],
139
+ mVT[2][0], mVT[2][1], mVT[2][2], mVT[2][3]
140
+ ];
141
+ const smoothedFlat = this.filters[targetIndex].filter(Date.now(), flatMVT);
142
+ const smoothedMVT = [
143
+ [smoothedFlat[0], smoothedFlat[1], smoothedFlat[2], smoothedFlat[3]],
144
+ [smoothedFlat[4], smoothedFlat[5], smoothedFlat[6], smoothedFlat[7]],
145
+ [smoothedFlat[8], smoothedFlat[9], smoothedFlat[10], smoothedFlat[11]]
146
+ ];
147
+ this._positionOverlay(smoothedMVT, targetIndex);
130
148
  this.onUpdateCallback && this.onUpdateCallback({ targetIndex, worldMatrix });
131
149
  }
132
150
  else {
133
151
  // Target lost
134
152
  if (this.isTracking) {
135
153
  this.isTracking = false;
154
+ if (this.filters[targetIndex])
155
+ this.filters[targetIndex].reset();
136
156
  this.overlay && (this.overlay.style.opacity = '0');
137
157
  this.onLost && this.onLost({ targetIndex });
138
158
  }
@@ -174,13 +194,20 @@ class SimpleAR {
174
194
  console.log('Rotated Angle:', (rotation * 180 / Math.PI).toFixed(1), 'deg');
175
195
  console.log('Final Scale:', finalScale.toFixed(4));
176
196
  }
177
- // Apply
197
+ // Apply styles to prevent CSS interference (like max-width: 100%)
198
+ this.overlay.style.maxWidth = 'none';
199
+ this.overlay.style.maxHeight = 'none';
178
200
  this.overlay.style.width = `${markerW}px`;
179
- this.overlay.style.height = 'auto'; // Maintain aspect ratio of the overlay asset
201
+ this.overlay.style.height = 'auto'; // Maintain aspect ratio if user has a custom overlay
180
202
  this.overlay.style.position = 'absolute';
181
203
  this.overlay.style.transformOrigin = 'center center';
204
+ this.overlay.style.display = 'block';
205
+ this.overlay.style.margin = '0';
182
206
  this.overlay.style.left = '0';
183
207
  this.overlay.style.top = '0';
208
+ // Apply final transform
209
+ // We use translate to move the center of the elements to 0,0
210
+ // Then apply our calculated screen position
184
211
  this.overlay.style.transform = `
185
212
  translate(${screenX}px, ${screenY}px)
186
213
  translate(-50%, -50%)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srsergio/taptapp-ar",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "description": "AR Compiler for Node.js and Browser",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,5 @@
1
1
  import { Controller } from "./controller.js";
2
+ import { OneEuroFilter } from "../libs/one-euro-filter.js";
2
3
 
3
4
  /**
4
5
  * 🍦 SimpleAR - Dead-simple vanilla AR for image overlays
@@ -51,6 +52,7 @@ class SimpleAR {
51
52
  this.controller = null;
52
53
  this.isTracking = false;
53
54
  this.lastMatrix = null;
55
+ this.filters = []; // One filter per target
54
56
  }
55
57
 
56
58
  /**
@@ -149,13 +151,33 @@ class SimpleAR {
149
151
  }
150
152
 
151
153
  this.lastMatrix = worldMatrix;
152
- this._positionOverlay(modelViewTransform, targetIndex);
154
+
155
+ // Smooth the tracking data if filters are initialized
156
+ if (!this.filters[targetIndex]) {
157
+ this.filters[targetIndex] = new OneEuroFilter({ minCutOff: 0.1, beta: 0.01 });
158
+ }
159
+
160
+ // Flatten mVT for filtering (3x4 matrix = 12 values)
161
+ const flatMVT = [
162
+ mVT[0][0], mVT[0][1], mVT[0][2], mVT[0][3],
163
+ mVT[1][0], mVT[1][1], mVT[1][2], mVT[1][3],
164
+ mVT[2][0], mVT[2][1], mVT[2][2], mVT[2][3]
165
+ ];
166
+ const smoothedFlat = this.filters[targetIndex].filter(Date.now(), flatMVT);
167
+ const smoothedMVT = [
168
+ [smoothedFlat[0], smoothedFlat[1], smoothedFlat[2], smoothedFlat[3]],
169
+ [smoothedFlat[4], smoothedFlat[5], smoothedFlat[6], smoothedFlat[7]],
170
+ [smoothedFlat[8], smoothedFlat[9], smoothedFlat[10], smoothedFlat[11]]
171
+ ];
172
+
173
+ this._positionOverlay(smoothedMVT, targetIndex);
153
174
  this.onUpdateCallback && this.onUpdateCallback({ targetIndex, worldMatrix });
154
175
 
155
176
  } else {
156
177
  // Target lost
157
178
  if (this.isTracking) {
158
179
  this.isTracking = false;
180
+ if (this.filters[targetIndex]) this.filters[targetIndex].reset();
159
181
  this.overlay && (this.overlay.style.opacity = '0');
160
182
  this.onLost && this.onLost({ targetIndex });
161
183
  }
@@ -207,13 +229,21 @@ class SimpleAR {
207
229
  console.log('Final Scale:', finalScale.toFixed(4));
208
230
  }
209
231
 
210
- // Apply
232
+ // Apply styles to prevent CSS interference (like max-width: 100%)
233
+ this.overlay.style.maxWidth = 'none';
234
+ this.overlay.style.maxHeight = 'none';
211
235
  this.overlay.style.width = `${markerW}px`;
212
- this.overlay.style.height = 'auto'; // Maintain aspect ratio of the overlay asset
236
+ this.overlay.style.height = 'auto'; // Maintain aspect ratio if user has a custom overlay
213
237
  this.overlay.style.position = 'absolute';
214
238
  this.overlay.style.transformOrigin = 'center center';
239
+ this.overlay.style.display = 'block';
240
+ this.overlay.style.margin = '0';
215
241
  this.overlay.style.left = '0';
216
242
  this.overlay.style.top = '0';
243
+
244
+ // Apply final transform
245
+ // We use translate to move the center of the elements to 0,0
246
+ // Then apply our calculated screen position
217
247
  this.overlay.style.transform = `
218
248
  translate(${screenX}px, ${screenY}px)
219
249
  translate(-50%, -50%)