main v1.1
Benjamin Kraft 2 years ago
commit ef4f0e8127
  1. 2
      .gitignore
  2. 6
      project.json
  3. BIN
      public/data/images/favicon.ico
  4. 272
      public/data/scripts/Cube.js
  5. 62
      public/data/scripts/Matrix.js
  6. 35
      public/data/scripts/events.js
  7. 91
      public/data/scripts/sketch.js
  8. 16
      public/data/scripts/solve.js
  9. 86
      public/data/settings/Credits.json
  10. 200
      public/data/settings/Settings.json
  11. 88
      public/data/styles/color_picker.css
  12. BIN
      public/data/styles/font.ttf
  13. 88
      public/data/styles/range_input.css
  14. 73
      public/index.html
  15. 102
      public/styles.css
  16. BIN
      public/thumbnail.png

2
.gitignore vendored

@ -0,0 +1,2 @@
.idea

@ -0,0 +1,6 @@
{
"display_name": "Rubiks Cube",
"info_text": "The 3x3 Rubiks Cube in 3D",
"visible": true,
"tags": ["Tool", "Game"]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

@ -0,0 +1,272 @@
"use strict"
class Cube{
constructor(){
this.bricks = [];
for (let x = -1; x < 2; x++){
for (let y = -1; y < 2; y++){
for (let z = -1; z < 2; z++){
this.bricks.push(new Brick(x, y, z));
}
}
}
}
show(){
push();
if (this.rotation){
for (let i = -1; i < 2; i++){
if (i === this.rotation.index){
push();
eval("rotate" + this.rotation.axis.toUpperCase() + "(this.rotation.angle);");
for (let b of this.getLayer(this.rotation.axis, i)) b.show();
pop();
}
else {
for (let b of this.getLayer(this.rotation.axis, i)) b.show();
}
}
}
else {
for (let b of this.bricks) b.show();
}
pop();
}
update(){
if (this.rotation) this.rotation.update();
}
updatePos(){
let m = new Matrix();
m.rotate(this.rotation.angle);
let o = other(this.rotation.axis),
bricks = [],
fields = [],
resultBricks = [], iBricks = 0, pBricks,
resultFields = [], iFields = 0, pFields;
for (let b of this.getLayer(this.rotation.axis, this.rotation.index)){
eval("bricks.push({x: b.pos." + o[0] + ", y: b.pos." + o[1] + "});");
for (let f of b.fields){
for (let p of f.points){
eval("fields.push({x: p." + o[0] + ", y: p." + o[1] + "});");
}
}
}
// transform points
while(pBricks = bricks[iBricks++]) resultBricks.push(m.applyToPoint(pBricks));
while(pFields = fields[iFields++]) resultFields.push(m.applyToPoint(pFields));
iBricks = 0, iFields = 0;
for (let b of this.getLayer(this.rotation.axis, this.rotation.index)){
let p = resultBricks[iBricks];
eval("b.pos." + o[0] + " = p.x;");
eval("b.pos." + o[1] + " = p.y;");
iBricks++;
for (let f of b.fields){
for (let pt of f.points){
let pf = resultFields[iFields];
eval("pt." + o[0] + " = pf.x;");
eval("pt." + o[1] + " = pf.y;");
iFields++;
}
}
}
}
getLayer(axis, index){
let bricks = [];
for (let b of this.bricks){
if (eval("b.pos." + axis) === index){
bricks.push(b);
}
}
return bricks;
}
rotate(axis, index, dir, v){
if (!this.rotation)
this.rotation = new Rotation(axis, index, dir, v, () => {
cube.updatePos();
cube.rotation = null;
});
}
scramble(count){
let cube = this;
if (count === 0)
this.rotation = null;
else
this.rotation = new Rotation(random(["x", "y", "z"]), random([-1, 1]), random([-1, 1]), PI / 32, () => {
cube.updatePos();
cube.scramble(count - 1);
});
}
}
function other(axis){
switch(axis){
case "x":
return ["y", "z"];
case "y":
return ["z", "x"];
case "z":
return ["x", "y"];
}
}
class Brick{
constructor(x, y, z){
this.pos = createVector(x, y, z);
this.size = 85;
this.createFields();
}
show(){
this.pos.mult(this.size);
push();
translate(this.pos.x, this.pos.y, this.pos.z);
for (let f of this.fields) f.show();
pop();
this.pos.div(this.size);
}
createFields(){
this.fields = [];
let sides = [[],[],[],[],[],[]];
let c = [
"#F00",
"#F90",
"#FFF",
"#FF0",
"#00F",
"#0F0",
"#000"
];
for (let x = -1; x < 2; x++){
for (let y = -1; y < 2; y++){
for (let z = -1; z < 2; z++){
let arr = [];
if (x > 0 && y && z){
if (this.pos.x > 0) arr.push({i: 0, colored: true});
else arr.push({i: 0});
}
if (x < 0 && y && z){
if (this.pos.x < 0) arr.push({i: 1, colored: true});
else arr.push({i: 1});
}
if (y > 0 && x && z){
if (this.pos.y > 0) arr.push({i: 2, colored: true});
else arr.push({i: 2});
}
if (y < 0 && x && z){
if (this.pos.y < 0) arr.push({i: 3, colored: true});
else arr.push({i: 3});
}
if (z > 0 && x && y){
if (this.pos.z > 0) arr.push({i: 4, colored: true});
else arr.push({i: 4});
}
if (z < 0 && x && y){
if (this.pos.z < 0) arr.push({i: 5, colored: true});
else arr.push({i: 5});
}
for (let a of arr){
sides[a.i].push({p: createVector(x, y, z), colored: a.colored});
}
}
}
}
for (let s of sides){
let points = [];
for (let a of s) points.push(a.p);
let color = s[0].colored ? c[sides.indexOf(s)] : c[6];
this.fields.push(new Field(points, color, this.size));
}
}
hasColor(c){
for (let f of this.fields){
if (f.colorEquals(c)){
return true;
}
}
return false;
}
get isEdge(){
return this.coloredCount === 2;
}
get isCorner(){
return this.coloredCount === 3;
}
get isFlat(){
return this.coloredCount === 1;
}
get coloredCount(){
let count = 0;
for (let f of this.fields){
if (!f.colorEquals("#000")) {
count++;
}
}
return count;
}
}
class Field{
constructor(points, c, size){
//relative to brick
this.color = {
light: color(c),
dark: dark(color(c), 0.4)
};
this.bSize = size;
this.size = size * 0.95;
this.points = points;
}
show(){
for (let p of this.points) p.mult(this.size / 2);
let p = this.points;
if (this.dark) fill(this.color.dark);
else fill(this.color.light);
strokeWeight(8);
stroke(0);
beginShape();
vertex(p[0].x, p[0].y, p[0].z);
vertex(p[2].x, p[2].y, p[2].z);
vertex(p[3].x, p[3].y, p[3].z);
vertex(p[1].x, p[1].y, p[1].z);
endShape(CLOSE);
for (let p of this.points) p.div(this.size / 2);
}
colorEquals(c){
let equal = true;
for (let i = 0; i < 3; i++){
if (this.color.light.levels[i] !== color(c).levels[i]){
equal = false;
}
}
return equal;
}
}
function dark(c, val){
return color(red(c) * val, green(c) * val, blue(c) * val);
}

@ -0,0 +1,62 @@
class Matrix{
constructor(){
this.a = 1;
this.b = 0;
this.c = 0;
this.d = 1;
this.e = 0;
this.f = 0;
}
applyToPoint(p){
return {
x: round(p.x * this.a + p.y * this.c + this.e),
y: round(p.x * this.b + p.y * this.d + this.f)
}
}
transform(a2, b2, c2, d2, e2, f2){
var a1 = this.a,
b1 = this.b,
c1 = this.c,
d1 = this.d,
e1 = this.e,
f1 = this.f;
this.a = a1 * a2 + c1 * b2;
this.b = b1 * a2 + d1 * b2;
this.c = a1 * c2 + c1 * d2;
this.d = b1 * c2 + d1 * d2;
this.e = a1 * e2 + c1 * f2 + e1;
this.f = b1 * e2 + d1 * f2 + f1;
}
rotate(angle){
var cs = cos(angle),
sn = sin(angle);
this.transform(cs, sn, -sn, cs, 0, 0);
}
}
class Rotation{
constructor(axis, index, dir, v, finishedCallback){
this.axis = axis;
this.index = index;
this.dir = dir;
this.angle = 0;
this.v = v;
this.finished = function(){
finishedCallback();
}
}
update(){
if (abs(this.angle) > PI / 2){
this.finished();
}
this.angle += this.v * this.dir;
}
}

@ -0,0 +1,35 @@
"use strict"
function keyPressed(){
}
function keyReleased(){
}
function mouseMoved(){
}
function mouseDragged(){
}
function mousePressed(){
}
function mouseReleased(){
}
window.onresize = function(){
let i = 0;
function resize(){
resizeCanvas($("#canvasHolder").outerWidth(), $("#canvasHolder").outerHeight(), true);
i++;
if (i < 5) window.setTimeout(resize, 0);
}
resize();
}

@ -0,0 +1,91 @@
"use strict"
let debug = false,
viewPort = {x: 0, y: 0},
font;
let cube,
mode = true;
let oldMouse = {x: 0, y: 0},
rotation = {x: -Math.PI / 8, y: -Math.PI / 4};
function preload(){
font = loadFont("data/styles/font.ttf");
}
function setup(){
canvasSetup();
interfaceSetup();
cube = new Cube();
}
function draw(){
myOrbitControl();
background(65);
cube.update();
cube.show();
}
function myOrbitControl(){
if (mouseIsPressed){
let x = map(mouseY - oldMouse.y, 0, height, 0, TWO_PI),
y = map(mouseX - oldMouse.x, 0, width, 0, TWO_PI);
rotation.x -= x;
rotation.y += y;
if (abs(rotation.x) > PI / 2){
rotation.x += x;
}
}
rotateX(rotation.x);
rotateY(rotation.y);
oldMouse.x = mouseX;
oldMouse.y = mouseY;
}
function canvasSetup(){
setFrameRate(60);
setAttributes('antialias', true);
let canvas = createCanvas($("#canvasHolder").width(), $("#canvasHolder").height(), WEBGL);
canvas.parent("canvasHolder");
textFont(font);
}
function interfaceSetup(){
let buttons = Object.values($("button:not(.actions)")).slice(0, 18);
for (let b of buttons){
let axis = $(b).parent().attr("class");
let index = (floor(buttons.indexOf(b) / 2) % 3) - 1;
let dir = int($(b).attr("id"));
$(b).click(function(){
cube.rotate(axis, index, dir, PI / 32);
});
$($("." + axis)[index + 1].children).mouseover(function(){
outer:
for (let b of cube.bricks){
for (let lb of cube.getLayer(axis, index)){
if (b == lb) continue outer;
}
for (let f of b.fields){
f.dark = true;
}
}
$($("." + axis)[index + 1].children).css("background-color", "rgb(30, 30, 30)");
});
$($("." + axis)[index + 1].children).mouseleave(function(){
for (let b of cube.bricks){
for (let f of b.fields){
f.dark = false;
}
}
$($("." + axis)[index + 1].children).css("background-color", "rgb(50, 50, 50)");
});
}
$($(".actions")[0]).click(function(){cube.scramble(20);});
$($(".actions")[1]).click(() => solve());
}

@ -0,0 +1,16 @@
function solve(){
cross();
cube = new Cube();
}
function cross(){
let whiteBricks = cube.bricks.filter(b => b.hasColor("#FFF"));
let main = whiteBricks.find(b => b.isFlat);
function doByColor(c){
}
doByColor("#00F");
}

@ -0,0 +1,86 @@
{
"credits": [
{
"title": "Electrical Sweep",
"artist": "Sweeper",
"link": "https://soundbible.com/1795-Electrical-Sweep.html",
"license": "Public Domain"
},
{
"title": "Jump",
"artist": "snottyboy",
"link": "https://soundbible.com/1343-Jump.html",
"license": "Attribution 3.0"
},
{
"title": "boo 01",
"artist": "tim.kahn",
"link": "https://freesound.org/people/tim.kahn/sounds/336997/",
"license": "Attribution 3.0"
},
{
"title": "Cheer crowd",
"artist": "Johanneskristjansson",
"link": "https://freesound.org/people/Johanneskristjansson/sounds/371339/",
"license": "Attribution 3.0"
},
{
"title": "cheer 01",
"artist": "tim.kahn",
"link": "https://freesound.org/people/tim.kahn/sounds/337000/",
"license": "Attribution 3.0"
},
{
"title": "awww 01",
"artist": "tim.kahn",
"link": "https://freesound.org/people/tim.kahn/sounds/336998/",
"license": "Attribution 3.0"
},
{
"title": "Evolution",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=RA6XneJGwfQ",
"license": "Creative Commons - Attribution"
},
{
"title": "Home Improvement",
"artist": "Josh Woodward",
"link": "https://youtu.be/NMi9Nrm1Mfs?t=2359",
"license": "Creative Commons - Attribution"
},
{
"title": "Incoherent",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=bxgzIOS-lSs",
"license": "Creative Commons - Attribution"
},
{
"title": "Cherubs",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=pzUkoJonpro",
"license": "Creative Commons - Attribution"
},
{
"title": "Let it in",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=M-GylSik2h8",
"license": "Creative Commons - Attribution"
},
{
"title": "California Lullabye",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=WmWHcyLsqHQ",
"license": "Creative Commons - Attribution"
},
{
"title": "Memorized",
"artist": "Josh Woodward",
"link": "https://www.youtube.com/watch?v=2eFKOxfUYwE",
"license": "Creative Commons - Attribution"
}
]
}

@ -0,0 +1,200 @@
{
"colors": {
"background": {
"mountains": {
"stroke": "rgb(0, 0, 0)",
"fill": "rgb(60, 60, 60)"
},
"ground": "rgb(40, 100, 30)",
"sky":"rgb(110, 130, 230)"
},
"map": {
"background": {
"stroke": "rgb(0, 0, 0)",
"fill": "rgb(90, 110, 210)"
}
},
"player": {
"body": "hsb(0, 100%, 100%)",
"eyes": {
"inner": "rgb(0, 0, 0)" ,
"outer": "rgb(255, 255, 255)"
}
},
"goal": {
"main": "#473115",
"roof": "#32210b",
"hole": "#14100b"
},
"brick": {
"earth": "rgb(81, 54, 37)",
"ground": "rgb(40, 150, 20)",
"grass": "#2c8300",
"flower": {
"center": "hsb(0, 100%, 100%)",
"petal": "hsb(0, 100%, 100%)",
"haulm": "#2c8300"
},
"tree": {
"leaf": "hsb(110, 100%, 50%)",
"wood": "hsb(32, 100%, 25%)"
},
"coin": {
"fill": "hsb(0, 100%, 100%)",
"stroke": "hsb(0, 100%, 100%)"
}
},
"loader": {
"background": "#3c598d",
"start": "hsb(120, 100%, 30%)",
"finished": "#00d3db",
"spinner": "#00d3db",
"text": {
"fill": "rgb(0, 0, 0)",
"stroke": "#00d3db"
}
}
},
"messages": {
"won": {
"html": "<p>You won the game! :D Wanna start another?</p>",
"styles": {
"border-color": "rgb(30, 120, 30)",
"height": "auto"
},
"buttons": [
{
"text": "Restart",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "game.restart();"
},
{
"text": "New Game",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "loadNewGame();"
},
{
"text": "Continue",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "game.resume()"
}
]
},
"lost": {
"html": "<p>Oh no, you fell out of the world!</p>",
"styles": {
"border-color": "rgb(160, 30, 30)",
"height": "auto"
},
"buttons": [
{
"text": "Restart",
"styles": {
"background-color": "rgb(160, 60, 60)"
},
"onclick": "game.restart();"
}
]
},
"newGame": {
"html": "<p>Are you sure you wanna start a new one?</p>",
"styles": {
"border-color": "rgb(70, 70, 20)",
"height": "auto"
},
"buttons": [
{
"text": "New Game",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "loadNewGame();"
},
{
"text": "Cancel",
"styles": {
"background-color": "rgb(160, 60, 60)"
},
"onclick": "game.resume();"
}
]
},
"credits": {
"html": "",
"styles": {
"border-color": "rgb(0, 37, 160)",
"background-color": "rgb(83, 61, 255)",
"height": "auto"
},
"buttons": [
{
"text": "Continue",
"styles": {
"background-color": "rgb(60, 160, 60)"
},
"onclick": "game.resume()"
}
]
}
},
"audio": {
"sound": {
"won": [
"data/audio/sound/cheer0.mp3",
"data/audio/sound/cheer1.wav",
"data/audio/sound/cheer2.wav",
"data/audio/sound/cheer3.wav"
],
"lost": [
"data/audio/sound/boo0.wav",
"data/audio/sound/aww0.wav",
"data/audio/sound/aww1.wav"
],
"jump": [
"data/audio/sound/jump.mp3"
],
"coin": [
"data/audio/sound/electrical_sweep.mp3"
]
},
"music":{
"game": [
"data/audio/music/background0.mp3",
"data/audio/music/background1.mp3",
"data/audio/music/background2.mp3",
"data/audio/music/background3.mp3",
"data/audio/music/background4.mp3",
"data/audio/music/background5.mp3",
"data/audio/music/background6.mp3",
"data/audio/music/background7.mp3",
"data/audio/music/background8.mp3"
]
}
},
"values": {
"minBrickWidth": "200",
"maxBrickWidth": "800",
"backgroundMoveScale": "500",
"minWorldSize": "30000",
"maxWorldSize": "35000",
"maxMapSize": "300",
"coinSize": "50",
"coinRarity": "20",
"coinDispoY": "10",
"loadedWaitTime": "1000",
"cursorTimeLimit": "1000",
"menuAnimationTime": "200",
"openerAnimationTime": "200"
}
}

@ -0,0 +1,88 @@
#color_picker{
width: 300px;
height: 25%;
margin: 20px;
margin-top: 50px;
border: 5px solid #000;
background-color: #000;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: relative;
}
#color_picker_numeric{
width: 80%;
padding: 5%;
margin: 5%;
background-color: #888;
border-radius: 10px;
overflow: hidden;
}
.color_picker_rgb{
float: left;
width: 22%;
height: 35px;
font-size: 25px;
color: #000;
}
.color_picker_rgb:nth-child(1){
margin-right: 10%;
margin-left: 3%;
background-color: #F00;
}
.color_picker_rgb:nth-child(2){
background-color: #0F0;
}
.color_picker_rgb:nth-child(3){
margin-left: 10%;
background-color: #00F;
color: #FFF;
}
#color_picker_hex{
width: 50%;
height: 30px;
font-size: 25px;
margin: 10% 25% 0 25%;
}
#saturation{
position: relative;
width: calc(100% - 33px);
height: 100%;
background: linear-gradient(to right, #FFF 0%, #F00 100%);
float: left;
margin-right: 6px;
}
#value {
width: 100%;
height: 100%;
background: linear-gradient(to top, #000 0%, rgba(255,255,255,0) 100%);
}
#sb_picker{
border: 2px solid;
border-color: #FFF;
position: absolute;
width: 14px;
height: 14px;
border-radius: 10px;
bottom: 50px;
left: 50px;
box-sizing: border-box;
z-index: 10;
}
#hue {
width: 27px;
height: 100%;
position: relative;
float: left;
background: linear-gradient(to bottom, #F00 0%, #F0F 17%, #00F 34%, #0FF 50%, #0F0 67%, #FF0 84%, #F00 100%);
}
#hue_picker {
position: absolute;
background: #000;
border-bottom: 1px solid #000;
top: 0;
width: 27px;
height: 2px;
}

