Clip API Ideas

Based on some of my feature suggestions here, I have some ideas for the Clips API and how it can be extended with simple yet powerful features. Some of these are already in Wick’s code, just not exposed yet. I also based quite a few of these on the ActionScript 3.0 reference for MovieClips.

The scripting reference would have a Clips heading with these functions and variables in it:

  • Clip.play(), stop(), goto...(), etc. except they apply to the clip’s timeline rather than the parent’s

  • Clip.playheadPosition : int [read-only]
    EDIT: Wick already has both this and currentFrameName, just one or the other’s fine.

  • Clip.currentFrameName : String [read-only]
    // Returns the name of the frame which is currently active. If multiple frames are active, returns the name of the first [topmost?] active frame.

  • Clip.length : int
    // EDIT: The length of the Clip. This is not the same as totalFrames, because you can have gaps between frames.

  • Clip.totalFrames : int
    // The total number of frames in the Clip.
    EDIT: I actually can’t think of a reason you’d need this if you have length

  • Clip.isPlaying : Boolean [read-only]
    // Is the Clip playing?

EDIT: I’ve rethought the ideas below, see the next posts!

  • Clip.syncTimeline : bool (default false)
    //If false, Clip’s playback can be controlled using code. If true, Clip’s playback will be synced to its parent timeline and will not respond to frame actions like Clip.play(). However, it will still run other code, and you can preview how its animation will look when editing its parent timelines.
    (You’d be able to change this in the inspector.)

    • Why?
      Only the first frame of animated Clips are represented on the stage when editing. (See here; there’s an example file.) This is because it’s impossible to predict what the code applied to it will be when the project runs. If Wick showed you the animated Clip playing all its frames, that might not be accurate, because there could be a script somewhere that runs stop() or gotoNextFrame() on it.

      This isn’t great for animation, because you must play the project to see how your animation really looks; you can’t scrub through the timeline to analyze it and fix issues. It’s also much more tedious to create a clip full of common objects, like a “hand” clip with many gestures inside to switch between. (This is an extremely common practice in Flash animation.) You must add code to switch the frames, and you can’t see your changes reflected while editing.

      A feature like this would help a lot by creating an equivalent to Flash’s Graphic symbols, which were used for these purposes. You could then adjust Clip behavior in the Inspector.
  • Clip.loops : int (default -1)
    //How many times should this Clip loop? If 0, Clip will just play once. If -1, Clip will loop infinitely.
    (You’d be able to change this in the inspector.)

  • Clip.framesToPlay : String (default "1 - end")
    //Which frames should be included when the Clip is playing? For example: "1-5, 'special', 6-end" plays the first five frames, skips to one called ‘special’, then continues playing from the 6th frame onward.
    (You’d be able to type this into the inspector.)

    • Why?
      This feature would allow you to re-use Clips easily without having to duplicate or redraw stuff. For example, you can make a Clip of a character’s head turning from left to right, then use this feature to make the head turn from right to left, or from the center to the right, etc. You can also use it to play Clips at whatever speed you want:
      half speed: 1, 1, 2, 2, 3, 3, etc.
      double speed: 1, 3, 5, 7, 9, 11, etc.
      The more ways there are to process and re-use the same data, the better!

    • How this would work internally
      Example input: "1, 2, 3-10, 'special frame', 12-8, end, 4"
      First, remove all spaces unless they are in quotes.
      "1,2,3-10,'special frame',12-8,end,4"
      Second, search for ‘end’, ‘END’, or ‘End’ and replace it with the clip’s length.
      "1,2,3-10,'special frame',12-8,14,4"
      Replace all labels (if valid) with their proper frames too.
      "1,2,3-10,5,12-8,14,4"
      Replace all dashes with all frames between the two numbers.
      "1,2,3,4,5,6,7,8,9,10,5,12,11,10,9,8,14,4"
      Convert this list to an internal array of frame numbers to visit, and use it in the part of Wick’s code that animates Clips.

Do these ideas seem useful? Confusing? Let me know what you all think, and feel free to post your own ideas as well!

2 Likes

Haven’t responded to this yet. I do like the idea of having a Clip section of the reference, it makes it super clear that these methods can be applied to clips as well!

playheadPosition, totalFrames and isPlaying shouldn’t be tough to add! Also, clip.loops should also be a pretty straightforward add! currentFrameName and Number should be available… I’ll take a look and ensure they’re exposed.

