{"id":19614326,"url":"https://github.com/fpapado/pingpong","last_synced_at":"2026-06-10T06:46:56.744Z","repository":{"id":96505046,"uuid":"110718222","full_name":"fpapado/pingpong","owner":"fpapado","description":null,"archived":false,"fork":false,"pushed_at":"2017-11-26T14:54:32.000Z","size":254,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-26T17:47:52.306Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fpapado.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-14T16:49:41.000Z","updated_at":"2017-11-26T14:48:37.000Z","dependencies_parsed_at":"2023-05-02T10:50:09.315Z","dependency_job_id":null,"html_url":"https://github.com/fpapado/pingpong","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fpapado/pingpong","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fpapado%2Fpingpong","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fpapado%2Fpingpong/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fpapado%2Fpingpong/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fpapado%2Fpingpong/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fpapado","download_url":"https://codeload.github.com/fpapado/pingpong/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fpapado%2Fpingpong/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34140774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T10:51:11.671Z","updated_at":"2026-06-10T06:46:56.726Z","avatar_url":"https://github.com/fpapado.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pingpong\nPingpong is my playground for trying out web APIs. You might find something interesting here :)\n\nCurrently playing with:\n- The DeviceOrientation and Geolocation APIs\n\nNext on the list:\n- Push and Notification APIs\n\n## Notes\n### Absolute Orientation\nI used `DeviceOrientation` in order to make a compass, with both an absolute and a custom bearing.\n\nGetting absolute orientation (i.e. to the north pole) turned out to be a bit of a pain.\nDespite what `DeviceOrientationEvent` specifies, `DeviceOrientationEvent.absolute` was never `true` in my tests (Chrome, Firefox).\n\nAs of version 50, Chrome uses a new `deviceorientationabsolute` event, to get absolute orientation.\nThis is because of VR/AR needs for relative orientation in `deviceorientation`.\nThis seems to be in the specification now, but Firefox does not have it.\n\nSafari (Webkit), has its own property for compass heading, `DeviceOrientationEvent.webkitCompassHeading`.\nI do not have a device to play with this, but if you have any suggestsions, I will happily take PRs!\n\nTo get the absolute orientation, I would thus suggest:\n```typescript\n// Check if Chrome post-v50 event is available\nif ('ondeviceorientationabsolute' in window) {\n  window.addEventListener(\n    'deviceorientationabsolute',\n    (ev: DeviceOrientationEvent) =\u003e {\n      // do something with ev here\n    }\n  );\n} else {\n  window.addEventListener(\n    'deviceorientation',\n    (ev: DeviceOrientationEvent) =\u003e {\n      // Check if Webkit-specific property\n      if (ev.webkitCompassHeading) {\n        // do something with ev here\n        // NOTE: might have to normalise values\n        // I have not tested this, as I don't have Safari\n      } else if (ev.absolute) {\n        // do something with ev here\n      // Usually Firefox gets here\n      } else {\n        // We don't have easy absolute values\n        // Choose to error, cry, or figure them out via movement\n      }\n    }\n  );\n```\n\n### `Coordinates.heading`\nAnother thought I had was using `Coordinates.heading` to get the orientation, and adjust form there.\n\nIt is described as:\n\"\nThe Coordinates.heading read-only property is a double representing the direction in which the device is traveling. This value, specified in degrees, indicates how far off from heading due north the device is. Zero degrees represents true true north, and the direction is determined clockwise (which means that east is 90 degrees and west is 270 degrees). If Coordinates.speed is 0, heading is NaN. If the device is not able to provide heading information, this value is null.\n\"\n\nDespite the \"Browser Compatibility\" in mdn indicating that Chrome and Firefox on mobile support it, I could not get values other than `null` and `NaN` out of it, but maybe I was not moving sufficiently.\n\nIn either case, I would prefer using an absolute `DeviceOrientation`, before resorting to `Coordinates.heading`, as it doesn't require (possibly more power-hungry) Geolocation.\n\n### Manual Heading\n**NOTE: Unsure of this**\n\nI recon you could calculate heading manually with just Geolocation:\n- Calculate the `Coordinates.latitude, Coordinate.longitude` bearing to True North (0, 90)\n- Instruct the user to move (much like Geolocation.heading)\n- Calculate the difference between the previous and current position with respect to the bearing\n\n#### Resources:\n\nDeviceOrientation:\n- https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent\n- https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Orientation_and_motion_data_explained\n\nChrome changes to DeviceOrientation in v50:\n- https://developers.google.com/web/updates/2016/03/device-orientation-changes\n\nSpec:\n- https://w3c.github.io/deviceorientation/spec-source-orientation.html#deviceorientationabsolute\n\nCoordinates Heading:\n- https://developer.mozilla.org/en-US/docs/Web/API/Coordinates/heading\n- https://dev.w3.org/geo/api/spec-source.html#heading\n\n### Streams\n**WIP**\n\nI found wrapping these APIs in streams to be particularly pleasant both for further use and calculating derived, normalised state.\n\n## CLI Commands\n\n``` bash\n# install dependencies\nnpm install\n\n# serve with hot reload at localhost:8080\nnpm run dev\n\n# build for production with minification\nnpm run build\n\n# test the production build locally\nnpm run serve\n```\n\nFor detailed explanation on how things work, checkout the [Preact CLI Readme](https://github.com/developit/preact-cli/blob/master/README.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffpapado%2Fpingpong","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffpapado%2Fpingpong","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffpapado%2Fpingpong/lists"}