I've modified my previous Sugarcane passage transition code to allow you to define your own transitions with CSS.
Update: the Javascript that was on this page is now installed in Twine 1.4.
What this does is remove the default JavaScript transition from Sugarcane, and cause the outgoing passage to gain a "transition-out" class, and the incoming passage to instantly gain and lose a "transition-in" class. This enables you to define new passage transitions by styling these 3 classes using CSS.
CSS Examples
In order for there to be a transition, you must specify the transition
property for your passage elements. A very basic example is as follows:
.passage { transition: 0.25s linear; -webkit-transition: 0.25s linear; }The
transition
property causes elements to transition between styles when they gain and lose them, in a specific way. In this case, it's a quarter-second, purely linear transition. (Other options than "linear" are listed here.) The maximum duration time before the departing passage is removed is 1 second.
The current versions of Opera, Firefox and IE support the plain transition property, but you need to also include the -webkit variant in order to work in Chrome and Safari (you can also include -khtml-transition
for Konqueror users, few though they may be).
Now that you've defined the transition itself, you can define the styles that the passages can transition from and to.
A very basic example:
.transition-in { position:absolute; opacity:0; }When a new passage arrives, its style will transition from the "transition-in" style to the normal passage style. In this case, it starts invisible ("opacity:0") and fades in to visibility. Note the "position:absolute" - both "transition-in" and "transition-out" should have either position:absolute or position:fixed if you want them to neatly appear above or below each other.
.transition-out { position:absolute; opacity:0; }
A broad number of CSS attributes can be used with this technique. Experiment!
Combining with tag-based CSS
If you use my tag-based passage CSS code, you can tie transitions to passages tagged with a particular tag. For instance, to bind the "dissolve" transition to passages tagged with "t8n-dissolve":
body[data-tags~=t8n-dissolve] .transition-in { position:absolute; opacity:0; } body[data-tags~=t8n-dissolve] .passage { transition:1s; -webkit-transition: 1s; } body[data-tags~=t8n-dissolve] .transition-out { position:absolute; opacity:0; }I recommend prefixing all transition-based tags with something identical, like "t8n" (a numeronym of "transition"). This way, you can then define a default transition to be used only when no "t8n" tags are present:
body:not([data-tags*=t8n]) .transition-in { opacity:0; transform: translate(0,3rem); -webkit-transform: translate(0,3rem); position:absolute; } body:not([data-tags*=t8n]) .passage { transition: 2s; -webkit-transition: 2s; } body:not([data-tags*=t8n]) .transition-out { opacity:0; transform: translate(0,-3rem); -webkit-transform: translate(0,-3rem); position:absolute; }
[data-tags*=t8n]
selects elements whose tags contain "t8n", and :not()
selects elements that do not fulfill the requirement in the brackets.)
It's important that if you use multiple transitions, the default transition should be guarded using body:not([data-tags*=t8n])
, so that its code doesn't interfere with the other transitions' code.
To see an example where the first four passages are tagged "t8n-dissolve" and the rest are not, see here.
Live examples
All examples are "The Sky in the Room" by Porpentine.
Fade in (the default transition)
.transition-in { opacity:0; position:absolute; } .passage:not(.transition-out) { transition: 1s; -webkit-transition: 1s; } .transition-out { opacity:0; position:absolute; }
:not(.transition-out)
means that the transition is applied only for the incoming passage - the departing one instantly gets opacity:0. Note that specifying passage.transition-in
would not do anything, since it is by removing the transition-in class that the transition is initiated.
Dissolve
.transition-in { position:absolute; opacity:0; } .passage { transition: 1s; -webkit-transition: 1s; } .transition-out { position:absolute; opacity:0; }
.transition-in { opacity:0; position:absolute; } .passage:not(.transition-out) { transition: 0.8s steps(3); -webkit-transition: 0.8s steps(3); } .transition-out { opacity:0; position:absolute; }
.transition-in { opacity:0; position:absolute; } .passage:not(.transition-out) { transition: 0s 1s; -webkit-transition: 0s 1s; } .transition-out { transition: 1s; -webkit-transition: 1s; opacity:0; position:absolute; }
Vertical wipe
Sadly, this currently only works if you give the passage div a fixed width and height.
If you use this, replace all instances of "1200px" and "800px" with dimensions appropriate for your story.
.transition-in { clip: rect(0px, 1200px, 0px, 0px) !important; } .passage { clip: rect(0px, 1200px, 800px, 0px); width: 1200px; height: 800px; position: absolute; transition: 1s linear; -webkit-transition: 1s linear; } .transition-out { clip: rect(800px, 1200px, 800px, 0px); }
.transition-in { opacity:0; transform: scale(0.8,0.8); -webkit-transform: scale(0.8,0.8); position:absolute; } .passage { width: calc(100% - 12em); // Necessary to keep the zoom origin point consistent. width: -webkit-calc(100% - 12em); transition: 0.5s ease-out; -webkit-transition: 0.5s ease-out; } .transition-out { opacity:0; transform: scale(2,2); -webkit-transform: scale(2,2); position:absolute; }
Fast scroll up
Ideally you would use "vh" (viewport height) units instead of "rem" (root em) units, but not enough browsers support it yet. ;_;
You can also make it a slow fading scroll if you change the lengths to something short (like 3rem).
.transition-in { opacity:0; transform: translate(0,-100rem); -webkit-transform: translate(0,-100rem); position:absolute; } .passage { transition: 1s; -webkit-transition: 1s; } .transition-out { opacity:0; transform: translate(0,100rem); -webkit-transform: translate(0,100rem); position:absolute; }
Garage door
This would work well with a story whose passage divs have a fixed width and height, but unlike the vertical wipe it isn't strictly necessary.
.transition-in { opacity:0; position:absolute; } .passage { background-color: #000; transition: 1s ease-in; -webkit-transition: 1s ease-in; } .transition-out { position:absolute; z-index:3; transform: translate(0,-200%); -webkit-transform: translate(0,-200%); }
.transition-in { color:transparent; text-shadow: #fff 0 0 1em; position:absolute; } .passage:not(.transition-out) { transition: 1s; -webkit-transition: 1s; } .transition-out { opacity:0; position:absolute; }
.transition-in { color:transparent; text-shadow: #fff -4em 0 1em, #fff 4em 0 1em; position:absolute; } .passage:not(.transition-out) { transition: 1s; -webkit-transition: 1s; } .transition-out { opacity:0; position:absolute; }
Attachment | Size |
---|---|
tsitr_fadein.html | 92.69 KB |
tsitr_fadeout.html | 92.74 KB |
tsitr_scrollup.html | 92.82 KB |
tsitr_focus.html | 92.76 KB |
tsitr_sillyrotate.html | 92.92 KB |
tsitr_retrofadein.html | 92.71 KB |
tsitr_spin5seconds.html | 92.98 KB |
tsitr_blur_merge.html | 92.74 KB |
tsitr_garagedoor.html | 92.78 KB |
tsitr_zoomin2.html | 92.92 KB |
tsitr_verticalwipe.html | 92.87 KB |
tsitr_t8ntest.html | 93.84 KB |
Comments
transition sandwich
hello glorious trainwreck,
we are trying to use your tag-based 'spin5seconds' feature
in the same twine story as this 'screen shake' macro:
https://gist.github.com/dariusk/4651698
however, the default mods for the transition css disable the
'screen shake'. any quick fix suggestions?
cheers!