clip.framesToPlay may cause a few issues development wise, but we’ll walk through some potential solutions to this. Being able to, at the very least, name certain sections of a clip so we can us things like clip.play(“section”), should be straightforward and allow us to control the clip a bit easier through code.

We’re having a bit of trouble following “syncTimeline” however. We think it may end up adding a bit of complexity to certain projects. I’d like to see some more implementations of this system to wrap my head around it.

2 Likes

I’m glad some of my suggestions could help! :smile: I’ll try to clarify syncTimeline and framesToPlay by explaining how I came up with them, since I think some context is missing. I’ve also revised those ideas in the process.

syncTimeline is supposed to be an equivalent to Flash’s Graphic symbols, which behave differently than MovieClips and are therefore used for different purposes.
Graphics (in Flash) cannot have code applied to them, so their animation is predetermined. You can choose whether they Loop, Play Once, or hold a Single Frame, and you can choose what frame they start at. They are bound to their parent timeline; if it stops, they stop. (That’s why I named the property syncTimeline, although that is a bit confusing.)
image

Movie Clips, on the other hand, can have code applied to them, and they operate independently of their parent. By default, they just loop endlessly when the project is run, regardless of whether its parent timeline is playing.
(A Movie Clip will continue to play independently even if it’s inside a Graphic.)

Because their playback is unpredictable, you can’t preview it in the Flash editor. For example, if you place both a Graphic and a Movie Clip on a long frame and then scrub through it, you can see the Graphic’s animation progress (because it is predictable) but not the Movie Clip’s.
d91582ae-549b-4b9e-830a-00cc4175493a

Currently, all Wick Clips act like Flash’s Movie Clips in this regard. However, Flash’s Graphics have very helpful use cases. For example:

  • Create a “hand” Graphic that has several different hand gestures in it. Set it to Single Frame. Now change the frame shown whenever the character’s hand gesture needs to change. This also applies to eyes, mouths, limbs, etc.!
  • Wrap large scenes or moving backgrounds in a Graphic for better organization. You can still see how it looks when navigating the main timeline. I do this when animating in Flash.
  • Scrub through the timeline to quickly make sure all your animations-inside-Graphics look good, without having to run Control > Test Movie. I use Graphics a lot, so this is pretty important for me!

Another great feature is that if you create an asset in the library and save it as, say, a Movie Clip, you can tell an individual instance to behave as a Graphic or even as a Button. That way, you don’t have to remake or duplicate any assets (and keep copying any changes to them) if you want to use one multiple ways.
I don’t think I’ve used this a lot, personally, but it’s really helpful to be able to use the same data in as many ways as possible. For example, if you have an animated character for a game, you might want to make his body parts Graphics for “cutscenes” (where you’re animating him in advance) and Movie Clips for gameplay (where his body or facial expressions might change through code based on what he’s doing in the game).

image

I wrote syncTimeline as a boolean property rather than a separate data type (like Clip or Button) because I thought, if you want a Clip to behave like a Graphic at one point and a Movie Clip at a different point, you could easily change the behavior with code or in the inspector.

But it might be better to just add a Graphic option like Flash has. That might be better for communicating that Clips are intended to be interactive (as well as animated) while Graphics are strictly for animation and cannot have code applied to them. The fact that Graphics cannot have code also prevents, say, a stop(); action that the user forgot about from altering the finished product.

As for framesToPlay, I wrote that thinking it’d be a super efficient and cool way to use the data in your Clips any way you want, but looking at it now, I can’t think of many good use cases for it that can’t be accomplished other ways. It’s also pretty clunky as it requires you to input a string in a specific format.
It was more of a “this would be nice to have / good design ideal” thing but I’m not sure if it’d be helpful enough to be worth the effort.

Instead, I’d suggest these inspector options exclusively for Graphics:

  • Amount of loops (anywhere from play once to loop forever)
  • Play forward/reverse
  • Frame numbers or labels to start at and stop at
    • Useful for animation; you can type, say, “face_happy” instead of frame 38 or something
  • Hold a single frame
  • Use this Graphic as a Clip (and vice-versa)

These would add a little more power than the options Flash gives you.

For Clips, you could use code to get the same results. Below, I used:

  • Your idea about giving arguments to play()
  • A simple function that allows Wick to wait seconds or frames before executing the next command. (Like Construct 2’s “wait” action or Unity3D’s yield return new WaitForSeconds(1).) This would be helpful in all sorts of situations, not just playing Clips.
  • And a variable in the Clip API that tells you which direction your clip is playing.
