a Rubik's Cube made in HTML, JavaScript and CSS.
A Pen by Gregor Adams on CodePen.
link(href='http://fonts.googleapis.com/css?family=Lato:300,400' | |
rel='stylesheet' | |
type='text/css') | |
mixin cubePart(x, y, z) | |
div(class="cube-part-wrapper cube-part-wrapper-#{x}#{y}#{z}" | |
data-x="#{x}" | |
data-y="#{y}" | |
data-z="#{z}") | |
.axis.axis-part(data-rotation-x="0" | |
data-rotation-y="0" | |
data-rotation-z="0") | |
ul.cube-part | |
li(class=z>1?"side top white" : "side top") #{x}#{y}#{z} | |
.sticker | |
li(class=z<1?"side bottom yellow" : "side bottom") #{x}#{y}#{z} | |
.sticker | |
li(class=y>1?"side right orange" : "side right") #{x}#{y}#{z} | |
.sticker | |
li(class=y<1?"side left red" : "side left") #{x}#{y}#{z} | |
.sticker | |
li(class=x>1?"side back green" : "side back") #{x}#{y}#{z} | |
.sticker | |
li(class=x<1?"side front blue" : "side front") #{x}#{y}#{z} | |
.sticker | |
// --- @start control section | |
.controls | |
// --- @start button-wrapper | |
.button-wrapper | |
div | |
h3 Theme | |
- each theme in ["flat", "realistic", "ice"] | |
button(type="button" | |
class="themer" | |
data-theme="#{theme}") #{theme} | |
- each axis in ["x", "y", "z"] | |
div | |
h3 Axis #{axis} | |
- for (var i = 0; i < 3; i++) | |
button(type="button" | |
class="rotater" | |
data-axis="#{axis}" | |
data-level="#{i}") Level #{i} | |
button(type="button" | |
class="scrambler") Scramble cube | |
// --- @start canvas | |
.canvas.theme-flat | |
.cube-wrapper | |
.cube | |
// --- @start grip | |
.grip | |
.axis.axis-grip | |
// --- @start parts | |
- for (var x = 0; x < 3; x++) | |
- for (var y = 0; y < 3; y++) | |
- for (var z = 0; z < 3; z++) | |
+cubePart(x, y, z) |
a Rubik's Cube made in HTML, JavaScript and CSS.
A Pen by Gregor Adams on CodePen.
/* jshint -W069 */ | |
(function($, undefined) { | |
'use strict'; | |
var data = {}; | |
data['x'] = {}; | |
data['x']['base'] = {}; | |
data['x']['left'] = {}; | |
data['x']['right'] = {}; | |
data['y'] = {}; | |
data['y']['base'] = {}; | |
data['y']['left'] = {}; | |
data['y']['right'] = {}; | |
data['z'] = {}; | |
data['z']['base'] = {}; | |
data['z']['left'] = {}; | |
data['z']['right'] = {}; | |
for (var i = 0; i < 3; i++) { | |
data['x']['base'][i] = [{ | |
'x': i, | |
'y': 0, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 2 | |
}]; | |
data['y']['base'][i] = [{ | |
'x': 2, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 0 | |
}]; | |
data['z']['base'][i] = [{ | |
'x': 2, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 2, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 2, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 2, | |
'z': i | |
}]; | |
data['x']['left'][i] = [{ | |
'x': i, | |
'y': 2, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 2 | |
}]; | |
data['x']['right'][i] = [{ | |
'x': i, | |
'y': 0, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 2 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 1 | |
}, { | |
'x': i, | |
'y': 0, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 1, | |
'z': 0 | |
}, { | |
'x': i, | |
'y': 2, | |
'z': 0 | |
}]; | |
data['y']['left'][i] = [{ | |
'x': 0, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 0 | |
}]; | |
data['y']['right'][i] = [{ | |
'x': 2, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 0 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 1 | |
}, { | |
'x': 2, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 1, | |
'y': i, | |
'z': 2 | |
}, { | |
'x': 0, | |
'y': i, | |
'z': 2 | |
}]; | |
data['z']['left'][i] = [{ | |
'x': 2, | |
'y': 2, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 2, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 2, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 0, | |
'z': i | |
}]; | |
data['z']['right'][i] = [{ | |
'x': 0, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 2, | |
'z': i | |
}, { | |
'x': 0, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 1, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 0, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 1, | |
'z': i | |
}, { | |
'x': 2, | |
'y': 2, | |
'z': i | |
}]; | |
} | |
var rotate3d = { | |
'x': '1, 0, 0, ', | |
'y': '0, 1, 0, ', | |
'z': '0, 0, 1, ' | |
}; | |
var block = false; | |
var down = false; | |
var canvas = { | |
'axis': null, | |
'css': '', | |
'mouse': { | |
'distance': 0, | |
'time': 0 | |
} | |
}; | |
var randomNumber = function(min, max) { | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
}; | |
var withPrefix = function(regex) { | |
return function(index, classes) { | |
return classes.split(/\s+/).filter(function(el) { | |
return regex.test(el); | |
}).join(' '); | |
}; | |
}; | |
/** | |
* @jsdoc function | |
* @name rubics.clearHelpers | |
* @description | |
* clear the grip after the rotation | |
*/ | |
var clearHelpers = function() { | |
var $gripAxis = $('.grip .axis'); | |
$gripAxis.css({ | |
transition: 'none', | |
transform: '' | |
}); | |
setTimeout(function() { | |
$gripAxis.css({ | |
transition: '' | |
}); | |
}, 0); | |
}; | |
/** | |
* @jsdoc function | |
* @name rubics.positionParts | |
* @description | |
* puts the cubes in the new position | |
*/ | |
var positionParts = function(turnAxis, level) { | |
var axis = ['x', 'y', 'z']; | |
var elements = []; | |
var axi = axis.splice(axis.indexOf(turnAxis), 1); | |
$.each(data[turnAxis]['base'][level], function(i, obj) { | |
var selector3d = '[data-x="'; | |
selector3d += obj['x']; | |
selector3d += '"][data-y="'; | |
selector3d += obj['y']; | |
selector3d += '"][data-z="'; | |
selector3d += obj['z'] + '"]'; | |
elements.push($(selector3d)); | |
}); | |
$.each(elements, function(i, el) { | |
if (turnAxis === 'y') { | |
$.each(axis, function(j, ax) { | |
$(el).attr('data-' + ax, data[turnAxis]['right'][level][i][ax]); | |
}); | |
$(el).attr('data-' + axi[0], data[turnAxis]['left'][level][i][axi[0]]); | |
} else { | |
$.each(axis, function(j, ax) { | |
$(el).attr('data-' + ax, data[turnAxis]['left'][level][i][ax]); | |
}); | |
$(el).attr('data-' + axi[0], data[turnAxis]['right'][level][i][axi[0]]); | |
} | |
}); | |
}; | |
/** | |
* @jsdoc function | |
* @name rubics.performTurn | |
* @description | |
* performes the turn. | |
* allows a callback when the turn is done | |
*/ | |
var performTurn = function(rotate3d, turnAxis, callback) { | |
$('.grip').find('.axis-grip:first').css({ | |
transform: 'rotate3d(' + rotate3d[turnAxis] + ' 90deg)' | |
}).one('transitionend', callback); | |
}; | |
/** | |
* @jsdoc function | |
* @name rubics.rotateParts | |
* @description | |
* rotates the parts | |
*/ | |
var rotateParts = function(rotate3d, turnAxis) { | |
$('.grip .cube-part-wrapper').each(function(i, el) { | |
var css = $(el).find('.axis-part').css('transform'); | |
css = css === 'none' ? '' : css; | |
css = 'rotate3d(' + rotate3d[turnAxis] + 90 + 'deg) ' + css; | |
$(el).find('.axis-part').css({ | |
transform: css | |
}); | |
}); | |
}; | |
/** | |
* @jsdoc function | |
* @name rubics.attatchParts | |
* @description | |
* puts the parts back into the cube | |
*/ | |
var attatchParts = function(turnAxis, level) { | |
$('[data-' + turnAxis + '=' + level + ']').appendTo('.cube'); | |
}; | |
/** | |
* @jsdoc function | |
* @name rubics.detatchParts | |
* @description | |
* puts the parts into the grip | |
*/ | |
var detatchParts = function(turnAxis, level) { | |
$('[data-' + turnAxis + '=' + level + ']').appendTo('.grip .axis-grip'); | |
}; | |
var autoTurn = function(turnAxis, level) { | |
if (!block) { | |
block = true; | |
turnAxis = turnAxis || 'x'; | |
level = level || 0; | |
detatchParts(turnAxis, level); | |
performTurn(rotate3d, turnAxis, function() { | |
rotateParts(rotate3d, turnAxis); | |
attatchParts(turnAxis, level); | |
clearHelpers(); | |
positionParts(turnAxis, level); | |
block = false; | |
}); | |
} else { | |
return; | |
} | |
}; | |
var scrambleCube = function(n) { | |
var axis = ['x', 'y', 'z']; | |
$('.axis-grip').addClass('fast'); | |
var duration = $('.axis-grip').css('transition-duration'); | |
duration = (parseFloat(duration) + 0.1) * 1000; | |
var play; | |
play = setInterval(function() { | |
autoTurn(axis[randomNumber(0, 2)], randomNumber(0, 2)); | |
}, duration); | |
setTimeout(function() { | |
$('.axis-grip').removeClass('fast'); | |
if (play) { | |
clearTimeout(play); | |
} | |
}, duration * n); | |
}; | |
var showCube = function(delay, i) { | |
setTimeout(function() { | |
var cube = $('.cube-part-wrapper').get().reverse()[i]; | |
$(cube).addClass('show'); | |
}, delay * i); | |
}; | |
$(function() { | |
$('label').on('mousedown', function(e) { | |
e.preventDefault(); | |
}); | |
$('.canvas').on('mousedown', function(e) { | |
e.preventDefault(); | |
down = true; | |
canvas['axis'] = false; | |
canvas['mouse']['x'] = e.pageX; | |
canvas['mouse']['y'] = e.pageY; | |
canvas['css'] = $('.cube-wrapper').css('transform'); | |
canvas['mouse']['start'] = +new Date(); | |
}); | |
$(document).on('mouseup', function() { | |
if (down) { | |
down = false; | |
canvas['mouse']['end'] = +new Date(); | |
canvas['mouse']['time'] = canvas['mouse']['end'] - canvas['mouse']['start']; | |
canvas['mouse']['bouce'] = (canvas['mouse']['distance'] / canvas['mouse']['time']) * 200; | |
canvas['css'] = $('.cube-wrapper').css('transform'); | |
canvas['mouse']['bouce'] = Math.abs(canvas['mouse']['bouce']) <= 25 ? 0 : canvas['mouse']['bouce']; | |
$('.cube-wrapper').css({ | |
transitionDuration: Math.min(Math.abs(canvas['mouse']['bouce'] * 20), 300) + 'ms', | |
transform: 'rotate3d(' + rotate3d[canvas['axis']] + canvas['mouse']['bouce'] + 'deg) ' + canvas['css'] | |
}).one('transitionend', function() { | |
$('.cube-wrapper').css({ | |
transitionDuration: '' | |
}); | |
}); | |
} | |
}); | |
$(document).on('mousemove', function(e) { | |
if (!down) { | |
return false; | |
} | |
var x = (e.pageX - canvas['mouse']['x']) / 4; | |
var y = (e.pageY - canvas['mouse']['y']) / -4; | |
var transformation = ''; | |
if ((x > 10 || x < -10) && canvas['axis'] !== 'x') { | |
canvas['axis'] = 'y'; | |
transformation += 'rotate3d(0, 1, 0, '; | |
transformation += x; | |
transformation += 'deg) '; | |
transformation += canvas['css']; | |
canvas['mouse']['distance'] = x; | |
} else if ((y > 10 || y < -10) && canvas['axis'] !== 'y') { | |
canvas['axis'] = 'x'; | |
transformation += 'rotate3d(1, 0, 0, '; | |
transformation += y; | |
transformation += 'deg) '; | |
transformation += canvas['css']; | |
canvas['mouse']['distance'] = y; | |
} else { | |
return false; | |
} | |
$('.cube-wrapper').css({ | |
transform: transformation | |
}); | |
}); | |
$('.themer').on('click', function() { | |
var theme = $(this).data('theme'); | |
$('.canvas').removeClass(withPrefix(/^theme-/)); | |
$('.canvas').addClass('theme-' + theme); | |
}); | |
$('.scrambler').on('click', function() { | |
scrambleCube(30); | |
}); | |
$('.rotater').on('click', function() { | |
if (!block) { | |
block = true; | |
var turnAxis = $(this).data('axis') || 'x'; | |
var level = $(this).data('level') || 0; | |
detatchParts(turnAxis, level); | |
performTurn(rotate3d, turnAxis, function() { | |
rotateParts(rotate3d, turnAxis); | |
attatchParts(turnAxis, level); | |
clearHelpers(); | |
positionParts(turnAxis, level); | |
block = false; | |
}); | |
} else { | |
return; | |
} | |
}); | |
setTimeout(function() { | |
$('body').addClass('init'); | |
}, 310); | |
}); | |
})(window.jQuery); |
// ██╗ ██╗ █████╗ ██████╗ ███████╗ | |
// ██║ ██║██╔══██╗██╔══██╗██╔════╝ | |
// ██║ ██║███████║██████╔╝███████╗ | |
// ╚██╗ ██╔╝██╔══██║██╔══██╗╚════██║ | |
// ╚████╔╝ ██║ ██║██║ ██║███████║ | |
// ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ | |
// | |
@cube-size: 15rem; | |
@cube-part-count: 3; | |
@cube-part-size: @cube-size / @cube-part-count; | |
@border-width: 0.3rem; | |
@border-radius: @border-width * 2; | |
@cube-color: rgba(30, 30, 30, 1); | |
@cube-hover-color: rgba(80, 180, 240, 1); | |
@fast: 100ms; | |
@medium: 200ms; | |
@slow: 400ms; | |
@base-mix-perc: 15%; | |
@hover-mix-perc: 35%; | |
@hover-base-mix-perc: 5%; | |
@button-color: #4e3d61; | |
@base-font-size: 16px; | |
@rotater-size: 1.8rem; | |
@rotater-factor: 1; | |
@gutter-width: 1rem; | |
@radius: 0.2rem; | |
@arrow-size: @cube-part-size / 3; | |
@red: #c41e3a; | |
@green: #009e60; | |
@blue: #0051ba; | |
@orange: #ff5800; | |
@yellow: #ffd500; | |
@white: #fff; | |
.for(@i, @n) {.-each(@i)} | |
.for(@n) when (isnumber(@n)) {.for(1, @n)} | |
.for(@i, @n) when not (@i = @n) { | |
.for((@i + ((@n - @i) / abs(@n - @i))), @n); | |
} | |
.for(@array) when (default()) {.for-impl_(length(@array))} | |
.for-impl_(@i) when (@i > 1) {.for-impl_((@i - 1))} | |
.for-impl_(@i) {.-each(extract(@array, @i));} | |
/** ██████╗ █████╗ ███████╗███████╗ | |
* ██╔══██╗██╔══██╗██╔════╝██╔════╝ | |
* ██████╔╝███████║███████╗█████╗ | |
* ██╔══██╗██╔══██║╚════██║██╔══╝ | |
* ██████╔╝██║ ██║███████║███████╗ | |
* ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ | |
*/ | |
*, | |
*:before, | |
*:after { | |
box-sizing: border-box; | |
margin: 0; | |
padding: 0; | |
font-family: inherit; | |
line-height: inherit; | |
font-weight: 300; | |
user-select: none; | |
} | |
html { | |
height: 100%; | |
min-height: 100%; | |
font-size: @base-font-size; | |
font-family: 'Lato', sans-serif; | |
line-height: 1.25; | |
} | |
html, | |
body { | |
overflow: hidden; | |
} | |
body { | |
background: @button-color; | |
} | |
ul, | |
ol { | |
list-style: none; | |
li { | |
list-style: inherit; | |
} | |
} | |
h3 { | |
margin: 0 0 0.5em; | |
} | |
/** | |
* ███████╗██████╗ █████╗ ███╗ ███╗███████╗ | |
* ██╔════╝██╔══██╗██╔══██╗████╗ ████║██╔════╝ | |
* █████╗ ██████╔╝███████║██╔████╔██║█████╗ | |
* ██╔══╝ ██╔══██╗██╔══██║██║╚██╔╝██║██╔══╝ | |
* ██║ ██║ ██║██║ ██║██║ ╚═╝ ██║███████╗ | |
* ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ | |
* | |
*/ | |
.canvas { | |
height: @cube-size * 2; | |
width: @cube-size * 2; | |
margin: 0 0 0 250px; | |
backface-visibility: hidden; | |
perspective: 700px; | |
&:hover { | |
cursor: grab; | |
} | |
&:active { | |
cursor: grabbing; | |
} | |
} | |
/** | |
* ███████╗ ██████╗ ██████╗ ███╗ ███╗███████╗ | |
* ██╔════╝██╔═══██╗██╔══██╗████╗ ████║██╔════╝ | |
* █████╗ ██║ ██║██████╔╝██╔████╔██║███████╗ | |
* ██╔══╝ ██║ ██║██╔══██╗██║╚██╔╝██║╚════██║ | |
* ██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████║ | |
* ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ | |
*/ | |
::-moz-focus-inner { | |
outline: 0; | |
} | |
button, input, select, option, a, textarea, label, [contenteditable] { | |
line-height: 1; | |
&:focus { | |
outline: 0; | |
} | |
} | |
button { | |
margin: 0 @gutter-width @gutter-width 0; | |
padding: 0.5em 1em; | |
font-size: 0.8rem; | |
background: @button-color; | |
border: 0.1rem solid #fff; | |
color: #fff; | |
box-shadow: none; | |
border-radius: @radius; | |
cursor: pointer; | |
font-variant: small-caps; | |
&:focus, &:hover { | |
color: darken(@button-color, 10%); | |
background: #fff; | |
border-color: darken(@button-color, 10%); | |
} | |
&:active { | |
color: #fff; | |
border-color: darken(@button-color, 10%); | |
background-color: darken(@button-color, 10%); | |
} | |
&:focus { | |
outline: 0; | |
} | |
} | |
.button-wrapper { | |
position: absolute; | |
top: 0; | |
left: 0; | |
max-width: 20rem; | |
padding-left: @gutter-width; | |
padding-top: @gutter-width; | |
color: #fff; | |
} | |
/** | |
* ██████╗██╗ ██╗██████╗ ███████╗███████╗ | |
* ██╔════╝██║ ██║██╔══██╗██╔════╝██╔════╝ | |
* ██║ ██║ ██║██████╔╝█████╗ ███████╗ | |
* ██║ ██║ ██║██╔══██╗██╔══╝ ╚════██║ | |
* ╚██████╗╚██████╔╝██████╔╝███████╗███████║ | |
* ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ | |
*/ | |
.cube { | |
position: absolute; | |
top: 0; | |
left: 0; | |
height: inherit; | |
width: inherit; | |
transition: transform @medium linear; | |
transform-style: preserve-3d; | |
backface-visibility: hidden; | |
.init & { | |
transform: rotate3d(0, 1, 0, 45deg) rotate3d(1, 0, 0, 45deg); | |
} | |
} | |
.cube-wrapper { | |
position: absolute; | |
top: @cube-size / 2; | |
left: @cube-size / 2; | |
height: @cube-size; | |
width: @cube-size; | |
transform: translate3d(0, 0, 0); | |
transition-property: transform; | |
transition-timing-function: ease-out; | |
transition-duration: 0; | |
transform-style: preserve-3d; | |
backface-visibility: hidden; | |
} | |
.cube-part { | |
height: inherit; | |
width: inherit; | |
.side { | |
position: absolute; | |
top: 0; | |
left: 0; | |
height: inherit; | |
width: inherit; | |
line-height: @cube-part-size; | |
text-align: center; | |
font-size: 0; | |
transform-style: preserve-3d; | |
backface-visibility: hidden; | |
border-radius: @border-radius; | |
&:before, &:after { | |
transform-style: preserve-3d; | |
} | |
&.front { | |
transform: translate3d((@cube-part-size /-2), 0, 0) rotate3d(0, 1, 0, -90deg) scale(1); | |
} | |
&.back { | |
transform: translate3d((@cube-part-size / 2), 0, 0) rotate3d(0, 1, 0, 90deg) scale(1); | |
} | |
&.right { | |
transform: translate3d(0, (@cube-part-size / 2), 0) rotate3d(1, 0, 0, -90deg) scale(1); | |
} | |
&.left { | |
transform: translate3d(0, (@cube-part-size / -2), 0) rotate3d(1, 0, 0, 90deg) scale(1); | |
} | |
&.top { | |
transform: translate3d(0, 0, (@cube-part-size / 2)) rotate3d(1, 0, 0, 0) scale(1); | |
} | |
&.bottom { | |
transform: translate3d(0, 0, (@cube-part-size / -2)) rotate3d(1, 0, 0, -180deg) scale(1); | |
} | |
} | |
} | |
.cube-part-wrapper { | |
position: absolute; | |
height: @cube-part-size; | |
width: @cube-part-size; | |
z-index: 0; | |
transform-style: preserve-3d; | |
backface-visibility: hidden; | |
transition-property: all; | |
transition-duration: @slow; | |
&[data-x="0"] { | |
left: 0; | |
} | |
&[data-x="1"] { | |
left: @cube-part-size; | |
} | |
&[data-x="2"] { | |
left: @cube-part-size * 2; | |
} | |
&[data-y="0"] { | |
top: 0; | |
} | |
&[data-y="1"] { | |
top: @cube-part-size; | |
} | |
&[data-y="2"] { | |
top: @cube-part-size * 2; | |
} | |
&[data-z="0"] { | |
transform+_: translate3d(0, 0, (@cube-part-size / -1)); | |
} | |
&[data-z="1"] { | |
transform+_: translate3d(0, 0, 0); | |
} | |
&[data-z="2"] { | |
transform+_: translate3d(0, 0, @cube-part-size); | |
} | |
} | |
/** | |
* ██████╗ ██████╗ ██╗██████╗ | |
* ██╔════╝ ██╔══██╗██║██╔══██╗ | |
* ██║ ███╗██████╔╝██║██████╔╝ | |
* ██║ ██║██╔══██╗██║██╔═══╝ | |
* ╚██████╔╝██║ ██║██║██║ | |
* ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ | |
* | |
*/ | |
.grip { | |
position: absolute; | |
top: 0; | |
left: 0; | |
height: inherit; | |
width: inherit; | |
pointer-events: none; | |
transform-style: preserve-3d; | |
backface-visibility: hidden; | |
.axis { | |
transition: transform @medium; | |
&.fast { | |
transition: transform @fast; | |
} | |
} | |
} | |
.axis { | |
position: absolute; | |
top: 0; | |
left: 0; | |
height: inherit; | |
width: inherit; | |
transform-style: preserve-3d; | |
backface-visibility: hidden; | |
} | |
/** | |
* ████████╗██╗ ██╗███████╗███╗ ███╗███████╗ | |
* ╚══██╔══╝██║ ██║██╔════╝████╗ ████║██╔════╝ | |
* ██║ ███████║█████╗ ██╔████╔██║█████╗ | |
* ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██╔══╝ | |
* ██║ ██║ ██║███████╗██║ ╚═╝ ██║███████╗ | |
* ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ | |
*/ | |
.theme-flat { | |
//@border-width: 0.2rem; | |
@border-radius: @border-width; | |
.cube-part { | |
.side { | |
border-radius: @border-radius; | |
.sticker { | |
position: absolute; | |
top: @border-width; | |
left: @border-width; | |
right: @border-width; | |
bottom: @border-width; | |
border-radius: @border-radius; | |
z-index: 2; | |
} | |
&.white .sticker { | |
background-color: @white; | |
} | |
&.blue .sticker { | |
background-color: @blue; | |
} | |
&.orange .sticker { | |
background-color: @orange; | |
} | |
&.red .sticker { | |
background-color: @red; | |
} | |
&.green .sticker { | |
background-color: @green; | |
} | |
&.yellow .sticker { | |
background-color: @yellow; | |
} | |
} | |
} | |
} | |
/** | |
* ████████╗██╗ ██╗███████╗███╗ ███╗███████╗ | |
* ╚══██╔══╝██║ ██║██╔════╝████╗ ████║██╔════╝ | |
* ██║ ███████║█████╗ ██╔████╔██║█████╗ | |
* ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██╔══╝ | |
* ██║ ██║ ██║███████╗██║ ╚═╝ ██║███████╗ | |
* ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ | |
*/ | |
.theme-ice { | |
//@border-width: 0.3rem; | |
//@border-radius: @border-width * 2; | |
@cube-color: #c3dbea; | |
@base-mix-perc: 70%; | |
.cube-part { | |
.side { | |
box-shadow: 0 0 2px 0 lighten(@cube-color, 13%) inset, | |
0 0 0 @border-width lighten(@cube-color, 5%) inset; | |
border-radius: @border-radius; | |
.sticker { | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
border-radius: @border-radius; | |
z-index: 2; | |
background: @cube-color; | |
} | |
&.white .sticker{ | |
background-color: mix(@white, @cube-color, @base-mix-perc); | |
} | |
&.blue .sticker{ | |
background-color: mix(@blue, @cube-color, @base-mix-perc); | |
} | |
&.orange .sticker{ | |
background-color: mix(@orange, @cube-color, @base-mix-perc); | |
} | |
&.red .sticker{ | |
background-color: mix(@red, @cube-color, @base-mix-perc); | |
} | |
&.green .sticker{ | |
background-color: mix(@green, @cube-color, @base-mix-perc); | |
} | |
&.yellow .sticker{ | |
background-color: mix(@yellow, @cube-color, @base-mix-perc); | |
} | |
&.white .sticker, &.blue .sticker, &.orange .sticker, &.red .sticker, &.green .sticker, &.yellow .sticker { | |
box-shadow: 0 0 2px 0 lighten(@cube-color, 13%) inset, | |
0 0 0 @border-width lighten(@cube-color, 5%) inset, | |
0 0 1px (@border-width + 0.1) rgba(255, 255, 255, 0.2) inset; | |
background-image: radial-gradient(ellipse farthest-corner, | |
rgba(255, 255, 255, 0.2) 0%, | |
rgba(255, 255, 255, 0) 80%, | |
rgba(255, 255, 255, 0)); | |
} | |
&:after { | |
content: ''; | |
position: absolute; | |
top: 1px; | |
right: 1px; | |
bottom: 1px; | |
left: 1px; | |
border-radius: @border-radius; | |
transform: translate3d(0, 0, -1px); | |
} | |
&:before, &:after { | |
background: lighten(@cube-color, 10%); | |
} | |
} | |
} | |
} | |
/** | |
* ████████╗██╗ ██╗███████╗███╗ ███╗███████╗ | |
* ╚══██╔══╝██║ ██║██╔════╝████╗ ████║██╔════╝ | |
* ██║ ███████║█████╗ ██╔████╔██║█████╗ | |
* ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██╔══╝ | |
* ██║ ██║ ██║███████╗██║ ╚═╝ ██║███████╗ | |
* ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ | |
*/ | |
.theme-realistic { | |
.cube-part { | |
.side { | |
box-shadow: 0 0 2px 0 lighten(@cube-color, 13%) inset, | |
0 0 0 @border-width lighten(@cube-color, 5%) inset; | |
border-radius: @border-radius; | |
.sticker { | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
border-radius: @border-radius; | |
z-index: 2; | |
background: @cube-color; | |
} | |
&.white .sticker{ | |
background-color: @white; | |
} | |
&.blue .sticker{ | |
background-color: @blue; | |
} | |
&.orange .sticker{ | |
background-color: @orange; | |
} | |
&.red .sticker{ | |
background-color: @red; | |
} | |
&.green .sticker{ | |
background-color: @green; | |
} | |
&.yellow .sticker{ | |
background-color: @yellow; | |
} | |
&.white .sticker, &.blue .sticker, &.orange .sticker, &.red .sticker, &.green .sticker, &.yellow .sticker { | |
box-shadow: 0 0 2px 0 lighten(@cube-color, 13%) inset, | |
0 0 0 @border-width lighten(@cube-color, 5%) inset, | |
0 0 1px (@border-width + 0.1) rgba(255, 255, 255, 0.2) inset; | |
background-image: radial-gradient(ellipse farthest-corner, | |
rgba(255, 255, 255, 0.1) 0%, | |
rgba(255, 255, 255, 0) 60%, | |
rgba(255, 255, 255, 0)); | |
} | |
&:after { | |
content: ''; | |
position: absolute; | |
top: 1px; | |
right: 1px; | |
bottom: 1px; | |
left: 1px; | |
border-radius: @border-radius; | |
transform: translate3d(0, 0, -1px); | |
background: lighten(@cube-color, 10%); | |
} | |
} | |
} | |
} |