Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "fix: fix issue of custom type\n\n",
"type": "none",
"packageName": "@visactor/vrender-animate"
}
],
"packageName": "@visactor/vrender-animate",
"email": "lixuef1313@163.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "fix: fix issue of custom type\n\n",
"type": "none",
"packageName": "@visactor/vrender-components"
}
],
"packageName": "@visactor/vrender-components",
"email": "lixuef1313@163.com"
}
13 changes: 4 additions & 9 deletions packages/vrender-animate/src/executor/animate-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
IAnimationChannelInterpolator
} from './executor';
import { cloneDeep, isArray, isFunction } from '@visactor/vutils';
import { getCustomType } from './utils';

interface IAnimateExecutor {
execute: (params: IAnimationConfig) => void;
Expand Down Expand Up @@ -171,8 +172,7 @@ export class AnimateExecutor implements IAnimateExecutor {
duration: (slice.duration as number) * scale,
effects: effects.map(effect => {
const custom = effect.custom ?? AnimateExecutor.builtInAnimateMap[(effect.type as any) ?? 'fromTo'];
const customType =
custom && isFunction(custom) ? (/^class\s/.test(Function.prototype.toString.call(custom)) ? 1 : 2) : 0;
const customType = getCustomType(custom);
return {
...effect,
custom,
Expand All @@ -198,12 +198,7 @@ export class AnimateExecutor implements IAnimateExecutor {
(params as IAnimationTypeConfig).custom ??
AnimateExecutor.builtInAnimateMap[(params as IAnimationTypeConfig).type ?? 'fromTo'];

const customType =
parsedParams.custom && isFunction(parsedParams.custom)
? /^class\s/.test(Function.prototype.toString.call(parsedParams.custom))
? 1
: 2
: 0;
const customType = getCustomType(parsedParams.custom);
parsedParams.customType = customType;

if (totalTime) {
Expand Down Expand Up @@ -565,7 +560,7 @@ export class AnimateExecutor implements IAnimateExecutor {
from = parsedFromProps.from;
}
const custom = effect.custom ?? AnimateExecutor.builtInAnimateMap[type];
const customType = (effect as any).customType;
const customType = effect.custom ? (effect as any).customType : getCustomType(custom);
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition checks effect.custom instead of checking if customType already exists on the effect object. This is incorrect because:

  1. At line 562, custom can be either effect.custom OR a built-in animation from AnimateExecutor.builtInAnimateMap[type]
  2. In the parseParams function (lines 173-180), effects that go through the timeline path have customType computed and stored
  3. When effect.custom is not provided but a built-in animation is used, this condition will be false even though customType might already exist on the effect

The condition should check for the presence of customType on the effect, not effect.custom. For example: (effect as any).customType !== undefined ? (effect as any).customType : getCustomType(custom)

Suggested change
const customType = effect.custom ? (effect as any).customType : getCustomType(custom);
const customType =
(effect as any).customType !== undefined ? (effect as any).customType : getCustomType(custom);

Copilot uses AI. Check for mistakes.
this._handleRunAnimate(
animate,
custom,
Expand Down
5 changes: 5 additions & 0 deletions packages/vrender-animate/src/executor/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { isFunction } from '@visactor/vutils';

Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function lacks documentation explaining what the return values (0, 1, 2) represent. Based on the implementation:

  • 0: not a function or falsy value
  • 1: ES6 class constructor
  • 2: regular function

Adding JSDoc documentation would improve code maintainability and help other developers understand the purpose and return values of this function.

Suggested change
/**
* Determines the type of the given `custom` value.
*
* Return values:
* - `0`: `custom` is falsy or not a function.
* - `1`: `custom` is an ES6 class constructor.
* - `2`: `custom` is a regular (non-class) function.
*
* @param custom - The value to check.
* @returns A numeric code indicating the type of `custom`.
*/

Copilot uses AI. Check for mistakes.
export function getCustomType(custom: any): number {
return custom && isFunction(custom) ? (/^class\s/.test(Function.prototype.toString.call(custom)) ? 1 : 2) : 0;
}
Loading