0 votes
by (1.4k points)

Hello SugarCubers 2.28.2!

I am trying to use <<toggleclass>> to get something to fade out after a <<timed>>, but it randomly skips ahead in the transition, jumping to half faded out or completely faded out and so on.

Here is what is in the stylesheet:

.see {
  opacity: 0;
  transition: 4s all ease;
}

.see:hover {
  opacity: 1;
  transition: 4s all ease;
}
.unsee  {
  opacity: 0;
  transition: 2.5s all ease;
}

And I'm using <<toggleclass ".see" "see unsee">>. Anything wrong with that?

Thank you!

1 Answer

0 votes
by (68.6k points)
edited by

You're changing the transition, so naturally you're running into issues with the animation.

I don't know exactly what you're going for, as you left out some details, but try the following:

.see {
	opacity: 0;
	transition: 4s all ease;
}
.see:hover {
	opacity: 1;
}

.unsee  {
	opacity: 0;
}

Also.  Unless you really need to apply a transition to many properties at once, it's generally better to be specific.  For example:

/* Set up a transition for all properties that allow transitions. */
transition: 4s all ease;

/* Set up a transition for the `opacity` property only. */
transition: 4s opacity ease;

 

by (1.4k points)
edited by

I changed it to this but it doesn't seem to affect it:

.see {
  opacity: 0;
  transition: 4s opacity ease;
}
.see:hover {
  opacity: 1;
}
.unsee  {
  opacity: 0;
  transition: 4s opacity ease;
}

(If I leave the transition out of .unsee the image merely vanishes.)

There aren't many details I can think of to add; here is what I have in the test passage:

<div class="see">[img[img.url]]</div>
<<timed 4s>><<toggleclass ".see" "see unsee">><</timed>>

[Update] I was able to find a pattern: if I entered the test passage with my mouse over the element and never took it off, it would work fine, but if I ever had the mouse off the element it would mess up.

So I would think the problem would be messing with the class while its transition is in progress... but I am not sure how that could be avoided, since the idea of this is to have something that fades in and out, then fades out after a <<timed>>.

I suppose a simpler version of my question would be "how can I have a passage fade out?", this was just the only way I thought of to do it. Maybe there is an obvious other way...

by (68.6k points)
edited by

The basic problem, as I explained before, is that you cannot replace or remove the transition, which your newest example still does, or the transition animation will break.  You are literally replacing or removing the property that is anchoring the animation; that you're replacing it with another transition property does not matter.

Your original post made it sound like you were adding content via the <<timed>>, which you then wanted to fade.  And there was the hover bit, which made it seem you were really doing something more involved that you let on.

If you're just attempting to get something to fade in and then out after some period, then what should trigger the fade in and what's the hover bit for?  It would really help if you explained exactly what you want to happen at every stage.

Regardless.  If all you need is a fade in and then out, then the following will CSS work:

.seeable {
    opacity: 0;
    transition: 4s opacity ease;
}
​
.see  {
    opacity: 1;
}

With the following markup:

<div class="seeable">[img[img.url]]</div>

<<timed 2s>>
    <<addclass ".seeable" "see">>
<<next 4s>>
    <<removeclass ".seeable" "see">>
<</timed>>

Note how I do not remove the class containing the transition, rather only adding and removing the class that alters the property that is being transitioned (opacity).

I doubt I'm on target just yet, but that should be closer to the mark.

EDIT: Fixed a bit of reading comprehension failure on my part.

by (1.4k points)

Sorry, when I said I needed it to "fade in and out, and then fade out", to be more specific I needed it to fade in when I mouseover it, fade out when I mouseoff, then after a <<timed>> stop fading in when I mouseover it, and fade out if it is in.

I altered the setup according to your suggestions, but it still skips the fade out if it is in mid transition when I add the class:

.see {
  opacity: 0;
  transition: 4s opacity ease;
}
.see:hover {
  opacity: 1;
}
.unsee:hover  {
  opacity: 0;
}

And in the test passage:

<div class="see">[img[img.url]]</div>
<<timed 4s>>
<<addclass ".see" "unsee">>
<</timed>>

It may complicate the matter, but for the full story: I am editing this game I made. If you don't kill a monster, it eats you. But I recently added a walking mirror you are not supposed to kill, so when you successfully don't kill it I want it to fade away just like it faded in. This not being possible, since for another monster to appear you have to go to another passage, I would settle for the whole passage to fade out (since it mostly not visible anyway) before it goes to another passage.

Basically the whole thing I am trying to avoid is an abrupt disappearance of the passage before the new passage fades in. You can download the index.html file on itch.io, but it probably won't be very enlightening (my code formatting is jungle-ish; I wasn't actually intending to ever use code, but Twine kind of... snuck it in).

by (68.6k points)
edited by

AFAIK, that's not possible with CSS transitions.  You simply do not have the level of control over the animations required to make that seamless. 

You might be able to make that work with CSS animations (i.e. keyframe animations defined via @keyframes and the animation property).

I would think that you should definitely be able achieve that with programmatic (i.e. JavaScript) animations.  There are many libraries available.

by (1.4k points)
edited by

I did make it work with keyframes, like so:

.see {
  opacity: 0;
  transition: 4s opacity ease;
}
.see:hover {
  opacity: 1;
}
.unsee  {
  animation: unsee 2.5s;
  animation-iteration-count: 1;
}
@keyframes unsee {
  0% { opacity: 1; }
  80% { opacity: 0; }
  100% { opacity: 0; }
}

And in passage:

<<timed 4s>>
<<addclass ".m" "unsee">>
<<timed 2.3s>>
<<goto "room">>
<</timed>><</timed>>

I put .m on the specific element for the walking mirror that I wanted to fade out, since I didn't want all the .see elements to suddenly have full opacity then fade out.[Update: I changed my mind and put .m on the whole passage, in case the mouse is over one of the other .see elements when it goes to another passage. Anyway, another part of the room dimming as the mirror leaves gives a suggestion of reflected light!]

Interestingly the similar problem I expected I would have, of the walking mirror jumping to full opacity before it started to fade out if it wasn't full opacity already, didn't happen. I even jiggled my mouse on an off the element so it would never reach more than half opacity, and it still smoothly faded away. I wonder why.[Update: oh that's why!]

Anyway, thank you for the perfect suggestion! (Is there a way to mark that particular suggestion as the answer? We may also want to mention it somewhere as a way to make a passage fade out.)

by (68.6k points)

Glad you got it to work.  And not as far as I am aware.

 

Also.  You probably shouldn't be nesting <<timed>> macros when you can simply use the original's <<next>> tag.  For example:

<<timed 4s>>
<<addclass ".m" "unsee">>
<<next 2.3s>>
<<goto "room">>
<</timed>>

 

by (1.4k points)
Thanks for the tip!
...