JSFL ActionScript Conversion
बनाया गया: 5 जनवरी 2025
बनाया गया: 5 जनवरी 2025
Converting code
OK, let me see. The code needs translation to ActionScript 2.0 and removing modern APIs. Progressing through this conversion, focusing on eliminating "fl," "document," or "dom."
Navigating JSFL functions
I’m thinking about JSFL's unique functions synced with Flash. Converting these to ActionScript 2 involves shifting from JSFL's fl
references to standard AS2 constructs.
Clarifying the context
Refining the code to fit ActionScript 2 involves avoiding JSFL methods like fl.getDocumentDOM()
. This results in removing the extensive timeline and library references, focusing on a streamlined version just for echo
and prompt
.
Tracing differences
Interestingly, while ActionScript 2 allows various definitions and assignments, it contrasts sharply with how the Flash IDE uses JSFL for references like timelines and libraries.
Mapping progress
I'm adjusting the code to actionScript 2.0 by tweaking variable declarations and type references, and pinpointing how to handle dom
references and JSFL functions like prompt
.
Choosing simple styles
I'm leaning towards a straightforward ActionScript 2 style, opting for simpler variable structure and incorporating parseInt
. This approach first explores what fits best.
Wondering about syntax
Trying out ActionScript 2 syntax, I’m noting optional var
declarations and the absence of "for each" loops. This exploration reveals both familiarity and gaps in syntax nuances.
Finalizing conversion
I’m integrating var
declarations and evaluating the removal of document.currentTimeline
references. This ensures the code is ready for the Commands panel's Flash environment.
Refining the details
OK, let me see. Keeping the code intact while trimming unnecessary typed references or document
mentions is central. This approach ensures clarity and adaptability across various scenarios.
Implementing frame modifications
I’m thinking about function creation, using prompts for user input, and iterating over selected frames. This approach includes random transformations and enhancements to achieve the desired effects.
Converting functionality
Ensuring the script aligns with an older ActionScript 2 style, focusing on functions and timeline handling to work within the constraints of the Flash IDE environment without fl
references.
Thought about ActionScript 3 to 2 conversion por 24 segundos
Below is a version of your script adapted to the older ActionScript 2 style. Important note: Much of this code (particularly the references to fl
, dom
, document
, timeline
, and prompt
) is actually part of the JSFL (JavaScript for Flash) API and the Flash IDE’s extensibility layer, rather than “pure” AS2 that would run inside a published SWF.
In other words, this script still relies on JSFL calls (fl.getDocumentDOM()
, prompt()
, etc.)—which are the same in both AS2 and AS3 “IDE scripts.” The main changes for “AS2 style” are removing strict type annotations, using simpler function declarations, and ensuring we aren’t using features unique to AS3.
You can place this in the Flash (Animate) Commands panel or a JSFL file. If you truly need pure ActionScript 2 that runs at runtime in a SWF, references to fl
, dom
, and prompt
will not work. However, for an older Animate/Flash environment that expects an ActionScript 2-like syntax in a JSFL file, this version should be acceptable.
// ActionScript 2/JSFL version var dom = fl.getDocumentDOM(); var timeline = dom.getTimeline(); var library = dom.library; var mx = 0; var my = 0; var mr = 0; // Retrieve selection from the current timeline. var selectedFrames = timeline.getSelectedFrames(); // JSFL does not differentiate between AS2/AS3 here, // but we avoid modern “AS3-only” function syntax. function prompt1() { return prompt("Horizontal shake:"); } function prompt2() { return prompt("Vertical shake:"); } function prompt3() { return prompt("Rotational shake (degrees):"); } function prompt4() { return prompt("Fade away? (y/n):"); } function prompt5() { return prompt("In synch? (y/n):"); } // Action logic: if (selectedFrames.length >= 3) { var str = prompt1(); // If the user typed just a letter, skip numeric parsing if (str.length == 1 && str.charCodeAt(0) > 64) { // This block effectively does nothing in the original code } else { var sx = parseInt(str); var sy = parseInt(prompt2()); var sr = parseInt(prompt3()) * Math.PI / 180; var fa = (prompt4() == "y"); var inSync = (prompt5() == "y"); // First pass: insert keyframes and remove tweens for (var i = 0; i < selectedFrames.length; i += 3) { var layerNum = selectedFrames[i]; var thisLayer = timeline.layers[layerNum]; timeline.setSelectedLayers(layerNum); var sf = -6; for (var j = selectedFrames[i+1]; j < selectedFrames[i+2]; j++) { if (thisLayer.frames[j].startFrame == sf) { timeline.currentFrame = j; timeline.insertKeyframe(j); } sf = thisLayer.frames[j].startFrame; timeline.setFrameProperty("tweenType", "none", j); } } // Second pass: apply shakes for (var frameIndex = selectedFrames[1]; frameIndex < selectedFrames[2]; frameIndex++) { timeline.currentFrame = frameIndex; // If in-sync rotation and sr > 0, we need a consistent center var center; if (inSync && sr > 0) { dom.selectAll(); center = dom.getTransformationPoint(); } // If fading out, scale shake intensity from 1 to 0^2 var intensity = 1; if (fa) { var progress = (frameIndex - selectedFrames[1]) / (selectedFrames[2] - selectedFrames[1]); intensity = Math.pow(1 - progress, 2); } // Apply transformations for all layers in the selected frames for (var i2 = 0; i2 < selectedFrames.length; i2 += 3) { var layerNum2 = selectedFrames[i2]; var frameElements = timeline.layers[layerNum2].frames[frameIndex].elements; for (var k = 0; k < frameElements.length; k++) { // We only shake symbol instances if (frameElements[k].toString() == "[object SymbolInstance]") { var mat = frameElements[k].matrix; // If this is the “first” instance this frame, // or we are NOT in sync mode, randomize new offsets if ((i2 == 0 && k == 0) || !inSync) { mx = (Math.random()*2 - 1) * sx * intensity; my = (Math.random()*2 - 1) * sy * intensity; mr = (Math.random()*2 - 1) * sr * intensity; } // Translate mat.tx += mx; mat.ty += my; // Rotate if (sr != 0) { var sinVal = Math.sin(mr); var cosVal = Math.cos(mr); var a = mat.a; var b = mat.b; var c = mat.c; var d = mat.d; var tx = mat.tx; var ty = mat.ty; mat.a = a * cosVal - b * sinVal; mat.b = a * sinVal + b * cosVal; mat.c = c * cosVal - d * sinVal; mat.d = c * sinVal + d * cosVal; // If in sync, rotate around 'center' so all layers/objects share pivot if (inSync && center) { mat.tx = (tx - center.x) * cosVal - (ty - center.y) * sinVal + center.x; mat.ty = (tx - center.x) * sinVal + (ty - center.y) * cosVal + center.y; } } frameElements[k].matrix = mat; } } } } } }
fl.getDocumentDOM()
, prompt()
, document.currentTimeline
, etc. are JSFL methods and properties. These are not part of typical AS2/AS3 that runs in a published SWF.Enhancing the script
I’m mapping out the script to apply random shaking keyframes to a range of frames, ensuring the effects extend beyond just a single frame.
Setting the framework
Considering a "shaking length" in frames, I’m preparing to insert keyframes behind each selected frame, applying random transformations, and removing previous tweens for continuity.
Shifting perspective
I’m planning to introduce a "shake duration" setting and modifying the script to ensure random transformations apply to each frame behind each selected region, thereby enhancing the animation effect.
Clarifying the user’s needs
I’m thinking through the user’s request for multiple keyframes with random offsets behind each selected frame, ensuring the transformations apply to each frame in the range.
Mapping out possibilities
Considerations include modifying frames behind each selected range or creating a trail effect behind each frame, with the complexity of potentially excessive frames.
Crafting user experience
I’m refining the script to include a user prompt for shake duration, adding keyframes with random transformations, and a gradual fade effect to enhance the animation's progression.
Refining the focus
I’m honing in on a user prompt for determining the number of frames behind each selected frame, ensuring keyframes with specified transformations are inserted, while preventing collisions with existing timeline frames.
Finalizing the script
I’m assembling the script with a new prompt for frames behind each selected frame, inserting keyframes with transformations, and preserving the original code logic for reference.
Refining the script
I’m detailing how to sequence keyframes behind each selected frame, incorporating defined transformations and fade effects, and ensuring randomness aligns with the selected frames.
Crafting the updated script
I’m refining the script to loop through frames behind each selected frame, applying random transforms, ensuring no negative indices, and retaining the original code logic for in-sync properties.
Rewriting code
I’m refining the script by looping through each frame within the selected range and adding frames behind, applying random transformations while adhering to the original code logic.
Refining the approach
I’m integrating prompt responses for frames behind each frame, ensuring the script extends keyframes with random transformations and maintains reversed fade logic. Progress is steady and methodical.
Thought about keyframe generation and shaking por 21 segundos
Below is an updated JSFL-like script (in AS2-style function syntax) that creates multiple keyframes behind each selected start frame, each with its own random shake values. In other words, instead of only modifying a single range or a single frame, it will create a “trail” of keyframes going backward in time from the selected start frame, each with random offsets.
Important: This is still a JSFL script (Flash/Animate extension), not “pure” ActionScript that runs in a published SWF. Calls such as
fl.getDocumentDOM()
,dom.getTimeline()
,prompt()
, etc. are only available in the Flash/Animate IDE environment.
Feel free to adjust details (like how many keyframes or where they are placed) to match your exact needs.
// // "Shake Trail" JSFL script in an AS2-style syntax // var dom = fl.getDocumentDOM(); var timeline = dom.getTimeline(); var library = dom.library; // We’ll track random offsets here: var mx = 0; var my = 0; var mr = 0; // Retrieve the selection data from the timeline as [layerIndex, startFrame, endFrame, layerIndex, startFrame, endFrame, ...] var selectedFrames = timeline.getSelectedFrames(); // -- PROMPTS ------------------------------------------------- function prompt1() { return prompt("Horizontal shake (pixels):"); } function prompt2() { return prompt("Vertical shake (pixels):"); } function prompt3() { return prompt("Rotational shake (degrees):"); } function prompt4() { return prompt("Fade away? (y/n):"); } function prompt5() { return prompt("In synch? (y/n):"); } // New: How many frames behind the start frame should we create? function prompt6() { return prompt("How many keyframes behind each start frame?"); } // -- MAIN ACTION --------------------------------------------- if (selectedFrames.length >= 3) { // 1) Prompt user for parameters var str = prompt1(); // Horizontal shake if (str.length == 1 && str.charCodeAt(0) > 64) { // This means they typed a single letter. In original code it just skips. // We’ll exit quietly. } else { var sx = parseInt(str); var sy = parseInt(prompt2()); var sr = parseInt(prompt3()) * Math.PI / 180; // convert degrees to radians var fa = (prompt4() == "y"); // fade away? var inSync = (prompt5() == "y"); // same random offset for everything in that frame? var framesBehind = parseInt(prompt6()); // how many frames behind the start? // -- FIRST PASS: Insert keyframes & remove tweens on each relevant layer/region. // (Same idea as your original code, ensuring no tweens in these frames.) for (var i = 0; i < selectedFrames.length; i += 3) { var layerIndex = selectedFrames[i]; var startFrame = selectedFrames[i + 1]; var endFrame = selectedFrames[i + 2]; var thisLayer = timeline.layers[layerIndex]; timeline.setSelectedLayers(layerIndex); var sf = -9999; // track the last startFrame we saw, to prevent re-inserting // For all frames in [startFrame - framesBehind … startFrame], ensure keyframes exist & no tweens for (var j = startFrame; j >= Math.max(0, startFrame - framesBehind); j--) { // Insert a keyframe if we haven't already if (thisLayer.frames[j].startFrame == sf) { timeline.currentFrame = j; timeline.insertKeyframe(j); } sf = thisLayer.frames[j].startFrame; timeline.setFrameProperty("tweenType","none", j); } } // -- SECOND PASS: Actually apply the random shakes behind each start frame for (var i2 = 0; i2 < selectedFrames.length; i2 += 3) { var layerIndex2 = selectedFrames[i2]; var startFrame2 = selectedFrames[i2 + 1]; var endFrame2 = selectedFrames[i2 + 2]; // not strictly needed if we're only going behind // If we are rotating “in sync,” we’ll grab a single center once for each chunk var centerPoint; if (inSync && sr !== 0) { // Must select all on stage for the DOM to define a transformation point timeline.currentFrame = startFrame2; dom.selectAll(); centerPoint = dom.getTransformationPoint(); } // Step from 'startFrame2' backward to 'startFrame2 - framesBehind' for (var framePos = startFrame2; framePos >= Math.max(0, startFrame2 - framesBehind); framePos--) { // Move the playhead to ensure we’re referencing the correct frame’s elements timeline.currentFrame = framePos; // If we’re fading over those behind frames: // progress = how far we are into the “trail” // e.g. framePos = startFrame2 means progress=0, framePos = startFrame2 - framesBehind means progress=1 var progress = (startFrame2 - framePos) / framesBehind; var intensity = 1; if (fa) { intensity = Math.pow(1 - progress, 2); } // Now apply transformations to each SymbolInstance in this layer at 'framePos' var frameElements = timeline.layers[layerIndex2].frames[framePos].elements; for (var e = 0; e < frameElements.length; e++) { if (frameElements[e].toString() == "[object SymbolInstance]") { var mat = frameElements[e].matrix; // If “inSync” is true, each SymbolInstance in the same frame uses the same random offsets // If not, each symbol gets new random offsets // (But if we want the same offset for *all layers*, consider moving these lines outside the layer loop.) if ((e == 0) || !inSync) { mx = (Math.random() * 2 - 1) * sx * intensity; my = (Math.random() * 2 - 1) * sy * intensity; mr = (Math.random() * 2 - 1) * sr * intensity; } // Translate mat.tx += mx; mat.ty += my; // Rotate if (sr != 0) { var sinVal = Math.sin(mr); var cosVal = Math.cos(mr); var a = mat.a; var b = mat.b; var c = mat.c; var d = mat.d; var tx = mat.tx; var ty = mat.ty; mat.a = a * cosVal - b * sinVal; mat.b = a * sinVal + b * cosVal; mat.c = c * cosVal - d * sinVal; mat.d = c * sinVal + d * cosVal; // If “inSync”, rotate around a single pivot (centerPoint) so all share the same center if (inSync && centerPoint) { mat.tx = (tx - centerPoint.x) * cosVal - (ty - centerPoint.y) * sinVal + centerPoint.x; mat.ty = (tx - centerPoint.x) * sinVal + (ty - centerPoint.y) * cosVal + centerPoint.y; } } // Apply the updated matrix to the symbol frameElements[e].matrix = mat; } } } } } }
Prompts
First pass:
For each selected region (layerIndex, startFrame, endFrame
), we insert (or ensure) keyframes at each frame going from startFrame
backward to startFrame - framesBehind
, removing tweens so the frames are fully keyframed.
Second pass:
We move the playhead to each of those newly inserted frames, apply random transformations (shake in x, y, and rotation).
Feel free to adjust the logic on how you compute the fade or how many frames behind you create. You could also adapt it to keep going beyond endFrame as well, or add other variations. This script should at least give you a starting point for a “shake trail” that spans multiple keyframes behind the original.
Designing the shake effect
I’m thinking through how to apply the shake effect to every frame, ensuring no gaps, and leveraging references for precision throughout the animation.
Tweaking the keyframe logic
I'm working on tweaking keyframe logic to insert a keyframe in each frame. Removing the condition for duplicates will ensure the effect is applied consistently throughout.
Tweaking the approach
OK, let me see. I’m refining the code to ensure every frame gets a keyframe. The tween type is set to "none" for simplicity and consistency throughout.
Thought about continuous keyframe shaking por 8 segundos
Below is an updated JSFL script (still using an ActionScript 2–style syntax) that ensures every frame in the specified range gets converted to a keyframe. The previous version only inserted keyframes if it detected a new “startFrame,” which could create gaps. Now, we simply force a keyframe on every frame so there are no empty spans.
// // "Shake Every Frame" JSFL script (AS2-style syntax) // var dom = fl.getDocumentDOM(); var timeline = dom.getTimeline(); var library = dom.library; var mx = 0; var my = 0; var mr = 0; // Retrieve selection as [layerIndex, startFrame, endFrame, layerIndex, ...]. var selectedFrames = timeline.getSelectedFrames(); // -- PROMPTS ------------------------------------------------- function prompt1() { return prompt("Horizontal shake (pixels):"); } function prompt2() { return prompt("Vertical shake (pixels):"); } function prompt3() { return prompt("Rotational shake (degrees):"); } function prompt4() { return prompt("Fade away? (y/n):"); } function prompt5() { return prompt("In synch? (y/n):"); } function prompt6() { return prompt("How many frames behind each start frame?"); } // -- MAIN ACTION --------------------------------------------- if (selectedFrames.length >= 3) { // 1) Prompt user for parameters var str = prompt1(); // Horizontal shake if (str.length == 1 && str.charCodeAt(0) > 64) { // If user typed a single letter, original logic was to skip. // We'll just exit quietly. } else { var sx = parseInt(str); var sy = parseInt(prompt2()); var sr = parseInt(prompt3()) * Math.PI / 180; // convert degrees to radians var fa = (prompt4() == "y"); // fade away? var inSync = (prompt5() == "y"); // same random offset for everything in that frame? var framesBehind = parseInt(prompt6()); // how many frames behind the start? // -- FIRST PASS: Convert every relevant frame to a keyframe (no tween). for (var i = 0; i < selectedFrames.length; i += 3) { var layerIndex = selectedFrames[i]; var startFrame = selectedFrames[i + 1]; // var endFrame = selectedFrames[i + 2]; // Not used here for going behind timeline.setSelectedLayers(layerIndex); // Convert every frame from startFrame down to (startFrame - framesBehind) // into a keyframe, with no tween. for (var j = startFrame; j >= Math.max(0, startFrame - framesBehind); j--) { timeline.currentFrame = j; // Force a keyframe every time (no condition). timeline.insertKeyframe(j); // Remove any tweens. timeline.setFrameProperty("tweenType","none", j); } } // -- SECOND PASS: Apply the shake to every one of these new keyframes. for (var i2 = 0; i2 < selectedFrames.length; i2 += 3) { var layerIndex2 = selectedFrames[i2]; var startFrame2 = selectedFrames[i2 + 1]; var centerPoint; if (inSync && sr !== 0) { // If we're rotating in sync, let's define a pivot from the startFrame. // (We do 'selectAll()' so the pivot is computed from everything on stage.) timeline.currentFrame = startFrame2; dom.selectAll(); centerPoint = dom.getTransformationPoint(); } // Go from 'startFrame2' backward to 'startFrame2 - framesBehind' // applying random shakes to each frame. for (var f = startFrame2; f >= Math.max(0, startFrame2 - framesBehind); f--) { timeline.currentFrame = f; // If we’re fading, figure out how far we are along the “trail.” var progress = (startFrame2 - f) / framesBehind; // 0 at startFrame, 1 at the farthest behind var intensity = 1; if (fa) { intensity = Math.pow(1 - progress, 2); } // For the layer we’re processing, apply transformations to every SymbolInstance var frameElements = timeline.layers[layerIndex2].frames[f].elements; for (var e = 0; e < frameElements.length; e++) { if (frameElements[e].toString() == "[object SymbolInstance]") { var mat = frameElements[e].matrix; // If “inSync” is true, all SymbolInstances in this frame share the same random offsets. // If not, each SymbolInstance gets its own new random offsets. if ((e == 0) || !inSync) { mx = (Math.random() * 2 - 1) * sx * intensity; my = (Math.random() * 2 - 1) * sy * intensity; mr = (Math.random() * 2 - 1) * sr * intensity; } // Translate mat.tx += mx; mat.ty += my; // Rotate if (sr != 0) { var sinVal = Math.sin(mr); var cosVal = Math.cos(mr); var a = mat.a; var b = mat.b; var c = mat.c; var d = mat.d; var tx = mat.tx; var ty = mat.ty; mat.a = a * cosVal - b * sinVal; mat.b = a * sinVal + b * cosVal; mat.c = c * cosVal - d * sinVal; mat.d = c * sinVal + d * cosVal; // If “inSync,” rotate around a single pivot so all share the same center if (inSync && centerPoint) { mat.tx = (tx - centerPoint.x) * cosVal - (ty - centerPoint.y) * sinVal + centerPoint.x; mat.ty = (tx - centerPoint.x) * sinVal + (ty - centerPoint.y) * cosVal + centerPoint.y; } } frameElements[e].matrix = mat; } } } } } }
In the first pass (where keyframes are inserted), we removed the condition that sometimes skipped frames. Now, for each frame j
from (startFrame)
down to (startFrame - framesBehind)
, we call:
timeline.insertKeyframe(j); timeline.setFrameProperty("tweenType", "none", j);
so every frame is converted to a keyframe—no gaps.
The second pass still applies the random shaking to every frame in that range.
This way, you’ll have a continuous set of keyframes with no empty frames in between.
Thought about shake trail in keyframes por um segundo
Glad to help! If you need further tweaks—like shaking forward in time instead of backward, or altering how fading/in-sync behavior works—just let me know. Good luck with your animation!