added vertical mode and optimised layout for mobile

This commit is contained in:
Daniel Ledda
2021-10-19 18:57:36 +02:00
parent 342e65345d
commit f3851f32cd
20 changed files with 280 additions and 8593 deletions

8622
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,5 +28,8 @@
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
},
"dependencies": {
"file-loader": "^6.2.0"
}
}

View File

View File

@@ -1,6 +1,6 @@
import "./main.css";
import BeatGroup from "./BeatGroup";
import RootView from "./ui/Root/RootView";
import "./ui/global.css";
const defaultSettings = {
barCount: 2,

View File

@@ -3,26 +3,54 @@
padding-left: 1em;
}
.vertical-mode .beat > * {
padding-right: 0;
padding-left: 0;
}
.beat-unit-block {
height: 2em;
}
.vertical-mode .beat-unit-block {
height: auto;
width: 2em;
}
.beat-title {
width: 3em;
line-height: 32px;
margin: 0;
}
.vertical-mode .beat-title {
display: block;
width: auto;
text-align: center;
}
.beat-spacer {
display: inline-block;
width: 1em;
height: 2em;
}
.vertical-mode .beat-spacer {
display: block;
width: 2em;
height: 1em;
}
.beat-main {
display: inline-flex;
}
.vertical-mode .beat-main {
width: 2em;
margin-right: 4px;
display: block;
}
.beat-settings-container {
display: flex;
}
@@ -30,4 +58,8 @@
.beat {
width: max-content;
margin-bottom: 4px;
}
.vertical-mode .beat {
display: inline-block;
}

View File

@@ -11,6 +11,11 @@
cursor: pointer;
}
.vertical-mode .beat-unit {
margin-bottom: 4px;
display: block;
}
.beat-unit:hover {
border-color: var(--color-ui-neutral-dark-hover);
background-color: var(--color-ui-neutral-dark-hover);

View File

@@ -1,4 +1,15 @@
.beat-group {
padding: 1em;
overflow-x: scroll;
}
overflow-y: hidden;
display: flex;
width: inherit;
flex-direction: column;
}
.vertical-mode .beat-group {
height: inherit;
overflow-x: hidden;
overflow-y: scroll;
display: block;
}

View File

@@ -1,4 +1,3 @@
import BeatLikeLoopSettingsView from "../BeatLikeLoopSettings/BeatLikeLoopSettingsView";
import "./BeatGroupSettings.css";
import UINode, {UINodeOptions} from "../UINode";
import NumberInputView from "../Widgets/NumberInput/NumberInputView";
@@ -30,6 +29,7 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
BeatEvents.DisplayTypeChanged,
BeatGroupEvents.BeatListChanged,
BeatGroupEvents.LockingChanged,
BeatGroupEvents.AutoBeatSettingsChanged,
]);
}
@@ -46,6 +46,8 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
} else {
this.barCountInput.enable();
}
} else if (event === BeatGroupEvents.AutoBeatSettingsChanged) {
this.autoBeatLengthCheckbox.setValue(this.beatGroup.autoBeatLengthOn());
}
}

View File