play(); //plays entire clip

//Play, starting from startFrame until end. Argument can be an integer or a string label.
play(startFrame);

//Play between two frames. If startFrame is after endFrame, the clip will play in reverse.
play(startFrame, endFrame);

//Play between two frames and choose how many times to loop.
//By default, this is -1, which means loop forever. 0 means play once.
play(startFrame, endFrame, -1);

//Playing in reverse
play(clip.totalFrames, 1);

//Playing in reverse (alternate method)
for (i=0; i < clip.totalFrames; i++) {
    gotoAndStop(clip.totalFrames-i);
    waitForFrames(1);
}

//Playing a custom sequence
gotoAndPlay("myCoolFrame");
waitForFrames(1);
gotoAndPlay(5);
waitForFrames(1);
gotoAndPlay("myOtherCoolFrame");

//read-only
if (clip.isPlayingInReverse) {
    console.log("I'm dizzy");
}

A read-only isPlayingInReverse would probably be better than a clip.reversed variable that can be changed. The latter can introduce bugs unless you preface every play() with clip.reversed = false. Beginners might get confused about why their Clips are playing the wrong way; they set them to reverse one time, then later they try to play them, expecting them to go forwards.
This also means clip.loops is unnecessary for a similar reason.

What do you think of these ideas? :slightly_smiling_face: Things like playing clips in reverse are nice-to-haves rather than necessities, but the more powerful Clips are, the better a foundation they set for what Wick can do.

I started implementing some of these features here!!! It’s going really well :sunny: Since Wick is open-source, anyone can make modifications (or “code forks”) of it. So I put mine here:

To make forward and reverse playback possible, I reupholstered the Timeline code and then added a new function.

    /**
     * Repeats a specific part of the timeline.
     * @param {string|number} startFrame - A playhead position or name of a frame to start at.
     * @param {string|number} endFrame - When the playhead reaches this frame, it will loop back to startFrame.
     * @param {number|bool} [loop = true] - If true, will loop forever. If false, will play once and stop. If a number, it will play that many times in total.
     */
    gotoAndLoop (startFrame, endFrame, loop = true) {
        this.timeline.gotoAndLoop(startFrame, endFrame, loop);
    }

I also added almost all of the above Clip members (Clip.length, Clip.playing etc.) to the reference, as well as some other new features.

image

And I fixed some Clip-related bugs (like playing frames that are out-of-range).

If you know how to download and run Wick from source, I encourage you to try out my fork and tell me what you think of the new functionality! :smile: And post about any bugs you find :bug:

1 Like

As for adding the functionality of Graphics from Flash, I’m reconsidering whether it’d be better to simply extend Clips rather than create a whole new data type. Instead of a complicated framesToPlay variable, you’d choose the Clip’s default behavior in the inspector. So instead of all Clips automatically playing, you could make them show a specific frame, loop a range, etc. Wick would then quietly run gotoAndLoop() on it based on your settings.

Here’s a quick mockup (not a real interface) of what that might look like:

  • You can type numbers or frame labels
  • Infinity sign means loop infinitely, and it disables the loop count input field
  • That big button controls whether the Clip acts more like a Flash Graphic or a Flash Movie Clip. (Clip.playIndependentlyOfParent) Its tooltip would say something like…

image
“This Clip can play() or stop() itself regardless of whether its parent is playing. You can change its playback anytime using goto functions like gotoAndPlay().”

image
“This Clip always plays when its parent plays, and stops when its parent stops. goto functions will not work. However, you can see how its animation will look onstage while you’re editing!”

I think this makes the syncTimeline concept a lot easier to understand, while having some really cool benefits:

  • No need to program another type of object
  • Users can get all the benefits of Graphics in Flash AND are able to code them
    • I was looking at this like a bad thing before, since you could accidentally leave some code on an object and mess up the final product…but…you could just WATCH the final product and then delete the code…
    • Also, Wick’s playback is really awesome in that you can instantly see how the final movie will look, code and all! :+1:
  • If you want to always preview how your Clips animate, you can flick this option on and then put in some code like:
this.playIndependentlyOfParent = true;

That way, it doesn’t matter what the editor setting is - your Clip will always behave the same way when the project is run!

1 Like