Binary file not shown.

@ -0,0 +1,88 @@
input[type=range] {
-webkit-appearance: none;
margin: 18px 0;
width: 100%;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border: 0.2px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -14px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #367ebd;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border: 0.2px solid #010101;
}
input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #2a6495;
border: 0.2px solid #010101;
border-radius: 2.6px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
background: #3071a9;
border: 0.2px solid #010101;
border-radius: 2.6px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
background: #3071a9;
}
input[type=range]:focus::-ms-fill-upper {
background: #367ebd;
}

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js" type="text/javascript"></script>
<script src="data/scripts/events.js" type="text/javascript"></script>
<script src="data/scripts/sketch.js" type="text/javascript"></script>
<script src="data/scripts/Cube.js" type="text/javascript"></script>
<script src="data/scripts/Matrix.js" type="text/javascript"></script>
<script src="data/scripts/solve.js" type="text/javascript"></script>
<link href="styles.css" rel="stylesheet">
<link href="data/styles/color_picker.css" rel="stylesheet">
<link href="data/styles/range_input.css" rel="stylesheet">
<link href="data/images/favicon.ico" rel="icon" type="image/x-icon">
<title>Rubiks Cube</title>
</head>
<body>
<div id="p5_loading"></div>
<div id="content">
<div id="interface">
<div class="x">
<button id="-1">L</button>
<div class="label">X-1</div>
<button id="1">R</button>
</div>
<div class="x">
<button id="-1">L</button>
<div class="label">X-2</div>
<button id="1">R</button>
</div>
<div class="x">
<button id="-1">L</button>
<div class="label">X-3</div>
<button id="1">R</button>
</div>
<div class="y">
<button id="-1">L</button>
<div class="label">Y-1</div>
<button id="1">R</button>
</div>
<div class="y">
<button id="-1">L</button>
<div class="label">Y-2</div>
<button id="1">R</button>
</div>
<div class="y">
<button id="-1">L</button>
<div class="label">Y-3</div>
<button id="1">R</button>
</div>
<div class="z">
<button id="-1">L</button>
<div class="label">Z-1</div>
<button id="1">R</button>
</div>
<div class="z">
<button id="-1">L</button>
<div class="label">Z-2</div>
<button id="1">R</button>
</div>
<div class="z">
<button id="-1">L</button>
<div class="label">Z-3</div>
<button id="1">R</button>
</div>
</div>
<div id="canvasHolder"></div>
</div>
<button class="actions">Scramble</button>
<button class="actions">Solve</button>
</body>
</html>