@@ -13,19 +13,32 @@
}
.root {
position: relative;
overflow: hidden;
color: var(--color-p-light);
background-color: var(--color-bg-dark);
height: 100vh;
display: flex;
align-content: center;
}
.root-settings {
background-color: var(--color-bg-light);
height: 100%;
.root-sidebar {
position: absolute;
left: -28em;
width: 30em;
padding: 0 2em 0 2em;
height: 100vh;
display: flex;
transition: left 400ms;
}
.sidebar-visible .root-sidebar {
left: 0;
}
.root-settings {
z-index: 1;
width: 28em;
padding: 0 0 0 2em;
background-color: var(--color-bg-light);
overflow: scroll;
display: inline-block;
}
@@ -35,19 +48,86 @@
text-align: center;
}
.root-sidebar-toggle {
z-index: 1;
height: 100vh;
min-width: 2em;
background-color: var(--color-bg-light);
left: 0;
}
.root-hamburger {
right: 0;
width: 2em;
height: 2em;
cursor: pointer;
mask-image: url(./drawing.svg);
mask-size: 2em;
background-color: var(--color-ui-neutral-dark);
}
.root-switch-mode {
right: 0;
width: 2em;
height: 2em;
cursor: pointer;
mask-image: url(./rotate.svg);
mask-size: 2em;
background-color: var(--color-ui-neutral-dark);
}
.root-beat-stage-container {
flex: 1;
position: absolute;
height: 100%;
width: calc(100vw - 30em);
left: 0;
width: 100vw;
display: flex;
justify-content: center;
flex-direction: column;
transition: left 400ms, width 400ms;
}
.sidebar-visible .root-beat-stage-container {
left: 30em;
width: calc(100vw - 30em);
}
.root-beat-stage {
max-width: calc(100vw - 30em);
overflow: hidden;
padding: 2em;
max-height: 100vh;
margin: auto;
max-width: 100vw;
transition: max-width 400ms;
}
.vertical-mode .root-beat-stage {
height: 100vh;
}
.sidebar-visible .root-beat-stage {
max-width: calc(100vw - 30em);
}
@media screen and (max-width: 900px) {
.sidebar-visible .root-sidebar {
left: 0;
width: 100vw;
}
.root-sidebar {
left: calc(-100vw + 2em);
width: 100vw;
}
.root-settings {
width: calc(100vw - 2em);
}
.sidebar-visible .root-beat-stage-container {
left: 100vw;
}
.root-beat-stage-container {
left: 0;
}
.sidebar-visible .root-beat-stage {
max-width: 100vw;
}
}
* {

View File

@@ -14,6 +14,7 @@ export default class RootView extends UINode {
private beatGroupView: BeatGroupView;
private mainBeatGroup: BeatGroup;
private beatGroupSettingsView!: BeatGroupSettingsView;
private sidebar!: HTMLDivElement;
constructor(options: RootUINodeOptions) {
@@ -23,18 +24,47 @@ export default class RootView extends UINode {
this.title = options.title;
}
rebuild(): HTMLDivElement {
toggleSidebar(): void {
this.node!.classList.toggle("sidebar-visible");
}
toggleOrientation(): void {
this.node!.classList.toggle("vertical-mode");
}
rebuild(): HTMLElement {
this.beatGroupSettingsView = new BeatGroupSettingsView({beatGroup: this.mainBeatGroup});
return UINode.make("div", {
classes: ["root"],
const sidebarMain = UINode.make("div", {
classes: ["root-settings"],
subs: [
UINode.make("h1", {innerText: this.title, classes: ["root-title"]}),
this.beatGroupSettingsView.render(),
]
});
const sidebarToggle = UINode.make("div", {
classes: ["root-sidebar-toggle"],
subs: [
UINode.make("div", {
classes: ["root-settings"],
subs: [
UINode.make("h1", {innerText: this.title, classes: ["root-title"]}),
this.beatGroupSettingsView.render(),
]
classes: ["root-hamburger"],
onclick: () => this.toggleSidebar(),
}),
UINode.make("div", {
classes: ["root-switch-mode"],
onclick: () => this.toggleOrientation(),
})
]
});
this.sidebar = UINode.make("div", {
classes: ["root-sidebar"],
subs: [
sidebarMain,
sidebarToggle,
]
});
this.node = UINode.make("div", {
classes: ["root", "sidebar-visible"],
subs: [
this.sidebar,
UINode.make("div", {
classes: ["root-beat-stage-container"],
subs: [
@@ -48,5 +78,6 @@ export default class RootView extends UINode {
})
],
});
return this.node;
}
}

View File

@@ -2,11 +2,13 @@
height: 1.1em;
margin: 0.5em;
line-height: 1em;
cursor: pointer;
}
.bool-box-label {
display: inline-block;
margin-right: 0.5em;
cursor: pointer;
}
input.bool-box-checkbox[type="checkbox"] {
@@ -20,6 +22,7 @@ input.bool-box-checkbox[type="checkbox"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
cursor: pointer;
}
input.bool-box-checkbox[type="checkbox"]::before {

View File

@@ -39,6 +39,9 @@ export default class BoolBoxView extends UINode {
this.labelElement = UINode.make("label", {
classes: ["bool-box-label"],
innerText: this.label ?? "",
onclick: () => {
this.onInput(!this.checkboxElement.checked);
},
});
if (this.label !== null) {
this.labelElement.classList.add("visible");
@@ -46,7 +49,9 @@ export default class BoolBoxView extends UINode {
this.checkboxElement = UINode.make("input", {
type: "checkbox",
classes: ["bool-box-checkbox"],
oninput: (event: Event) => this.onInput((event.target as HTMLInputElement).checked),
onclick: (event: Event) => {
this.onInput((event.target as HTMLInputElement).checked);
},
});
return UINode.make("div", {
classes: ["bool-box"],

View File

@@ -64,34 +64,38 @@ button:focus {
::-webkit-scrollbar {
background-color: transparent;
}
body {
scrollbar-width: thin;
scrollbar-color: var(--color-ui-neutral-dark) transparent;
}
::-webkit-scrollbar-thumb {
background-color: rgba(0,0,0);
background-color: rgba(0,0,0,0);
}
@font-face {
font-family: 'DMSans';
font-style: normal;
font-weight: 400;
src: url(/static/DMSans-Regular.ttf) format('woff2');
src: url(./DMSans-Regular.ttf) format('woff2');
}
@font-face {
font-family: 'DMSans';
font-style: normal;
font-weight: 600;
src: url(/static/DMSans-Bold.ttf) format('woff2');
src: url(./DMSans-Bold.ttf) format('woff2');
}
@font-face {
font-family: 'DMSans';
font-style: italic;
font-weight: 400;
src: url(/static/DMSans-Italic.ttf) format('woff2');
src: url(./DMSans-Italic.ttf) format('woff2');
}
@font-face {
font-family: 'DMSans';
font-style: italic;
font-weight: 600;
src: url(/static/DMSans-BoldItalic.ttf) format('woff2');
src: url(./DMSans-BoldItalic.ttf) format('woff2');
}

View File

@@ -25,18 +25,20 @@ const webpackConfig = {
}, {
loader: "css-loader",
options: {
url: true,
sourceMap: true
}
}]
},
{
test: /\.(png|jpe?g|gif|ttf|woff2?|eot|svg)$/i,
use: [
{
loader: "file-loader",
},
],
}]
// {
// test: /\.(png|jpe?g|gif|ttf|woff2?|eot|svg)$/i,
// use: [
// {
// loader: "file-loader",
// },
// ],
// }
]
},
resolve: {
@@ -45,13 +47,14 @@ const webpackConfig = {
output: {
filename: "bundle.js",
publicPath: "/static",
publicPath: "/static/",
path: path.resolve(__dirname, "./public/static/"),
},
devServer: {
static: {
directory: path.join(__dirname, "./public"),
publicPath: "/",
},
hot: true,
compress: true,