Last updated: 14 Jun 24 14:23:01 (UTC)
Toggle dark/light theme (SugarCube)
14 June 2024
I used the link from https://hiev-heavy-ind.com/ on “A simple color-inversion theme toggle” - downloaded that Twine page and duplicated it. Essentially you create a new macro for SugarCube in this story that can be called anywhere by <<ToggleTheme>>:
- Create a new passage named “Global Widgets”, tag it with “widget” and “nobr”. In the body of this passage:
<<widget "ToggleTheme">>
Toggle Theme: <div class="toggle-wrapper">
<div class="rect_2"></div>
<div class="rect_1">
<div class="rect_1_inset"></div>
</div>
<div class="rect_3"></div>
<div class="toggle_handler">
<div class="toggle_ellipse"></div>
</div>
</div>
<</widget>><<widget "ToggleTheme">>
Toggle Theme: <div class="toggle-wrapper">
<div class="rect_2"></div>
<div class="rect_1">
<div class="rect_1_inset"></div>
</div>
<div class="rect_3"></div>
<div class="toggle_handler">
<div class="toggle_ellipse"></div>
</div>
</div>
<</widget>>Note that you can change the “Toggle Theme:” to whatever you want.
- In the CSS Stylesheet (Story > Stylesheet), put the following (edit as desired):
.invert {
filter: invert(100%);
}
.invert #menu li a {
color: #111;
}
.invert #menu li a:hover {
color: inherit;
}
/* Inverted Theme - End */
/* Toggle Switch - Start */
.toggle-wrapper {
position: relative;
top: 8px;
width: 91px;
height: 29px;
display: inline-flex;
}
.rect_1 {
position: absolute;
left: 4px;
top: 4px;
width: 80px;
height: 20px;
background-color: #d6503a;
border-radius: 9px;
box-shadow: 0 0 1px 0px #e1e1e1;
overflow: hidden;
transition: all 0.3s;
will-change: background-color;
}
.rect_1_inset {
position: absolute;
left: 32px;
top: -4px;
width: 48px;
height: 28px;
background-color: #3362a8;
background-image: linear-gradient(to top, #b6b8b3 0%, #b6b8b3 18%, #e1e2e1 62%, #e1e2e1 74%, #e1e2e1 100%, #e1e2e1 100%);
border-radius: 16px;
box-shadow: inset 0 0 2px rgba(255,255,255,0.35);
transition: all 0.2s;
will-change: transform;
}
.rect_2 {
position: absolute;
left: 0;
top: 0;
width: 84px;
height: 22px;
background-color: #3362a8;
background-image: linear-gradient(to right, #cbcbcb 0%, #cbcbcb 0%, #cdcdcd 100%);
border: 3px solid #e4e4e3;
border-radius: 14px;
}
.rect_3 {
position: absolute;
left: 4px;
top: 4px;
width: 80px;
height: 20px;
border-radius: 10px;
background-color: rgba(0,0,0,0);
box-shadow: inset 0 5px 25px 0 rgba(0,0,0,0.6);
}
.toggle_handler {
position: absolute;
left: 39px;
top: 3px;
width: 48px;
height: 22px;
background-color: #3362a8;
background-image: linear-gradient(to top, #bfbfbe 0%, #e1e2e1 64%, #f3f3f3 77%, #f3f3f3 100%, #f3f3f3 100%);
border-radius: 11px;
box-shadow: inset 0 0 2px rgba(255,255,255,0.35), 0 3px 3px rgba(0,0,0,0.5), 0 0 3px rgba(0,0,0,0.5);
transition: all 0.2s;
will-change: transform;
}
.toggle_ellipse {
position: absolute;
left: 28px;
top: 4px;
width: 14px;
height: 14px;
border-radius: 50%;
background-color: #3362a8;
background-image: linear-gradient(to top, #e1e2e1 0%, #e1e2e1 0%, #b6b8b3 100%, #c1c1c1 100%);
}
.toggle-wrapper.pushed .toggle_handler {
-webkit-transform: translate3d(-75%, 0, 0);
transform: translate3d(-75%, 0, 0);
}
.toggle-wrapper.pushed .rect_1_inset {
-webkit-transform: translate3d(-60%, 0, 0) scale(1, 1);
transform: translate3d(-60%, 0, 0) scale(1, 1);
}
.toggle-wrapper.pushed .rect_1 {
background-color: #4fade3;
}
/* Toggle Switch - End */.invert {
filter: invert(100%);
}
.invert #menu li a {
color: #111;
}
.invert #menu li a:hover {
color: inherit;
}
/* Inverted Theme - End */
/* Toggle Switch - Start */
.toggle-wrapper {
position: relative;
top: 8px;
width: 91px;
height: 29px;
display: inline-flex;
}
.rect_1 {
position: absolute;
left: 4px;
top: 4px;
width: 80px;
height: 20px;
background-color: #d6503a;
border-radius: 9px;
box-shadow: 0 0 1px 0px #e1e1e1;
overflow: hidden;
transition: all 0.3s;
will-change: background-color;
}
.rect_1_inset {
position: absolute;
left: 32px;
top: -4px;
width: 48px;
height: 28px;
background-color: #3362a8;
background-image: linear-gradient(to top, #b6b8b3 0%, #b6b8b3 18%, #e1e2e1 62%, #e1e2e1 74%, #e1e2e1 100%, #e1e2e1 100%);
border-radius: 16px;
box-shadow: inset 0 0 2px rgba(255,255,255,0.35);
transition: all 0.2s;
will-change: transform;
}
.rect_2 {
position: absolute;
left: 0;
top: 0;
width: 84px;
height: 22px;
background-color: #3362a8;
background-image: linear-gradient(to right, #cbcbcb 0%, #cbcbcb 0%, #cdcdcd 100%);
border: 3px solid #e4e4e3;
border-radius: 14px;
}
.rect_3 {
position: absolute;
left: 4px;
top: 4px;
width: 80px;
height: 20px;
border-radius: 10px;
background-color: rgba(0,0,0,0);
box-shadow: inset 0 5px 25px 0 rgba(0,0,0,0.6);
}
.toggle_handler {
position: absolute;
left: 39px;
top: 3px;
width: 48px;
height: 22px;
background-color: #3362a8;
background-image: linear-gradient(to top, #bfbfbe 0%, #e1e2e1 64%, #f3f3f3 77%, #f3f3f3 100%, #f3f3f3 100%);
border-radius: 11px;
box-shadow: inset 0 0 2px rgba(255,255,255,0.35), 0 3px 3px rgba(0,0,0,0.5), 0 0 3px rgba(0,0,0,0.5);
transition: all 0.2s;
will-change: transform;
}
.toggle_ellipse {
position: absolute;
left: 28px;
top: 4px;
width: 14px;
height: 14px;
border-radius: 50%;
background-color: #3362a8;
background-image: linear-gradient(to top, #e1e2e1 0%, #e1e2e1 0%, #b6b8b3 100%, #c1c1c1 100%);
}
.toggle-wrapper.pushed .toggle_handler {
-webkit-transform: translate3d(-75%, 0, 0);
transform: translate3d(-75%, 0, 0);
}
.toggle-wrapper.pushed .rect_1_inset {
-webkit-transform: translate3d(-60%, 0, 0) scale(1, 1);
transform: translate3d(-60%, 0, 0) scale(1, 1);
}
.toggle-wrapper.pushed .rect_1 {
background-color: #4fade3;
}
/* Toggle Switch - End */- In the JavaScript file (Story > JavaScript):
/* ToggleTheme JavaScript - Start */
Config.ui.updateStoryElements = false;
setup.clickToggleSwitch = function() {
if ($(".toggle-wrapper").hasClass("pushed")) {
$(".toggle-wrapper").removeClass("pushed");
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').removeClass("invert");
} else {
$(".toggle-wrapper").addClass("pushed");
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').addClass("invert");
}
};
$(document).on("click", ".toggle_handler", function (event) {
setup.clickToggleSwitch();
State.variables.toggle = $(".toggle-wrapper").hasClass("pushed");
});
var ivID = 0;
setup.setTheme = function() {
if (Engine.isIdle() || (ivID === 0)) {
console.log(ivID);
if (ivID !== 0) {
clearInterval(ivID);
ivID = 0;
}
if ($(".toggle-wrapper").hasClass("pushed")) {
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').addClass("invert");
} else {
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').removeClass("invert");
}
}
}
$(document).on(":passageend", function (event) {
if (State.variables.toggle === undefined) {
State.variables.toggle = false;
}
if (State.variables.toggle && !$(".toggle-wrapper").hasClass("pushed")) {
$(".toggle-wrapper").addClass("pushed");
}
if ($(".toggle-wrapper").hasClass("pushed")) {
ivID = setInterval(setup.setTheme, 10);
}
});
/* ToggleTheme JavaScript - End *//* ToggleTheme JavaScript - Start */
Config.ui.updateStoryElements = false;
setup.clickToggleSwitch = function() {
if ($(".toggle-wrapper").hasClass("pushed")) {
$(".toggle-wrapper").removeClass("pushed");
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').removeClass("invert");
} else {
$(".toggle-wrapper").addClass("pushed");
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').addClass("invert");
}
};
$(document).on("click", ".toggle_handler", function (event) {
setup.clickToggleSwitch();
State.variables.toggle = $(".toggle-wrapper").hasClass("pushed");
});
var ivID = 0;
setup.setTheme = function() {
if (Engine.isIdle() || (ivID === 0)) {
console.log(ivID);
if (ivID !== 0) {
clearInterval(ivID);
ivID = 0;
}
if ($(".toggle-wrapper").hasClass("pushed")) {
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').addClass("invert");
} else {
$('html, a, img:not([src*=\".svg\"]), video, .rect_1, .rect_2, .rect_3, .toggle_handler').removeClass("invert");
}
}
}
$(document).on(":passageend", function (event) {
if (State.variables.toggle === undefined) {
State.variables.toggle = false;
}
if (State.variables.toggle && !$(".toggle-wrapper").hasClass("pushed")) {
$(".toggle-wrapper").addClass("pushed");
}
if ($(".toggle-wrapper").hasClass("pushed")) {
ivID = setInterval(setup.setTheme, 10);
}
});
/* ToggleTheme JavaScript - End */- Where you want the toggle switch to appear (I put mine in the StoryAuthor passage, but it can also go in StoryCaption to appear in essentially the same place in the sidebar), call the macro with
<<ToggleTheme>>. - That’s it. Should work. Edit CSS as desired.