Skip to content

Commit

Permalink
Allow resetting the Konami Code effects for Paint
Browse files Browse the repository at this point in the history
  • Loading branch information
1j01 committed Apr 9, 2018
1 parent a578d1d commit cf5cce4
Showing 1 changed file with 187 additions and 149 deletions.
336 changes: 187 additions & 149 deletions programs/jspaint/src/vaporwave-fun.js
Original file line number Diff line number Diff line change
@@ -1,171 +1,209 @@
(function () {
var rAF_ID, rotologo, $window, space_phase_key_handler, player;
var vaporwave_active = false;

// TODO: make this whole thing work multiple times
// (and allow reseting the effect entirely by re-entering the Konami Code)

var start_movie = function () {

var rotologo = document.createElement("img");
rotologo.classList.add("rotologo");
if (frameElement) {
frameElement.parentElement.appendChild(rotologo);
rotologo.src = "images/logo/98.js.org.svg";
if (parent && frameElement && parent.$) {
$window = parent.$(frameElement).closest(".window");
} else {
document.body.appendChild(rotologo);
rotologo.src = "images/98.js.org.svg";
$window = $();
}

$(rotologo).css({
position: "absolute",
left: "50%",
top: "50%",
pointerEvents: "none",
transformOrigin: "0% 0%",
transition: "opacity 1s ease",
opacity: "0",
});

var animate = function () {
var rAF_ID = requestAnimationFrame(animate);
// cleanup = function(){
// cancelAnimationFrame(rAF_ID);
// };
var wait_for_youtube_api = function (callback) {
if (typeof YT !== "undefined") {
callback();
} else {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// The YouTube API will call this global function when loaded and ready.
window.onYouTubeIframeAPIReady = function () {
callback();
};
}
};

var stop_vaporwave = function () {
vaporwave_active = false;

cancelAnimationFrame(rAF_ID);

$(rotologo).remove();
$window.css({transform: ""});

removeEventListener("keydown", space_phase_key_handler);
if (player) {
player.destroy();
player = null;
}
// vaporwave is dead. long live vaporwave.
// bepis pepsi isded pepsi isded
};

var start_vaporwave = function () {
vaporwave_active = true;

rotologo = document.createElement("img");
rotologo.classList.add("rotologo");
if (frameElement) {
frameElement.parentElement.appendChild(rotologo);
rotologo.src = "images/logo/98.js.org.svg";
} else {
document.body.appendChild(rotologo);
rotologo.src = "images/98.js.org.svg";
}

$(rotologo).css({
transform:
`perspective(4000px) rotateY(${
Math.sin(Date.now() / 5000)
}turn) rotateX(${
0
}turn) translate(-50%, -50%) translateZ(500px)`,
filter:
`hue-rotate(${
Math.sin(Date.now() / 4000)
// TODO: slow down and stop when you pause
}turn)`,
position: "absolute",
left: "50%",
top: "50%",
pointerEvents: "none",
transformOrigin: "0% 0%",
transition: "opacity 1s ease",
opacity: "0",
});

var $window = parent.$(frameElement).closest(".window");
if($window.length){
var el = $window[0];
var offsetLeft = 0;
var offsetTop = 0;
do {
offsetLeft += el.offsetLeft;
offsetTop += el.offsetTop;
el = el.offsetParent;
} while (el);

$window.css({

var animate = function () {
rAF_ID = requestAnimationFrame(animate);

$(rotologo).css({
transform:
`perspective(4000px) rotateY(${
-(offsetLeft + ($window.outerWidth() - parent.innerWidth) / 2) / parent.innerWidth / 3
Math.sin(Date.now() / 5000)
}turn) rotateX(${
(offsetTop + ($window.outerHeight() - parent.innerHeight) / 2) / parent.innerHeight / 3
0
}turn) translate(-50%, -50%) translateZ(500px)`,
filter:
`hue-rotate(${
Math.sin(Date.now() / 4000)
// TODO: slow down and stop when you pause
}turn)`,
transformOrigin: "50% 50%",
transformStyle: "preserve-3d",
// FIXME: interactivity problems (with order elements are considered to have), I think related to preserve-3d
});
}
};
animate();

var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
var player_placeholder = document.createElement("div");
document.querySelector(".canvas-area").appendChild(player_placeholder);
$(player_placeholder).css({
position: "absolute",
top: "3px", // TODO: dynamic
left: "3px",
mixBlendMode: "multiply",
pointerEvents: "none",
transition: "opacity 0.4s ease",
width: "100vw",
height: "100vh",
});
// NOTE: placeholder not a container; the YT API replaces the element passed in the DOM
// but keeps inline styles apparently, and maybe other things, I don't know; it's weird

// The YouTube API will call this global function when loaded and ready.
window.onYouTubeIframeAPIReady = function () {
player = new YT.Player(player_placeholder, {
height: "390",
width: "640",
videoId: "8TvcyPCgKSU",
playerVars: {
autoplay: 1,
controls: 0,
},
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange,
},

if ($window.length) {
var el = $window[0];
var offsetLeft = 0;
var offsetTop = 0;
do {
offsetLeft += el.offsetLeft;
offsetTop += el.offsetTop;
el = el.offsetParent;
} while (el);

$window.css({
transform:
`perspective(4000px) rotateY(${
-(offsetLeft + ($window.outerWidth() - parent.innerWidth) / 2) / parent.innerWidth / 3
}turn) rotateX(${
(offsetTop + ($window.outerHeight() - parent.innerHeight) / 2) / parent.innerHeight / 3
}turn)`,
transformOrigin: "50% 50%",
transformStyle: "preserve-3d",
// FIXME: interactivity problems (with order elements are considered to have), I think related to preserve-3d
});
}
};
animate();

var player_placeholder = document.createElement("div");
document.querySelector(".canvas-area").appendChild(player_placeholder);
$(player_placeholder).css({
position: "absolute",
top: "3px", // TODO: dynamic
left: "3px",
mixBlendMode: "multiply",
pointerEvents: "none",
transition: "opacity 0.4s ease",
width: "100vw",
height: "100vh",
});
// TODO: attribution for this video!
// I mean, you can see the title if you hit spacebar, but
// I could make it wave across the screen behind Paint on the desktop
// I could add a "Song Name?" button that responds "Darude Sandstorm"
// I could add a "Song At 420?" button that actually links to the video
// some number of those things or something like that
};
// NOTE: placeholder not a container; the YT API replaces the element passed in the DOM
// but keeps inline styles apparently, and maybe other things, I don't know; it's weird

// The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.playVideo();
// TODO: unmute if muted?
player.unMute();
}
wait_for_youtube_api(function () {
player = new YT.Player(player_placeholder, {
height: "390",
width: "640",
videoId: "8TvcyPCgKSU",
playerVars: {
autoplay: 1,
controls: 0,
},
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange,
},
});
// TODO: attribution for this video!
// I mean, you can see the title if you hit spacebar, but
// I could make it wave across the screen behind Paint on the desktop
// I could add a "Song Name?" button that responds "Darude Sandstorm"
// I could add a "Song At 420?" button that actually links to the video
// some number of those things or something like that
});

// The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
// TODO: pause and resume this timer with the video
setTimeout(function(){
$(rotologo).css({opacity: 1});
}, 14150);
// The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.playVideo();
player.unMute();
}
if (event.data == YT.PlayerState.ENDED) {
player.destroy();
// TODO: fade to white instead of black, to work with the multiply effect
// or fade out opacity alternatively
// setTimeout/setInterval and check player.getCurrentTime() for when near the end?
// or we might switch to using soundcloud for the audio and so trigger it with that, with a separate video of just clouds
// also fade out the rotologo earlier
$(rotologo).css({opacity: 0});
// TODO: destroy rotologo once faded out

// The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
// TODO: pause and resume this timer with the video
setTimeout(function(){
$(rotologo).css({opacity: 1});
}, 14150);
}
if (event.data == YT.PlayerState.ENDED) {
player.destroy();
player = null;
// TODO: fade to white instead of black, to work with the multiply effect
// or fade out opacity alternatively
// setTimeout/setInterval and check player.getCurrentTime() for when near the end?
// or we might switch to using soundcloud for the audio and so trigger it with that, with a separate video of just clouds
// also fade out the rotologo earlier
$(rotologo).css({opacity: 0});
// destroy rotologo once faded out
setTimeout(stop_vaporwave, 1200);
}
}
}
function stopVideo() {
player.stopVideo();
}

var is_theoretically_playing = true;
var space_phase_key_handler = function (e) {
if (e.which === 32) {
// TODO: record player SFX
if (is_theoretically_playing) {
player.pauseVideo();
is_theoretically_playing = false;
$(player.getIframe())
.add(rotologo)
.css({opacity: "0"});
} else {
player.playVideo();
is_theoretically_playing = true;
$(player.getIframe())
.add(rotologo)
.css({opacity: ""});
var is_theoretically_playing = true;
space_phase_key_handler = function (e) {
// press space to phase in and out of space phase スペース相 - windows 98 マイクロソフト 『WINTRAP』 X 将来のオペレーティングシステムサウンド 1998 VAPORWAVE
if (e.which === 32) {
// TODO: record player SFX
if (is_theoretically_playing) {
player.pauseVideo();
is_theoretically_playing = false;
$(player.getIframe())
.add(rotologo)
.css({opacity: "0"});
} else {
player.playVideo();
is_theoretically_playing = true;
$(player.getIframe())
.add(rotologo)
.css({opacity: ""});
}
e.preventDefault();
// player.getIframe().focus();
}
e.preventDefault();
// player.getIframe().focus();
};
addEventListener("keydown", space_phase_key_handler);
};

var toggle_vaporwave = function () {
if (vaporwave_active) {
stop_vaporwave();
} else {
start_vaporwave();
}
};
addEventListener("keydown", space_phase_key_handler);
};

addEventListener("keydown", Konami.code(start_movie));
addEventListener("keydown", Konami.code(toggle_vaporwave));

}());

0 comments on commit cf5cce4

Please sign in to comment.