{"id":14961365,"url":"https://github.com/pinyin/tween-here","last_synced_at":"2025-10-24T20:31:38.946Z","repository":{"id":57136892,"uuid":"131495275","full_name":"pinyin/tween-here","owner":"pinyin","description":"An UI animation library designed for modern JS frameworks.","archived":false,"fork":false,"pushed_at":"2018-07-24T10:32:23.000Z","size":230,"stargazers_count":26,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-30T00:05:39.404Z","etag":null,"topics":["animation","animation-library","material-design","motion","tween"],"latest_commit_sha":null,"homepage":"http://pinyin.github.io/tween-here","language":"TypeScript","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/pinyin.png","metadata":{"files":{"readme":"README.cn.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}},"created_at":"2018-04-29T13:07:05.000Z","updated_at":"2019-08-02T14:33:56.000Z","dependencies_parsed_at":"2022-09-01T03:00:47.624Z","dependency_job_id":null,"html_url":"https://github.com/pinyin/tween-here","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinyin%2Ftween-here","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinyin%2Ftween-here/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinyin%2Ftween-here/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinyin%2Ftween-here/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pinyin","download_url":"https://codeload.github.com/pinyin/tween-here/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237860066,"owners_count":19377696,"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":["animation","animation-library","material-design","motion","tween"],"created_at":"2024-09-24T13:24:54.421Z","updated_at":"2025-10-24T20:31:33.497Z","avatar_url":"https://github.com/pinyin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# TweenHere\n\n[![Build Status](https://travis-ci.org/pinyin/tween-here.svg?branch=master)](https://travis-ci.org/pinyin/tween-here)\n\n为现代JS框架设计的动画方案\n\n[查看Demo (最好在大屏设备上打开)](http://pinyin.github.io/tween-here)\n\n[Open README in English](./README.md)\n\n## 安装\n\n`npm install --save tween-here`\n\n已经包含了TypeScript支持。\n\n## 用法\n\nTweenHere是为UI动画设计的。\n\n例如，如果想在滚动时实现动画效果：\n\n```html\n\u003cdiv style=\"overflow-y: scroll\"\u003e // scroll container element\n    \u003cdiv id=\"content\"\u003e // content element\n    // ... elements\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n首先，你需要像之前一样，调节容器的滚动位置：\n```\ncontainer.scrollTo = 100\n```\n滚动内容会跳动到新位置。怎样让这个过程变得平滑呢？\n\n有了TweenHere，你可以用三行代码解决这个问题：\n```\nconst content = document.getElementById('content')\nconst snapshot = getTweenState() // get position of scrolled content\ncontainer.scrollTop = 100\ntweenHere(content, snapshot) // content will move to its new position smoothly \n```\n\n... 这个简单的API可以实现很多其他动画效果。\n\n所有的动画都是用[FLIP技巧](https://aerotwist.com/blog/flip-your-animations/)实现的，所以性能比较好。\n\n## 设计目标\n\n[动画很重要](https://material.io/guidelines/motion/material-motion.html#material-motion-why-does-motion-matter)。\n\n但动画很难实现。\n\n我们已经有了很多优秀简洁的方案, 例如 [Popmotion](https://popmotion.io/) 和 [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API)。但是，有些时候，即使这些简洁的方案也显得过于复杂。\n\n\u003e “这里加个动画吧，应该挺简单的” - 你的产品经理\n\n这就是`TweenHere`的设计目标: UI动画。它并不想成为一个完整的动画库, 但你应该可以通过它实现大部分UI动画 (例如[Material Design](https://material.io/guidelines/motion/material-motion.html)里的那些)。\n\n在`TweenHere`中，动画被定义为“一个元素如何到达它的当前位置”而不是“从一个位置运动到另一个位置”， 所以它应该可以支持大部分JS框架: 只要你可以获得DOM元素的引用，就可以动画这个DOM元素\n\n## 用法\n\n`TweenHere` 提供两个函数，`tweenHere`和`tweenExit`，每个函数实现一类动画。 \n\n```typescript jsx\n\nasync function tweenHere(\n    element: HTMLElement,\n    from: TweenState | ((snapshot: TweenState, to: TweenState) =\u003e TweenState),\n    params?: {\n        duration?: number | ((from: TweenState, to: TweenState) =\u003e number),\n        easing?: [number, number, number, number],\n        fixed?: boolean,\n    }\n): Promise\u003cvoid\u003e \n\nasync function tweenExit(\n    element: HTMLElement,\n    to: TweenState | ((from: TweenState) =\u003e TweenState),\n    params?: {\n        duration?: number | ((from: TweenState, to: TweenState) =\u003e number),\n        easing?: [number, number, number, number],\n        container?: Element,\n        fixed?: boolean,\n    }\n): Promise\u003cvoid\u003e \n```\n\n每个函数都只有前两个参数是必须的。\n\nTweenState是代表元素位置的一个对象(相对视图窗口):\n```typescript jsx\ntype TweenState = {\n    x: number\n    y: number\n    width: number\n    height: number\n    opacity: number\n} \n```\n你可以通过`getBoundingClientRect()`和其他API手动计算出这些值。 \n\n方便起见，也可以通过调用`getTweenState`来获得一个DOM元素的这些值。\n\n```typescript jsx\ngetTweenState(element: HTMLElement): TweenState\n```\n[通过把这个函数的返回值传递给`tweenHere`](demo/OpenListItem.tsx)，你可以轻松让一个元素从另一个元素的位置平滑出现，从而创造出这两个元素是同一个元素的视觉效果。\n\n\n总之，如果你希望一个元素平滑过渡到它的当前位置，使用`tweenHere`。如果你希望一个元素平滑地消失，使用`tweenExit`。\n\n## 特点\n\n使用FLIP技巧保持动画过程中的FPS\n\n把对DOM的读写操作统一调度在microtask中，因此可以随时开始动画，不必担心触发reflow。\n\n## 限制\n\n被动画的元素的`transform` `opacity`和`transition`属性会被覆盖。\n\n`tweenExit`在动画过程中会向DOM中添加元素，因此可能对特定的CSS样式产生影响。\n\n这个库仍然在早期阶段，如果注意到不希望的行为，请报告issue。\n\n需要运行时支持WeakMap、Set和MutationObserver。Polyfill也可以。\n\n## 计划\n\n增加文档。\n\n支持旋转。\n\n增加更多的[Demo](http://pinyin.github.io/tween-here)。\n\n增加React/Angular/Vue的绑定。\n\n## 类似的项目和文章\n\n[FLIP Technique](https://aerotwist.com/blog/flip-your-animations/)\n\n[react-flip-move](https://github.com/joshwcomeau/react-flip-move)\n\n[Flipping](https://github.com/davidkpiano/flipping)\n\n[react-flip-toolkit](https://github.com/aholachek/react-flip-toolkit)\n\n## 授权\n\nMIT\n\n欢迎任何贡献\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpinyin%2Ftween-here","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpinyin%2Ftween-here","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpinyin%2Ftween-here/lists"}