使用Popmotion Tween实现仅返回唯一值的0-4计数器
The issue you're running into is that Popmotion's tween generates a continuous stream of values between your from and to ranges. When you pipe those values through Math.round, dozens of consecutive raw values will get rounded to the same integer—this is why you're seeing repeated logs of the same number.
Here are a few clean, straightforward ways to fix this, ensuring each integer from 0 to 4 is emitted exactly once:
Solution 1: Deduplicate Directly in the Tween Callback
The simplest approach is to track the last emitted value right in the start callback, and only call your addToList function when the value changes:
import { tween } from 'popmotion'; onHandleClick() { let lastValue = -1; // Initialize outside the 0-4 range to catch the first value (0) const twn = tween({ from: 0, to: 4 }).pipe(Math.round); twn.start((val) => { if (val !== lastValue) { lastValue = val; this.addToList(val); } }); } addToList(val) { console.log('val = ', val); }
Solution 2: Build Deduplication into the Pipe Chain
If you prefer to keep the tween logic self-contained, you can add a custom deduplication step to the pipe:
import { tween } from 'popmotion'; onHandleClick() { let lastValue = -1; // Custom pipe operator to skip duplicate values const deduplicate = (val) => { if (val !== lastValue) { lastValue = val; return val; } return undefined; // Return undefined to skip emitting this value }; const twn = tween({ from: 0, to: 4 }) .pipe(Math.round) .pipe(deduplicate) .filter(val => val !== undefined); // Filter out undefined entries twn.start(this.addToList); } addToList(val) { console.log('val = ', val); }
Solution 3: Use snap for Cleaner Integer Alignment
You can also use Popmotion's built-in snap transform to directly align tween values to integer steps, then add deduplication:
import { tween, transform } from 'popmotion'; onHandleClick() { const { snap } = transform; let lastValue = -1; const twn = tween({ from: 0, to: 4 }) .pipe(snap(1)) // Snap values directly to the nearest integer .pipe(val => { if (val !== lastValue) { lastValue = val; return val; } return undefined; }) .filter(val => val !== undefined); twn.start(this.addToList); } addToList(val) { console.log('val = ', val); }
All these solutions will output each integer from 0 to 4 exactly once, in order, as the tween runs. The core idea is to track the last value we've emitted and skip any duplicates that come from the tween's continuous stream of intermediate values.
内容的提问来源于stack exchange,提问作者me-me