@ -0,0 +1,102 @@
a:link, a:hover, a:active, a:visited{color: #000;}
html, body{margin: 0; padding: 0; height: 100%; width: 100%;}
canvas{margin: 0; padding: 0; border: none; display: block;}
button:hover{cursor: pointer;}
@font-face{
font-family: "Rametto";
src: url("data/styles/font.ttf");
}
*{
font-family: "Rametto";
color: #888;
font-size: 25px;
}
:root{
--iw: 200px;
--cw: 750px;
}
body{
background-color: rgb(40, 40, 40);
text-align: center;
}
#content{
width: calc(var(--iw) + var(--cw));
height: 750px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
#interface{
float: left;
width: var(--iw);
height: 750px;
text-align: center;
}
#canvasHolder{
float: left;
width: 750px;
height: 750px;
}
#canvasHolder canvas{
border-radius: 30px;
box-shadow: 10px 10px 15px #000;
border: 5px solid #000;
}
.x, .y, .z{
height: 60px;
margin-top: calc((750px - 9 * 60px) / 10);
}
button:not(.actions){
float: left;
width: 30%;
height: 100%;
background-color: rgb(50, 50, 50);
border-color: rgb(50, 50, 50);
border: 3px solid #000;
}
button:first-child:not(.actions){
margin-left: 4%;
border-radius: calc(var(--iw) / 20) 0px 0px calc(var(--iw) / 20);
border-right: none;
}
button:last-child:not(.actions){
margin-right: 4%;
border-radius: 0px calc(var(--iw) / 20) calc(var(--iw) / 20) 0px;
border-left: none;
}
.label{
float: left;
width: 30%;
height: 90%;
background-color: rgb(50, 50, 50);
border-bottom: 3px solid #000;
border-top: 3px solid #000;
cursor: pointer;
}
.actions{
margin: 30px;
background-color: rgb(30, 30, 30);
border-radius: 10px;
border: 3px solid #000;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Loading…
Cancel
Save