pxt-microbit 8.1.15 → 8.1.16

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.
package/built/sim.js CHANGED
@@ -4333,6 +4333,7 @@ path.sim-board {
4333
4333
  this.shakeInitialized = false;
4334
4334
  this.pinNmToCoord = {};
4335
4335
  this.domHardwareVersion = 1;
4336
+ this.bindings = [];
4336
4337
  this.moveHeadingOnClick = (ev) => {
4337
4338
  let pt = this.element.createSVGPoint();
4338
4339
  let cur = pxsim.svg.cursorPoint(pt, this.element, ev);
@@ -4390,6 +4391,10 @@ path.sim-board {
4390
4391
  });
4391
4392
  }
4392
4393
  removeEventListeners() {
4394
+ for (const binding of this.bindings) {
4395
+ const el = binding.element || document;
4396
+ el.removeEventListener(binding.event, binding.handler);
4397
+ }
4393
4398
  document.body.removeEventListener(pxsim.pointerEvents.down[0], this.moveHeadingOnClick);
4394
4399
  }
4395
4400
  updateTheme() {
@@ -4914,9 +4919,10 @@ path.sim-board {
4914
4919
  el.style.perspectiveOrigin = "50% 50% 50%";
4915
4920
  el.style.perspective = "30em";
4916
4921
  // don't display acc data when AB is on, v2 is on or soundLevel is on
4922
+ const soundLevelVisible = this.soundLevel.style.visibility == "visible";
4917
4923
  if (state.buttonPairState.usesButtonAB
4918
4924
  || this.v2Circle
4919
- || this.soundLevel) {
4925
+ || soundLevelVisible) {
4920
4926
  if (this.accTextX)
4921
4927
  this.accTextX.textContent = "";
4922
4928
  if (this.accTextY)
@@ -5267,49 +5273,116 @@ path.sim-board {
5267
5273
  }
5268
5274
  attachAccelerometerEvents() {
5269
5275
  let tiltDecayer = undefined;
5270
- this.element.addEventListener(pxsim.pointerEvents.move, (ev) => {
5271
- const state = this.board;
5272
- if (!state.accelerometerState.accelerometer.isActive)
5273
- return;
5274
- if (tiltDecayer) {
5275
- clearInterval(tiltDecayer);
5276
- tiltDecayer = 0;
5277
- }
5278
- const bbox = this.element.getBoundingClientRect();
5279
- // ev.clientX and ev.clientY are not defined on mobile iOS
5280
- const xPos = ev.clientX != null ? ev.clientX : ev.pageX;
5281
- const yPos = ev.clientY != null ? ev.clientY : ev.pageY;
5282
- const ax = (xPos - bbox.width / 2) / (bbox.width / 3);
5283
- const ay = (yPos - bbox.height / 2) / (bbox.height / 3);
5284
- const x = -Math.max(-1023, Math.min(1023, Math.floor(ax * 1023)));
5285
- const y = -Math.max(-1023, Math.min(1023, Math.floor(ay * 1023)));
5286
- const z2 = 1023 * 1023 - x * x - y * y;
5287
- const z = Math.floor((z2 > 0 ? -1 : 1) * Math.sqrt(Math.abs(z2)));
5288
- state.accelerometerState.accelerometer.update(x, y, z);
5289
- this.updateTilt();
5290
- }, false);
5291
- this.element.addEventListener(pxsim.pointerEvents.leave, (ev) => {
5292
- let state = this.board;
5293
- if (!state.accelerometerState.accelerometer.isActive)
5294
- return;
5276
+ const state = this.board;
5277
+ const startTiltDecay = () => {
5295
5278
  if (!tiltDecayer) {
5296
- tiltDecayer = setInterval(() => {
5279
+ const doDecay = () => {
5297
5280
  let accx = state.accelerometerState.accelerometer.getX(pxsim.MicroBitCoordinateSystem.RAW);
5298
5281
  accx = Math.floor(Math.abs(accx) * 0.85) * (accx > 0 ? 1 : -1);
5299
5282
  let accy = state.accelerometerState.accelerometer.getY(pxsim.MicroBitCoordinateSystem.RAW);
5300
5283
  accy = Math.floor(Math.abs(accy) * 0.85) * (accy > 0 ? 1 : -1);
5301
5284
  let accz = -Math.sqrt(Math.max(0, 1023 * 1023 - accx * accx - accy * accy));
5302
5285
  if (Math.abs(accx) <= 24 && Math.abs(accy) <= 24) {
5303
- clearInterval(tiltDecayer);
5286
+ cancelAnimationFrame(tiltDecayer);
5304
5287
  tiltDecayer = 0;
5305
5288
  accx = 0;
5306
5289
  accy = 0;
5307
5290
  accz = -1023;
5308
5291
  }
5292
+ else {
5293
+ tiltDecayer = requestAnimationFrame(doDecay);
5294
+ }
5309
5295
  state.accelerometerState.accelerometer.update(accx, accy, accz);
5310
5296
  this.updateTilt();
5311
- }, 50);
5297
+ };
5298
+ tiltDecayer = requestAnimationFrame(doDecay);
5299
+ }
5300
+ };
5301
+ const handleMove = (xPos, yPos, boardWidth, boardHeight) => {
5302
+ if (yPos > boardHeight || xPos < 0 || xPos > boardWidth) {
5303
+ startTiltDecay();
5304
+ return;
5305
+ }
5306
+ if (tiltDecayer) {
5307
+ cancelAnimationFrame(tiltDecayer);
5308
+ tiltDecayer = undefined;
5312
5309
  }
5310
+ const ax = (xPos - boardWidth / 2) / (boardWidth / 3);
5311
+ const ay = (yPos - boardHeight / 2) / (boardHeight / 3);
5312
+ const x = -Math.max(-1023, Math.min(1023, Math.floor(ax * 1023)));
5313
+ const y = -Math.max(-1023, Math.min(1023, Math.floor(ay * 1023)));
5314
+ const z2 = 1023 * 1023 - x * x - y * y;
5315
+ const z = Math.floor((z2 > 0 ? -1 : 1) * Math.sqrt(Math.abs(z2)));
5316
+ state.accelerometerState.accelerometer.update(x, y, z);
5317
+ this.updateTilt();
5318
+ };
5319
+ this.bindEvent(document, pxsim.pointerEvents.move, (ev) => {
5320
+ if (!state.accelerometerState.accelerometer.isActive)
5321
+ return;
5322
+ const boardElement = this.element;
5323
+ const parentSvg = this.findParentElement();
5324
+ const xPos = ev.clientX != null ? ev.clientX : ev.pageX;
5325
+ const yPos = ev.clientY != null ? ev.clientY : ev.pageY;
5326
+ // The outermost SVG has a transform applied to it to create the tilt
5327
+ // effect. In order to give us a constant bounding box to work with,
5328
+ // we want to calculate the pre-transform bounds of the board element
5329
+ // we can do this by comparing the aspect ratio of the page to the
5330
+ // viewbox of the board SVG, since it should always be maximized within
5331
+ // the page.
5332
+ const pageBounds = document.body.getBoundingClientRect();
5333
+ if (parentSvg && parentSvg !== this.element) {
5334
+ // If we are embedded in another SVG (e.g. the breadboard is present),
5335
+ // we need to do some extra work to find the bounding box of the board
5336
+ // element within the parent SVG.
5337
+ const parentViewBoxWidth = parentSvg.viewBox.baseVal.width;
5338
+ const parentViewBoxHeight = parentSvg.viewBox.baseVal.height;
5339
+ const aspectRatio = parentViewBoxWidth / parentViewBoxHeight;
5340
+ let parentWidth;
5341
+ let parentHeight;
5342
+ if (pageBounds.width / pageBounds.height > aspectRatio) {
5343
+ parentHeight = pageBounds.height;
5344
+ parentWidth = parentHeight * aspectRatio;
5345
+ }
5346
+ else {
5347
+ parentWidth = pageBounds.width;
5348
+ parentHeight = parentWidth / aspectRatio;
5349
+ }
5350
+ const parentLeft = pageBounds.left + (pageBounds.width - parentWidth) / 2;
5351
+ const parentTop = pageBounds.top + (pageBounds.height - parentHeight) / 2;
5352
+ const boardWidth = parseFloat(boardElement.getAttribute("width"));
5353
+ const boardHeight = parseFloat(boardElement.getAttribute("height"));
5354
+ const boardLeft = parseFloat(boardElement.getAttribute("x"));
5355
+ const boardTop = parseFloat(boardElement.getAttribute("y"));
5356
+ const boardPixelLeft = parentLeft + (boardLeft / parentViewBoxWidth) * parentWidth;
5357
+ const boardPixelTop = parentTop + (boardTop / parentViewBoxHeight) * parentHeight;
5358
+ const boardPixelWidth = (boardWidth / parentViewBoxWidth) * parentWidth;
5359
+ const boardPixelHeight = (boardHeight / parentViewBoxHeight) * parentHeight;
5360
+ handleMove(xPos - boardPixelLeft, yPos - boardPixelTop, boardPixelWidth, boardPixelHeight);
5361
+ }
5362
+ else {
5363
+ const boardViewboxWidth = this.element.viewBox.baseVal.width;
5364
+ const boardViewboxHeight = this.element.viewBox.baseVal.height;
5365
+ const aspectRatio = boardViewboxWidth / boardViewboxHeight;
5366
+ let boardWidth;
5367
+ let boardHeight;
5368
+ if (pageBounds.width / pageBounds.height > aspectRatio) {
5369
+ boardHeight = pageBounds.height;
5370
+ boardWidth = boardHeight * aspectRatio;
5371
+ }
5372
+ else {
5373
+ boardWidth = pageBounds.width;
5374
+ boardHeight = boardWidth / aspectRatio;
5375
+ }
5376
+ const boardLeft = pageBounds.left + (pageBounds.width - boardWidth) / 2;
5377
+ const boardTop = pageBounds.top + (pageBounds.height - boardHeight) / 2;
5378
+ handleMove(xPos - boardLeft, yPos - boardTop, boardWidth, boardHeight);
5379
+ }
5380
+ }, false);
5381
+ this.bindEvent(document, pxsim.pointerEvents.leave, (ev) => {
5382
+ let state = this.board;
5383
+ if (!state.accelerometerState.accelerometer.isActive)
5384
+ return;
5385
+ startTiltDecay();
5313
5386
  }, false);
5314
5387
  }
5315
5388
  attachPinsIOEvents() {
@@ -5504,6 +5577,10 @@ path.sim-board {
5504
5577
  attachKeyboardEvents() {
5505
5578
  pxsim.accessibility.postKeyboardEvent();
5506
5579
  }
5580
+ bindEvent(element, eventName, handler, ...rest) {
5581
+ element.addEventListener(eventName, handler, ...rest);
5582
+ this.bindings.push({ element, event: eventName, handler });
5583
+ }
5507
5584
  }
5508
5585
  visuals.MicrobitBoardSvg = MicrobitBoardSvg;
5509
5586
  const isHandledKey = (key) => {