{"id":14990198,"url":"https://github.com/captaincodeman/gif-player","last_synced_at":"2025-04-12T02:06:04.256Z","repository":{"id":66357871,"uuid":"97191352","full_name":"CaptainCodeman/gif-player","owner":"CaptainCodeman","description":"Control your animated GIFs","archived":false,"fork":false,"pushed_at":"2018-04-25T12:46:11.000Z","size":2011,"stargazers_count":143,"open_issues_count":3,"forks_count":14,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-12T02:05:59.080Z","etag":null,"topics":["custom-element","gif","gif-animation","webcomponent"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CaptainCodeman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-07-14T03:59:38.000Z","updated_at":"2025-02-18T10:44:01.000Z","dependencies_parsed_at":"2023-02-22T03:45:14.120Z","dependency_job_id":null,"html_url":"https://github.com/CaptainCodeman/gif-player","commit_stats":{"total_commits":12,"total_committers":2,"mean_commits":6.0,"dds":0.08333333333333337,"last_synced_commit":"54234731e58c579eda454bd5fb52eb453bd5abe5"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCodeman%2Fgif-player","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCodeman%2Fgif-player/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCodeman%2Fgif-player/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaptainCodeman%2Fgif-player/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CaptainCodeman","download_url":"https://codeload.github.com/CaptainCodeman/gif-player/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248505862,"owners_count":21115354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["custom-element","gif","gif-animation","webcomponent"],"created_at":"2024-09-24T14:19:41.706Z","updated_at":"2025-04-12T02:06:04.233Z","avatar_url":"https://github.com/CaptainCodeman.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/captaincodeman/gif-player)\n  \n[![Published on Vaadin  Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/CaptainCodemangif-player)\n[![Stars on vaadin.com/directory](https://img.shields.io/vaadin-directory/star/CaptainCodemangif-player.svg)](https://vaadin.com/directory/component/CaptainCodemangif-player)\n  \n\n# \\\u003cgif-player\\\u003e\n\nWebComponent to control Animated GIF playback and access individual frames.\n\n[More demos](https://captaincodeman.github.io/gif-player/components/gif-player/demo/)\n\nMove your mouse over the images ...\n\u003c!--\n```\n\u003ccustom-element-demo\u003e\n  \u003ctemplate\u003e\n    \u003cscript src=\"../webcomponentsjs/webcomponents-loader.js\"\u003e\u003c/script\u003e\n    \u003clink rel=\"import\" href=\"gif-player.html\"\u003e\n    \u003cnext-code-block\u003e\u003c/next-code-block\u003e\n  \u003c/template\u003e\n\u003c/custom-element-demo\u003e\n```\n--\u003e\n```html\n\u003cgif-player src=\"https://media.giphy.com/media/TN0GTccRi7Ixa/giphy.gif\" speed=\"0.5\" play\u003e\u003c/gif-player\u003e\n\u003cgif-player src=\"https://media.giphy.com/media/nh5QMbO89SFTG/giphy.gif\" size=\"contain\" prerender style=\"width:300px;height:200px\"\u003e\u003c/gif-player\u003e\n```\n\nThis was inspired by [x-gif](http://geelen.github.io/x-gif/) but designed to work with the latest WebComponents v1 spec and fix some issues with playback of certain gifs. It uses the excellent [GifReader from omggif](https://github.com/deanm/omggif) for decoding.\n\n## Features:\n\n* Pure v1 WebComponent, approximately 4.5Kb gzipped\n* In-built (simple) loading spinner (because some GIFs are large)\n* Auto-start playback on load or pause at any frame relative to the start or end\n* Control playback speed relative to original GIF settings\n* Control frame displayed by mouseover / touch (based on horizontal position across the image)\n* Pre-render frames in idle time* (even if animation is not playing)\n\nDue to the way animated gifs are encoded and rendered, it's not always possible to jump directly to a specific frame to display it - some of the image may be transparent and rely on pixels from previous frames to render correctly (called 'disposal' in the GIF spec). So if we want to render the _last_ frame in the image, we may need to render all the previous ones first. The pre-rendering option allows this to happen in browser idle-time so that they are ready in advance (but is configurable). Frames are always automatically rendered as they are required during playback or UI interaction but there may be a slight delay depending on the size and complexity of the GIF.\n\n## Properties:\n\n`src=\"url\"` sets the source URL for the image, just like with the `\u003cimg\u003e` element. DataURIs and regular URLs should work but the latter need to provide CORS headers if being used from a different domain. Imgur and Giphy both seem to work fine and are used in the demos.\n\n`size=\"auto\"` set to control the sizing. Options are `auto` (the control resizes to the size of the GIF image), `cover` or `contain` (as per `object-fit` or `background-size` CSS properties) or `stretch` to fill the control (may distort the GIF). The control must be explicitly sized for any option other than `auto`.\n\n`frame=\"0\"` set the frame to display relative to the start of the animation, use negative numbers to make the frame relative to the end, so `frame=\"-1\"` would display the _last_ frame.\n\n`play` set to auto play the GIF on load\n\n`speed=\"2\"` set the playback speed relative to the original GIF encoding. A value of 0.5 would playback in slow-motion at half speed whereas 2 would double the speed for faster playback (will always depending on the performance capability of the client device).\n\n`repeat` set to repeat playback on completion, otherwise stop\n\n`bounce` set to reverse playback direction at the start or end of the animation rather than restarting.\n\n`direction=\"1\"` set the direction to play with 1 being forwards and -1 being reverse.\n\n`prerender` set to use browser idle time to pre-render frames instead of rendering on demand.\n\nExample, fit GIF in a 240 x 160 area, play it continually and reverse direction at either end:\n\n```html\n\u003cgif-player src=\"my.gif\" size=\"contain\" play bounce style=\"width: 240px; height: 160px;\"\u003e\u003c/gif-player\u003e\n```\n\n## TODOs\n\nIt's not fully finished yet but it works pretty well for what I needed. Here are things I'm thinking should be added:\n\n* Alternative playback control - play / pause button to start \u0026 stop (or hold to play)\n* Use better rAF loop for rendering \u0026 timing of playback based on elapsed time.\n* Offload decoding work to service workers / offscreen canvas.\n* Fade-in images after loading and fade between frames to make display smoother.\n* Use IntersectionObserver to prevent playback while not on screen and also potentially unload some frames to reduce memory use.\n* Use streaming API to decode gif file as it loads so first frame can be displayed sooner.\n* Check disposal rules to determine exactly when retaining previous frame is required.\n* Make omggif a dependency and figure out how to make rollup remove the writer\n* Use css for cover / contain settings\n\nSave decoded data so it isn't decompressed for every frame\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaptaincodeman%2Fgif-player","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaptaincodeman%2Fgif-player","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaptaincodeman%2Fgif-player/lists"}