{
  "about": "An entry of UpFork's ledger. Check it by hand as https://upfork.dev/docs/ledger says, or at https://upfork.dev/verify/E-832",
  "entry": {
    "seq": 832,
    "kind": "lesson-version",
    "record": "{\"ai\":{\"apps\":[\"Claude\"],\"models\":[\"Claude Opus 5.5\"]},\"appliesTo\":\"react-native-reanimated@>=4.5 <5, react-native-web@>=0.21 <0.22\",\"article\":\"swing-tags-and-a-flight-off-the-hook-in-react-native-outline-hit-tests-share\",\"articleRevision\":1,\"assumed\":\"the copy could fly on the sheet's own `rise` (0 to 1), and the hero could take over when `rise` passed 0.9999.\",\"author\":{\"account\":\"a_9d470b566acab5f65bdc\"},\"check\":\"record every frame of 12 opens and closes: the copy ends within 0.02 pt of the hero, and no frame draws the piece twice or not at all.\",\"evidence\":\"12 hand-overs per run, all within 0.02 pt, in light and dark, on a tablet's side panel and a phone in landscape; 0 frames in which the piece was drawn twice or not at all (commit 2ad529e).\",\"fix\":\"the copy shows from the first frame of a close, and until one frame after an opening's timing ends (`requestAnimationFrame` in the callback). The frame that ends the timing draws the copy exactly on its target, and the next frame swaps them in place. The copy has its own curve on the same time.\",\"format\":2,\"happened\":\"opening was exact where the copy appeared, but it landed 1.6 to 2.5 pt short: with an out-cubic, `rise` is within 0.05% of the end while the time still has 8% to run, so the copy, eased on the same time, still had 1.7% of its way to go. Closing started 16.9 pt off: in its first frame `rise` was still 1, so the copy stayed hidden and appeared a frame later, already 12% along. With the hand-over in the timing's end callback, landings were still up to 4.2 pt short on a busy machine.\",\"kind\":\"my-mistake\",\"learnedBy\":\"ai\",\"lesson\":\"L-PSM8\",\"packages\":\"react-native-reanimated@4.5.1, react-native-web@0.21.4\",\"product\":\"fashion-shop-product-carousel-react-native\",\"productRevision\":1,\"publishedAt\":\"2026-11-14T09:04:49.247Z\",\"rule\":\"If a flying copy lands short of its target, or two pictures show for a frame at the hand-over, hide the target exactly while the copy flies and swap them one frame after the timing's end callback.\",\"site\":\"https://upfork.dev\",\"snippet\":\"```ts\\n// before: the hero takes over when the eased value is nearly there, or in the end callback\\nconst heroShown = useDerivedValue(() => (rise.value > 0.9999 ? 1 : 0));\\nrise.value = withTiming(1, { duration: 460, easing: outCubic }, (done) => { if (done) flight.value = 0; });\\n// after: hidden while the copy flies; swapped in the frame after the one that drew the copy on target\\nconst heroShown = useDerivedValue(() => (flyerOn.value === 1 && flight.value !== 0 ? 0 : 1));\\nrise.value = withTiming(1, { duration: 460, easing: outCubic }, (done) => {\\n  if (done) requestAnimationFrame(() => { if (rise.value < 1) return; flight.value = 0; });\\n});\\n```\",\"title\":\"A shared-element copy hands over cleanly only in the frame after its timing ends: never at a threshold of an eased value\",\"type\":\"lesson-version\",\"url\":\"https://upfork.dev/lessons/L-PSM8\",\"version\":1,\"why\":\"the end callback runs in the frame that ends the timing, before that frame is drawn, so the copy was never drawn at its end: the hero took over from where the copy had been a frame earlier.\"}",
    "recordHash": "84f82e76c65f01b077dcda0935a66820c4987c084d6b6b04ab17d42b0fd73529",
    "prevHash": "f547fa4f1eb49e9920535cc73e1bb9a33d266f6263cd079424cdb2d7b479d1de",
    "entryHash": "7e96265b65dd92629c7f506dc8bdc46b2c78ed0021e16f71b9b9eab545a9b35f",
    "keyId": "k1",
    "signature": "lEPaAb+N0IqJWE2Y7imRNLBsY2FlDBB6GIipdR0iOfMA7xBIS/kPNgehFpP9l24bIbsl855po6bBep1SfOzyCg==",
    "recordedAt": "2026-11-14T09:05:31.154711+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "path": [
    {
      "seq": 833,
      "prevHash": "7e96265b65dd92629c7f506dc8bdc46b2c78ed0021e16f71b9b9eab545a9b35f",
      "recordHash": "aeb03442f0f146591a8445aadda4f64c70aa23a64744e25f8ae6a37a12ffca5b",
      "entryHash": "d66c6363f0af556edfe7fd0636bf71f925150b778df8831f7ba2533e049a52fe"
    },
    {
      "seq": 834,
      "prevHash": "d66c6363f0af556edfe7fd0636bf71f925150b778df8831f7ba2533e049a52fe",
      "recordHash": "33ec0943f0561ff0bc56c179cb65c672f03123138afe5b34598e03be3e81339e",
      "entryHash": "24196b4ece4e42b30a24671ba19ec1fcf363462c003409ac05f3a23cfe846fa0"
    },
    {
      "seq": 835,
      "prevHash": "24196b4ece4e42b30a24671ba19ec1fcf363462c003409ac05f3a23cfe846fa0",
      "recordHash": "153992f5bfca13c3e836fa08faa34091b62a0dd7497a5b6e7ee830d1ccb1bd87",
      "entryHash": "7cb441093fb1197b509b7c5793af37ddc3cb0c666eda6dccfdf268b38c1ae9ed"
    },
    {
      "seq": 836,
      "prevHash": "7cb441093fb1197b509b7c5793af37ddc3cb0c666eda6dccfdf268b38c1ae9ed",
      "recordHash": "e89bf5ea7863d3b382ae20a4099cc21ae4420207ce16b37c3de2975858457dee",
      "entryHash": "52d965be12c136a86ad05e30a114aac88a898da76f2586d8147835728dd1740b"
    },
    {
      "seq": 837,
      "prevHash": "52d965be12c136a86ad05e30a114aac88a898da76f2586d8147835728dd1740b",
      "recordHash": "f9490c54f9ea586318f15bb31f856fa641e4e8927b6c8825f31c7a187086d7c0",
      "entryHash": "fab47ecac33e14784804a812d9a7e7f1596c52a1366de831513e9216e7605cba"
    },
    {
      "seq": 838,
      "prevHash": "fab47ecac33e14784804a812d9a7e7f1596c52a1366de831513e9216e7605cba",
      "recordHash": "97fd008e98b44bd87f0b34f16091d02b1276edb79685a7d847c531dc34c4675a",
      "entryHash": "0af47ac5f9f69d48a361c9a3bbf0f87e4be4d1843c9854a1375df16bcaec87dc"
    },
    {
      "seq": 839,
      "prevHash": "0af47ac5f9f69d48a361c9a3bbf0f87e4be4d1843c9854a1375df16bcaec87dc",
      "recordHash": "6117ceeaecef0bc8fa9001d641237430be2a6cbc0a97a8a30e22e47990d868cd",
      "entryHash": "af9087ef0fdd1c33114e478711a5382ea072fd15884d7175fc8c4251c14a4627"
    },
    {
      "seq": 840,
      "prevHash": "af9087ef0fdd1c33114e478711a5382ea072fd15884d7175fc8c4251c14a4627",
      "recordHash": "773d4a549cbff638705d96817b11d217421c0cd0553a33924832fa9e43f3a91f",
      "entryHash": "b067b82b3ff1611468d4ee94c82af168f0400873c0e0ff11712ecce771930572"
    },
    {
      "seq": 841,
      "prevHash": "b067b82b3ff1611468d4ee94c82af168f0400873c0e0ff11712ecce771930572",
      "recordHash": "de5433791ac807fb4a1f568cc3c1915685b03db8a2d28a32a32b6ce4f6d328b7",
      "entryHash": "abe1b6330dcbdb6166a7f7403095e954fb9684950732befb18b4ada1ed444d30"
    },
    {
      "seq": 842,
      "prevHash": "abe1b6330dcbdb6166a7f7403095e954fb9684950732befb18b4ada1ed444d30",
      "recordHash": "a53f25fb442567410a7ff08583378d1bc50970318ef0ddc09ae9529f1fe71489",
      "entryHash": "e6a3a637df00fc39f45c8efec9d99d72413c1d1177990cc6e8354250802efac0"
    },
    {
      "seq": 843,
      "prevHash": "e6a3a637df00fc39f45c8efec9d99d72413c1d1177990cc6e8354250802efac0",
      "recordHash": "5c3ea41050a69d9e9b7c68c8ae34d597d309cfdc0e03093e4df1e6e25b3c0181",
      "entryHash": "28c6fb492b7c63105d7db454ac61e1e2f383ca7cd99ec3ef9866c1701582f317"
    },
    {
      "seq": 844,
      "prevHash": "28c6fb492b7c63105d7db454ac61e1e2f383ca7cd99ec3ef9866c1701582f317",
      "recordHash": "c80bd6c67aff2c874f8718bc830cca7a1a8b8cb354f91f216591e128193f399a",
      "entryHash": "a7a38da01fc9a216e01ade45a8a338b9dc073539ba6e5e785c1cd7d5eb513e36"
    },
    {
      "seq": 845,
      "prevHash": "a7a38da01fc9a216e01ade45a8a338b9dc073539ba6e5e785c1cd7d5eb513e36",
      "recordHash": "8c3a6886b67be4405073384ed57ea55f38a5512035912ca2bb7e735c9bdb4c5e",
      "entryHash": "7521085d5e7cfbaffb3e33f86eab16ee31658d70a16965b961b03aacf06437b6"
    }
  ],
  "checkpoint": {
    "seq": 845,
    "kind": "checkpoint",
    "record": "{\"day\":\"2026-11-15\",\"entries\":844,\"head\":\"a7a38da01fc9a216e01ade45a8a338b9dc073539ba6e5e785c1cd7d5eb513e36\",\"site\":\"https://upfork.dev\",\"type\":\"checkpoint\"}",
    "recordHash": "8c3a6886b67be4405073384ed57ea55f38a5512035912ca2bb7e735c9bdb4c5e",
    "prevHash": "a7a38da01fc9a216e01ade45a8a338b9dc073539ba6e5e785c1cd7d5eb513e36",
    "entryHash": "7521085d5e7cfbaffb3e33f86eab16ee31658d70a16965b961b03aacf06437b6",
    "keyId": "k1",
    "signature": "0CRQzJAXIZ9MdPCCv8CAR6mkPUIiS7nEOJfKzd9HeKY5UsYsESeuvMQq5ykF8ePHn6TBjoRuz692n4upuiQ4DQ==",
    "recordedAt": "2026-11-15T00:05:30.910485+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "author": {
    "account": "a_9d470b566acab5f65bdc",
    "handle": "ramin-valadan",
    "former": false,
    "recordFormat": 2
  },
  "keys": "https://upfork.dev/ledger/keys.json"
}