JSFiddle - React, Tailwind, and code Playground
DPadComponentMockup
by Retsam19
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<!-- ko template: {
name: "layout",
data: main
} -->
<!-- /ko -->
<template id="layout">
<div class="layout">
<!-- ko template: {
name: 'layout-cell',
foreach: children
} -->
<!-- /ko -->
<div class="overlay">
<!-- ko template: {
name: "dpad"
} -->
<!-- /ko -->
</div>
</div>
</template>
<template id="layout-cell">
<div class="layout-cell" data-bind="
style: {
width: width,
height: height
}
"></div>
</template>
<template id="dpad">
<div class="dpad">
<div class="quarter quarter1" data-bind="
click: clickHandler('up')
"></div>
<div class="quarter quarter2" data-bind="
click: clickHandler('right')
"></div>
<div class="quarter quarter3" data-bind="
click: clickHandler('left')
"></div>
<div class="quarter quarter4" data-bind="
click: clickHandler('down')
"></div>
<div class="cutout"></div>
</div>
</template>
SCSS
html, body {
height: 100%
}
.layout {
position: relative;
height: 100%;
border: 1px solid black;
}
.layout-cell {
background-color: rgba(0, 0, 255, 10%)
}
.overlay {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
display: flex;
align-items: center;
/* background-color: rgba(255, 0, 0, 30%); */
}
/**
* Quarter Circles
*/
.dpad {
position:relative;
width:100px;
height:100px;
margin:0 auto;
}
.quarter {
position:absolute;
width:50%;
height:50%;
transform: rotate(45deg);
cursor: pointer;
}
.quarter:hover {
background-color:pink;
}
.quarter1 {
top:0;
left:0;
background-color: #CCC;
border-radius:100% 0 0 0;
transform-origin: bottom right;
}
.quarter2 {
top:0;
right:0;
background-color: #DDD;
border-radius:0 100% 0 0;
transform-origin: bottom left;
}
.quarter3 {
bottom:0;
left:0;
background-color: #DDD;
border-radius:0 0 0 100%;
transform-origin: top right;
}
.quarter4 {
bottom:0;
right:0;
background-color: #CCC;
border-radius:0 0 100% 0 ;
transform-origin: top left;
}
.cutout {
width:50%;
height:50%;
background-color:white;
position:absolute;
top:25%;
left:25%;
border-radius:50%;
/* pointer-events:none; */
cursor: default;
}
Babel + JSX
const STRETCH = "stretch";
const ROW = "row";
const COLUMN = "column";
class LayoutCell {
constructor(type) {
if(!([STRETCH, ROW, COLUMN].includes(type))) {
throw new Error("Invalid type: " + type)
}
this.width = ko.computed(function () {
return {
[STRETCH]: "100%",
[ROW]: "100%",
[COLUMN]: "100px"
}[type];
});
this.height = ko.computed(function () {
return {
[STRETCH]: "100%",
[ROW]: "100px",
[COLUMN]: "100%"
}[type];
});
}
}
class LayoutContainer {
constructor() {
this.children = ko.observableArray([
new LayoutCell(STRETCH)
]);
}
clickHandler(dir) {
return function () {
if(!this.direction) {
this.direction = (dir === "up" || dir === "down") ?
COLUMN : ROW;
}
console.log("Clicked " + dir);
}
}
}
ko.applyBindings({
main: new LayoutContainer()
});