Copy link to clipboard
Copied
I have built a makeshift accordion in Adobe Animate for a project at work, and I would like to improve upon it. Does anyone know of any good tutorials on how to best build an accordion in HTML5 using Adobe Animate?
I did a quick search here, and couldn't find much. Any suggestions would be much appreciated.
Copy link to clipboard
Copied
Hi.
Congrats on your achievement!
And what kind of accordion it is? Do you have a reference/sample?
Regards,
JC
Copy link to clipboard
Copied
Here you go - I was having some difficulty with masking the content so I just have it appear on click. (a lame workaround until I can figure out how to do it correctly. I tried working with booleans too, but that got real confusing real quick (meaning if open = true do this, else do that)...
any feedback on how to do this better would be appreciated..
Copy link to clipboard
Copied
Hi there. Are you taling about a menu type of accordion like jquery or the actual musical instrument?
Copy link to clipboard
Copied
Oh, not a musical instrument. An acordion navigation piece. I'll attach a sample in a sec..
Copy link to clipboard
Copied
Hi.
First I have to tell that this one was very tricky.
Is say this because I wanna an approach that favors timeline usage to help beginners to get started.
This means that all animations and states have been created in the IDE using frames and tweens. And, of course, there is a bit of JavaScript, but way less than a regular dynamic menu like this would require. The secret keys here are smart structuring and assets preparation rather than crazy and complex code.
Also, this approach has the advantage of allowing the developer/designer to come up with any super fancy transitions or effects because in the end everything is just a simple timeline animation. Another advantage is that the menu is modular. This means you can use as many instances as you want in any place because all the code is inside of the symbol. Generally is not a good idea to spread nested code all over the FLA, but if you know what you're doing than things are going to be OK.
The disadvantages are that you cannot add or remove items without some crazy hack, you always have to contract the menu before opening it again, and only one item can be opened at a time.
I just make a notice that in this example the data is being fed dynamically because I didn't wanna to go over editing 40 symbols. But one can easily edit all the data just by duplicating symbols.
Preview:
Live:
Main JS code:
var root = this;
root.buttonPrefix = "row";
root.inPrefix = "in";
root.outPrefix = "out";
root.start = function()
{
root.stop();
root.toggled = false;
root.canPress = true;
root.data.reverse();
root.on("click", function(e)
{
if (!root.canPress)
return;
var target = e.target;
if (e.target && target.name && target.name.indexOf(root.buttonPrefix) === 0)
{
root.canPress = false;
if (root.toggled)
root.gotoAndPlay(root.outPrefix + root.position);
else
{
root.position = root.numChildren - root.getChildIndex(target.parent);
root.gotoAndPlay(root.inPrefix + root.position);
}
root.toggled = !root.toggled;
}
});
};
root.check = function() // called in the end of an animation
{
root.stop();
root.canPress = true;
};
if (!root.started)
{
root.start();
root.started = true;
}
FLA / source / files:
Regards,
JC
Copy link to clipboard
Copied
Thank you! I will analyze this and see if I understand how it works. This is very close to what I wanted. The only thing that is not quite right is, when you click on Illustrator it opens, but when you click on someting else the menu just closes. it should close Illustrator and open the other. I started making something similar - timeline based rather than code based, and it didn't seem to work the way I wanted it to either.
In the file I shared above - I updated the code on my side with this (I didn't update the file in the above link I previously shared, but if you replace the code in the main actions layer with the below, you'll see what I mean) :
var accordion = this.accordion_mc;
//=======================
var tab1 = accordion.tab1_head;
var tab2 = accordion.tab2_head;
var tab3 = accordion.tab3_head;
var t1Icon = tab1.icon_mc;
var t2Icon = tab2.icon_mc;
var t3Icon = tab3.icon_mc;
var tab3start = -410.45 + 11;
var tab3end = -12.75;
var tab2start = -434.6 + 11;
var tab2end = -35;
var lastDataDate = "January 31, 2020";
var content_tab1 = accordion.content_tab1_mc;
var content_tab2 = accordion.content_tab2_mc;
var content_tab3 = accordion.content_tab3_mc;
var tab1Disclaimer = accordion.content_tab1_mc.content_mc.disclaimer_txt;
tab1Disclaimer.text = "Source: federalreserve.gov; Morningstar Direct. As of " + lastDataDate;
tab3Pos = 0;//0 = up, 1=down
content_tab1.alpha = 0;
content_tab2.alpha = 0;
content_tab3.alpha = 0;
function openTab1() {
//tab 1 does not move
}
function openTab2() {
createjs.Tween.get(tab2, {
override: true
})
//.wait(1500)
.to({
y: tab2end
}, 500, createjs.Ease.quartInOut)
}
function openTab3() {
createjs.Tween.get(tab3, {
override: true
})
//.wait(1500)
.to({
y: tab3end
}, 500, createjs.Ease.quartInOut)
tab3Pos=1;
}
function closeTab2() {
createjs.Tween.get(tab2, {
override: true
})
//.wait(1500)
.to({
y: tab2start
}, 500, createjs.Ease.quartInOut)
}
function closeTab3() {
createjs.Tween.get(tab3, {
override: true
})
//.wait(1500)
.to({
y: tab3start
}, 500, createjs.Ease.quartInOut)
}
tab1.addEventListener("click", chooseTab1.bind(this));
function chooseTab1() {
openTab2();
openTab3();
createjs.Tween.get(content_tab1, {
override: true
})
//
.wait(500)
.to({
alpha: 1
}, 500, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab2, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab3, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
t1Icon.gotoAndPlay("open");
t2Icon.gotoAndStop("default");
t3Icon.gotoAndStop("default");
tab1.removeEventListener("click", chooseTab1.bind(this));
tab1.addEventListener("click", closeAll.bind(this));
//tab1.addEventListener("click", chooseTab1.bind(this));
tab2.removeEventListener("click", closeAll.bind(this));
tab3.removeEventListener("click", closeAll.bind(this));
tab2.addEventListener("click", chooseTab2.bind(this));
tab3.addEventListener("click", chooseTab3.bind(this));
}
tab2.addEventListener("click", chooseTab2.bind(this));
function chooseTab2() {
closeTab2();
openTab3();
createjs.Tween.get(content_tab1, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab2, {
override: true
})
//.wait(500)
.to({
alpha: 1
}, 500, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab3, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
t1Icon.gotoAndStop("default");
t2Icon.gotoAndPlay("open");
t3Icon.gotoAndStop("default");
tab2.removeEventListener("click", chooseTab2.bind(this));
tab2.addEventListener("click", closeAll.bind(this));
tab1.removeEventListener("click", closeAll.bind(this));
tab3.removeEventListener("click", closeAll.bind(this));
tab1.addEventListener("click", chooseTab1.bind(this));
//tab2.addEventListener("click", chooseTab2.bind(this));
tab3.addEventListener("click", chooseTab3.bind(this));
}
tab3.addEventListener("click", chooseTab3.bind(this));
function chooseTab3() {
closeTab2();
closeTab3();
createjs.Tween.get(content_tab1, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab2, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab3, {
override: true
})
//.wait(300)
.to({
alpha: 1
}, 500, createjs.Ease.quartInOut)
t1Icon.gotoAndStop("default");
t2Icon.gotoAndStop("default");
t3Icon.gotoAndPlay("open");
tab3.removeEventListener("click", chooseTab3.bind(this));
tab3.addEventListener("click", closeAll.bind(this));
tab1.removeEventListener("click", closeAll.bind(this));
tab2.removeEventListener("click", closeAll.bind(this));
tab1.addEventListener("click", chooseTab1.bind(this));
tab2.addEventListener("click", chooseTab2.bind(this));
//tab3.addEventListener("click", chooseTab3.bind(this));
}
function closeAll() {
closeTab2();
closeTab3();
tab1.addEventListener("click", chooseTab1.bind(this));
tab2.addEventListener("click", chooseTab2.bind(this));
tab3.addEventListener("click", chooseTab3.bind(this));
createjs.Tween.get(content_tab1, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab2, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
createjs.Tween.get(content_tab3, {
override: true
})
//.wait(500)
.to({
alpha: 0
}, 1, createjs.Ease.quartInOut)
t1Icon.gotoAndStop("default");
t2Icon.gotoAndStop("default");
t3Icon.gotoAndStop("default");
}
It seems to work for a little while, but then gets bogged down when you click on the buttons several times and ultimately becomes unresponsive. I'm sure I probably just have to turn something off at some point so it stops running.
All that said, I'm going to take a look at the file you shared and see if I can get that to work the way I want. Thanks for taking the time to look at this with me!!
Rich
Copy link to clipboard
Copied
Hi.
Glad to know that it will serve as a reference!
Yeah. The menu has the limitation you mentioned. I stated this in the disadvantages part of my comment. But the main reason is that I wanna to keep things simple.
Maybe I'll come up later with a code solution that will allow the menu to be as dynamic as we expect it to be or maybe I will also improve this timeline based version so it will collapse any open item and immediately open the current pressed item.
And one suggestion I give to you is to increase the framerate of your FLA to 60 fps which is the standard value for UI motion.
Regards,
JC
Copy link to clipboard
Copied
Thank you! 🙂 I will update the frame rate!!
Copy link to clipboard
Copied
Looking it over and have a question - tell me about the usage of 'this.check();' Never saw that before - what does it do?
Copy link to clipboard
Copied
This is just a custom method I defined in frame 0. It only resets the user ability to press the menu and it also stops the accordion main timeline.
root.check = function()
{
root.stop();
root.canPress = true;
};
I gave it this generic name because I didn't know in the beginning what exactly this method would end up doing.
Copy link to clipboard
Copied
I have to make a few modifications, some of which I was able to make, but others I may need help on.
Specifically, I need to streamline the UI a bit - The behavior I need is: if you open tab 0 and click on tab1, tab 1 should open, rather than closing the whole accordion, and then needing to click on tab 1 again to open. But if you click on tab 0 and tab 0 is open, the whole accordion should close. No luck getting this to work on the timeline file. I have tried to make this repeatedly using event listeners and create js, but the accordion bogs down and eventually becomes unresponsive.
The code in your file works great (and does not bog down!), but is not what I'm accustomed to, so my attempts of making the above work have failed. Any advice on how to get the above to work? I think we're done if we can get that to work..
Thanks in advance!!
Rich
Copy link to clipboard
Copied
I think I figured it out - rewired the whole thing, but got it to work the way I need. So don't worry about anything! Thanks for your help!
Copy link to clipboard
Copied
Excellent! Congrats!