
【ティラノスクリプト】メニュー画面のサンプル

メニュー画面のサンプルです。
【参考記事】
上記の記事を参考にさせていただきました。
【注意①】
ティラノスクリプト本体を改造しています。
不具合が発生した場合は、お手数をおかけしますが、今回貼り付けたコードを削除してください。
【注意②】
お使いのバージョンによっては使用できない場合があります。
Ver525b(2024/8/7 更新)
上記のバージョンで動作を確認しています。
【first.ks】
;data/others/js/main.jsを読み込み
[loadjs storage="js/main.js"]
;data/others/html/menu.htmlを読み込み
[sysview type="menu" storage="./data/others/html/menu.html"]
;data/others/css/style.cssを読み込み
[loadcss file="./data/others/css/style.css"]
【main.js】
TYRANO.kag.menu.showMenu = function (call_back) {
if (this.kag.layer.layer_event.css("display") == "none" && this.kag.stat.is_strong_stop != true) {
return false;
}
if (this.kag.stat.is_wait == true) {
return false;
}
var that = this;
that.kag.unfocus();
this.kag.setSkip(false);
this.kag.setAuto(false);
this.kag.stat.is_auto_wait = false;
var layer_menu = this.kag.layer.getMenuLayer();
layer_menu.empty();
var button_clicked = false;
this.kag.html(
"menu",
{
novel: $.novel
},
function (html_str) {
var j_menu = $(html_str);
layer_menu.append(j_menu);
layer_menu
.find(".menu_skip")
.click(function (e) {
layer_menu.html("");
layer_menu.hide();
if (that.kag.stat.visible_menu_button == true) {
$(".button_menu").show();
}
that.kag.setSkip(true);
if (that.kag.layer.layer_event.css("display") == "none") {
} else {
that.kag.ftag.nextOrder();
}
e.stopPropagation();
})
.focusable();
layer_menu
.find(".menu_auto")
.click(function (e) {
layer_menu.html("");
layer_menu.hide();
if (that.kag.stat.visible_menu_button == true) {
$(".button_menu").show();
}
that.kag.setAuto(true);
if (that.kag.layer.layer_event.css("display") == "none") {
} else {
that.kag.ftag.nextOrder();
}
e.stopPropagation();
})
.focusable();
that.setMenuCloseEvent(layer_menu);
that.setHoverEvent(layer_menu);
layer_menu
.find(".menu_window_close")
.click(function (e) {
that.kag.layer.hideMessageLayers();
layer_menu.html("");
layer_menu.hide();
if (that.kag.stat.visible_menu_button == true) {
$(".button_menu").show();
}
e.stopPropagation();
})
.focusable();
layer_menu
.find(".menu_save")
.click(function (e) {
if (button_clicked == true) {
return;
}
button_clicked = true;
that.kag.makeUnfocusableAll(layer_menu);
that.displaySave();
e.stopPropagation();
})
.focusable();
layer_menu
.find(".menu_load")
.click(function (e) {
if (button_clicked == true) {
return;
}
button_clicked = true;
that.kag.makeUnfocusableAll(layer_menu);
that.displayLoad();
e.stopPropagation();
})
.focusable();
layer_menu
.find(".menu_log")
.click(function (e) {
if (button_clicked == true) {
return;
}
button_clicked = true;
that.kag.makeUnfocusableAll(layer_menu);
that.displayLog();
e.stopPropagation();
})
.focusable();
layer_menu
.find(".menu_back_title")
.click(function () {
that.kag.backTitle();
})
.focusable();
$.preloadImgCallback(
j_menu,
function () {
layer_menu.stop(true, true).fadeIn('fast', function() {
$('.menu_wrapper').addClass('open');
});
$(".button_menu").hide();
},
that
);
}
);
};
TYRANO.kag.menu.setMenuCloseEvent = function (j_parent, options = {}) {
const j_menu = this.kag.layer.getMenuLayer();
const target_selector = options.target || ".menu_close";
j_parent
.find(target_selector)
.click((e) => {
if ( $("#menu_save_wrapper").length == 0 && $("#menu_load_wrapper").length == 0 && $("#menu_backlog_wrapper").length == 0 ) {
$('.menu_wrapper').removeClass('open');
$('.menu_wrapper').on('transitionend', function(event) {
if (event.target === this && !$(this).hasClass('open')) {
j_menu.hide();
j_menu.empty();
if (typeof options.callback == "function") {
options.callback();
}
}
});
} else {
j_menu.fadeOut(300, () => {
j_menu.empty();
if (typeof options.callback == "function") {
options.callback();
}
});
}
if (this.kag.stat.visible_menu_button == true) {
$(".button_menu").show();
}
e.stopPropagation();
})
.focusable();
};
TYRANO.kag.menu.displayLog = function () {
var that = this;
that.kag.unfocus();
this.kag.setSkip(false);
var j_save = $("<div></div>");
this.kag.html(
"backlog",
{
novel: $.novel
},
function (html_str) {
var j_menu = $(html_str);
var layer_menu = that.kag.layer.getMenuLayer();
j_menu.hide();
layer_menu.append(j_menu);
layer_menu.show();
that.setMenuCloseEvent(layer_menu);
that.setHoverEvent(layer_menu);
that.setMenuScrollEvents(j_menu, { target: ".log_body", move: 60 });
j_menu.find(".log_body").on("touchmove", (e) => {
e.stopPropagation();
});
var log_str = "";
var array_log = that.kag.variable.tf.system.backlog;
for (var i = 0; i < array_log.length; i++) {
log_str += array_log[i] + "<br />";
}
layer_menu.find(".log_body").html(log_str);
layer_menu.find(".log_body").css("font-family", that.kag.config.userFace);
$.preloadImgCallback(
layer_menu,
function () {
j_menu.stop(true, true).fadeIn(300);
layer_menu.find(".log_body").scrollTop(9999999999);
layer_menu.find(".block_menu").fadeOut(300);
},
that
);
$(".button_menu").hide();
}
);
};
【menu.html】
<div class="display_menu block_menu">
<div class="menu_wrapper">
<div class="menu_close">
</div>
<div class="menu_button">
<div class="menu_save">SAVE</div>
<div class="menu_load">LOAD</div>
<div class="menu_log">BACKLOG</div>
<div class="menu_window_close">WINDOW HIDE</div>
<div class="menu_auto">AUTO</div>
<div class="menu_skip">SKIP</div>
<div class="menu_back_title">TITLE</div>
</div>
</div>
</div>
【style.css】
/* メニュー全体のラッパー(初期状態は非表示) */
.menu_wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.8);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease-in-out;
}
/* open クラスがついたときの表示状態 */
.menu_wrapper.open {
opacity: 1;
pointer-events: auto;
}
/* 閉じるボタン(右上の✕ボタン) */
.menu_wrapper .menu_close {
position: absolute;
top: 32px;
right: 32px;
width: 40px;
height: 40px;
cursor: pointer;
opacity: 1;
transition: opacity 0.3s ease-in-out;
}
/* ✕ の線 */
.menu_wrapper .menu_close::before,
.menu_wrapper .menu_close::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 80%;
height: 10%;
background-color: #fff;
transform-origin: center;
transition: background-color 0.3s;
}
/* 45度回転 */
.menu_wrapper .menu_close::before {
transform: translate(-50%, -50%) rotate(45deg);
}
/* -45度回転 */
.menu_wrapper .menu_close::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
/* ホバー時の色変更 */
.menu_wrapper .menu_close:hover::before,
.menu_wrapper .menu_close:hover::after {
background-color: #ccc;
}
/* ボタンリスト */
.menu_button {
display: flex;
flex-direction: column;
align-items: center;
}
/* ボタンの共通スタイル */
.menu_button > div {
padding: 10px;
text-align: center;
font-weight: bold;
font-size: 32px;
color: #fff;
cursor: pointer;
background-color: transparent;
border: none;
opacity: 0;
transform: translateX(-30px); /* 左から */
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
/* open クラスがついたときのボタン表示(時間差あり) */
.menu_wrapper.open .menu_button > div {
opacity: 1;
transform: translateX(0);
}
/* ボタンの間隔 */
.menu_button > div + div {
margin-top: 10px;
}
/* ボタンのホバーエフェクト */
.menu_button > div:hover {
color: #ccc !important;
}
/* 各ボタンに時間差をつける(開くとき) */
.menu_wrapper.open .menu_button > div:nth-child(1) { transition-delay: 0.1s; }
.menu_wrapper.open .menu_button > div:nth-child(2) { transition-delay: 0.2s; }
.menu_wrapper.open .menu_button > div:nth-child(3) { transition-delay: 0.3s; }
.menu_wrapper.open .menu_button > div:nth-child(4) { transition-delay: 0.4s; }
.menu_wrapper.open .menu_button > div:nth-child(5) { transition-delay: 0.5s; }
.menu_wrapper.open .menu_button > div:nth-child(6) { transition-delay: 0.6s; }
.menu_wrapper.open .menu_button > div:nth-child(7) { transition-delay: 0.7s; }
/* 閉じる時は逆のアニメーション(右へフェードアウト) */
.menu_wrapper:not(.open) .menu_button > div {
opacity: 0;
transform: translateX(30px); /* 右へ */
}
/* 各ボタンの非表示アニメーションを **順番に** 実行 */
.menu_wrapper:not(.open) .menu_button > div:nth-child(1) { transition-delay: 0.1s; }
.menu_wrapper:not(.open) .menu_button > div:nth-child(2) { transition-delay: 0.2s; }
.menu_wrapper:not(.open) .menu_button > div:nth-child(3) { transition-delay: 0.3s; }
.menu_wrapper:not(.open) .menu_button > div:nth-child(4) { transition-delay: 0.4s; }
.menu_wrapper:not(.open) .menu_button > div:nth-child(5) { transition-delay: 0.5s; }
.menu_wrapper:not(.open) .menu_button > div:nth-child(6) { transition-delay: 0.6s; }
.menu_wrapper:not(.open) .menu_button > div:nth-child(7) { transition-delay: 0.7s; }
/* menu_wrapper のフェードアウトを最後に実行(全ボタンが消えた後) */
.menu_wrapper:not(.open) {
transition-delay: 0.8s; /* 最後のボタンが消えた後に開始 */
}