Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to setup interactions plugin and make it working. #12

Open
neatbyte-vnobis opened this issue Apr 14, 2023 · 0 comments
Open

How to setup interactions plugin and make it working. #12

neatbyte-vnobis opened this issue Apr 14, 2023 · 0 comments

Comments

@neatbyte-vnobis
Copy link

neatbyte-vnobis commented Apr 14, 2023

It will be great to use @storybook/addon-interactions to automate some more complex animations that goes one after another.

There is no point to use @storybook/testing-library for Pixi stories (as it simulates events over the dom elements), but steps logic can be used.

There is one problem that is a blocker to use interactions - how to get a Pixi Container (our component) that is returned from a story.
Default Storybook interactions are using canvasElement which contains rendered component, but it is a DOM element (see docs sample https://storybook.js.org/docs/react/essentials/interactions).

This DOM element is useless for us as we need an object/component returned from a story, so we can trigger certain animation method from it. Sadly, Storybook doesn't provide a way to get a value returned from a story render process.

Bellow is workaround I have made to handle this problem:

  1. Create a decorator to store story render result:
export const storyResultDecorator = (story, context) => {
  // storyResult is the value returned from your Story render
  const storyResult = story();
  
  // store story result into context.canvasElement so it can be get from there in the interaction
  context.canvasElement.storyResult = storyResult;

  // return story result as is
  return storyResult;
};
  1. Add decorator to .storybook/preview.ts
export const decorators = [storyResultDecorator]; // can gave more decorators
  1. Create a story with interaction (do not forget to add animateAction func to a BunnyDemo, in my case it was changing a rotation direction)
import { action } from '@storybook/addon-actions';

import { BunnyDemo } from './BunnyDemo';

export default {
    title: 'Demos-Basic',
    args: {
        bunnySize: 1,
        bunnySpacing: 40,
        someInjectedObject: {
            onBunnyClick: action('onBunnyClick'),
        },
    },
    render: (args: any) => new BunnyDemo(args),
};

// plain func to add a pause
const pause = (time = 0) => new Promise<void>(resolve => setTimeout(() => resolve(), time));

export const Interaction = {
    play: async ({ step, canvasElement: { storyResult } }: any) => {
        await step('Wait for 3 secs', async () => await pause(3000));
    
        await step('Change rotation direction 1', async () => {
            await storyResult.animateAction();
        });

        await step('Wait for 3 secs', async () => await pause(3000));

        await step('Change rotation direction 2', async () => {
            await storyResult.animateAction();
        });

        await step('Wait for 3 secs', async () => await pause(3000));

        await step('Change rotation direction 3', async () => {
            await storyResult.animateAction();
        });
      },
}

Maybe there is a better way to get Story render result in the interaction? Feel free to suggest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant