Skip to content

Instantly share code, notes, and snippets.

@ohiofi
Forked from dariusk/README.md
Last active November 25, 2015 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ohiofi/a36f4162d1f57e745d9b to your computer and use it in GitHub Desktop.
Save ohiofi/a36f4162d1f57e745d9b to your computer and use it in GitHub Desktop.
Twine screenShake macro

This Twine version 1 macro lets you make the screen shake! Tested in Chrome and Firefox. Should work in Opera and IE 10+. Uses CSS3 animations, taken from this CSS Reset tutorial.

See a demo in action here.

How to set it up

IMPORTANT NOTE: Due to a bug in Twine 1.3.5, macros did not work on the Start passage. This issue has been fixed in Twine 1.4.1.

  • Paste the contents of the stylesheet.css file below into a new passage. Call the passage whatever you want, and add the tag "stylesheet" to it.
  • Paste the contents of the script.js file below into a new passage. Call the passage whatever you want, and add the tag "script" to it.
  • Paste the contents of the twineCode file below into your 'ActualStart' passage described above. This will make the screen shake for 5 seconds!

How to use it

Put the following in any passage where you want the screen to shake:

<<screenShake [milliseconds]>>

This tells the screen to shake for a certain number of milliseconds. For example, if you want the screen to shake for 1.5 seconds, put this in your passage:

<<screenShake 1500>>

1000 milliseconds = 1 second, so 1500 milliseconds = 1.5 seconds.

If you set the milliseconds to 0, the screen will shake forever (until the reader moves to a new page)!

// the screenShake macro. Created by dariusk. Edited by 20hz20khz for Twine 1.4.1. Adapted from Emmanuel Turner's article on creating Twine macros. http://eturnerx.blogspot.com/2012/12/how-to-create-custom-macros-in-twine.html
try {
version.extensions['screenShakeMacro'] = {
major: 1,
minor: 0,
revision: 0
};
macros['screenShake'] = {
handler: function (place, macroName, params, parser) {
var time = parseInt(params[0]);
if (typeof time !== 'number') {
time = 1000;
}
var el = document.body;
baz = el;
console.log(baz[0]);
document.body.className = 'shake';
if (time > 0){
setTimeout(function(){document.body.className='';},time);
};
// we're overriding the fade function. It behaves as usual except it runs screenShake() if time >= 0.
fade = function (el, options) {
var current;
var proxy = el.cloneNode(true);
var direction = (options.fade == 'in') ? 1 : -1;
el.parentNode.replaceChild(proxy, el);
if (options.fade == 'in') {
current = 0;
proxy.style.visibility = 'visible';
} else current = 1;
setOpacity(proxy, current);
var interval = window.setInterval(tick, 25);
function tick() {
current += 0.05 * direction;
setOpacity(proxy, Math.easeInOut(current));
if (((direction == 1) && (current >= 1)) || ((direction == -1) && (current <= 0))) {
console.log('swapping fader proxy out');
el.style.visibility = (options.fade == 'in') ? 'visible' : 'hidden';
proxy.parentNode.replaceChild(el, proxy);
delete proxy;
window.clearInterval(interval);
if (options.onComplete) options.onComplete();
if (time >= 0) {
time = -1;
}
}
};
function setOpacity(el, opacity) {
var percent = Math.floor(opacity * 100);
// IE
el.style.zoom = 1;
el.style.filter = 'alpha(opacity=' + percent + ')';
// CSS 3
el.style.opacity = opacity;
};
};
},
init: function () {},
};
} catch (e) {
throwError(place, "screenShake Setup Error: " + e.message);
}
@keyframes shakeit {
0% { transform: translate(2px, 1px) rotate(0deg); }
10% { transform: translate(-1px, -2px) rotate(-1deg); }
20% { transform: translate(-3px, 0px) rotate(1deg); }
30% { transform: translate(0px, 2px) rotate(0deg); }
40% { transform: translate(1px, -1px) rotate(1deg); }
50% { transform: translate(-1px, 2px) rotate(-1deg); }
60% { transform: translate(-3px, 1px) rotate(0deg); }
70% { transform: translate(2px, 1px) rotate(-1deg); }
80% { transform: translate(-1px, -1px) rotate(1deg); }
90% { transform: translate(2px, 2px) rotate(0deg); }
100% { transform: translate(1px, -2px) rotate(-1deg); }
}
@-o-keyframes shakeit {
0% { -o-transform: translate(2px, 1px) rotate(0deg); }
10% { -o-transform: translate(-1px, -2px) rotate(-1deg); }
20% { -o-transform: translate(-3px, 0px) rotate(1deg); }
30% { -o-transform: translate(0px, 2px) rotate(0deg); }
40% { -o-transform: translate(1px, -1px) rotate(1deg); }
50% { -o-transform: translate(-1px, 2px) rotate(-1deg); }
60% { -o-transform: translate(-3px, 1px) rotate(0deg); }
70% { -o-transform: translate(2px, 1px) rotate(-1deg); }
80% { -o-transform: translate(-1px, -1px) rotate(1deg); }
90% { -o-transform: translate(2px, 2px) rotate(0deg); }
100% { -o-transform: translate(1px, -2px) rotate(-1deg); }
}
@-webkit-keyframes shakeit {
0% { -webkit-transform: translate(2px, 1px) rotate(0deg); }
10% { -webkit-transform: translate(-1px, -2px) rotate(-1deg); }
20% { -webkit-transform: translate(-3px, 0px) rotate(1deg); }
30% { -webkit-transform: translate(0px, 2px) rotate(0deg); }
40% { -webkit-transform: translate(1px, -1px) rotate(1deg); }
50% { -webkit-transform: translate(-1px, 2px) rotate(-1deg); }
60% { -webkit-transform: translate(-3px, 1px) rotate(0deg); }
70% { -webkit-transform: translate(2px, 1px) rotate(-1deg); }
80% { -webkit-transform: translate(-1px, -1px) rotate(1deg); }
90% { -webkit-transform: translate(2px, 2px) rotate(0deg); }
100% { -webkit-transform: translate(1px, -2px) rotate(-1deg); }
}
@-moz-keyframes shakeit {
0% { -moz-transform: translate(2px, 1px) rotate(0deg); }
10% { -moz-transform: translate(-1px, -2px) rotate(-1deg); }
20% { -moz-transform: translate(-3px, 0px) rotate(1deg); }
30% { -moz-transform: translate(0px, 2px) rotate(0deg); }
40% { -moz-transform: translate(1px, -1px) rotate(1deg); }
50% { -moz-transform: translate(-1px, 2px) rotate(-1deg); }
60% { -moz-transform: translate(-3px, 1px) rotate(0deg); }
70% { -moz-transform: translate(2px, 1px) rotate(-1deg); }
80% { -moz-transform: translate(-1px, -1px) rotate(1deg); }
90% { -moz-transform: translate(2px, 2px) rotate(0deg); }
100% { -moz-transform: translate(1px, -2px) rotate(-1deg); }
}
.shake {
-webkit-animation-name: shakeit;
-webkit-animation-duration: 0.8s;
-webkit-transform-origin:50% 50%;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-name: shakeit;
-moz-animation-duration: 0.8s;
-moz-transform-origin:50% 50%;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
-o-animation-name: shakeit;
-o-animation-duration: 0.8s;
-o-transform-origin:50% 50%;
-o-animation-iteration-count: infinite;
-o-animation-timing-function: linear;
animation-name: shakeit;
animation-duration: 0.8s;
transform-origin:50% 50%;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
THIS PASSAGE IS SHAKING FOR TWO SECONDS, WHOAAAAA!!!!
<<screenShake 2000>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment