Skip to content

Instantly share code, notes, and snippets.

@pixelass
Created March 27, 2016 09:17
Show Gist options
  • Save pixelass/82fcdc1609950ed97034 to your computer and use it in GitHub Desktop.
Save pixelass/82fcdc1609950ed97034 to your computer and use it in GitHub Desktop.
RubiCSS cube
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
ul.cube-part
li(class=z>1?"side top white" : "side top")
.sticker
li(class=z<1?"side bottom yellow" : "side bottom")
.sticker
li(class=y>1?"side right orange" : "side right")
.sticker
li(class=y<1?"side left red" : "side left")
.sticker
li(class=x>1?"side back green" : "side back")
.sticker
li(class=x<1?"side front blue" : "side front")
.sticker
// --- @start control section
.controls
// --- @start button-wrapper
.button-wrapper
div
- each theme in ["flat", "realistic"]
button(type="button"
class=theme==="flat"?"themer selected" : "themer"
data-theme="#{theme}") #{theme}
button(type="button"
class="scrambler") Scramble
h1 RubiCCS cube
h2 drag anywhere to rotate
h2 drag cube to play
h3 The middle slice does not turn, just like a real Rubik's cube
// --- @start canvas
.canvas.theme-flat
.cube-wrapper
.cube
.swiper.top(data-x="y"
data-y="x"
data-control="top")
.swiper.bottom(data-x="y"
data-y="x"
data-control="bottom")
.swiper.left(data-x="y"
data-y="z"
data-control="left")
.swiper.right(data-x="y"
data-y="z"
data-control="right")
.swiper.front(data-x="z"
data-y="x"
data-control="front")
.swiper.back(data-x="z"
data-y="x"
data-control="back")
// --- @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)

RubiCSS cube

Chrome only !!! a Rubik's Cube made in HTML, JavaScript and CSS.

Drag to play

Now works in Firefox!!!!

A Pen by Gregor Adams on CodePen.

License.

/* jshint sub: true */
(function($, window, document, undefined) {
'use strict';
var data = {};
var allTurns = ['base', 'left', 'right'];
var allAx = ['x', 'y', 'z'];
for (var a = 0; a < allAx.length; a++) {
data[allAx[a]] = {};
for (var l = 0; l < allTurns.length; l++) {
data[allAx[a]][allTurns[l]] = {};
}
}
var makeData1 = function(m, n, o, i, dir) {
var v = $.extend(true, [], data[m].base[i]);
var w = $.extend(true, [], data[m].base[i]);
data[m][dir][i] = v.sort(function(a, b) {
if (a[o] > b[o]) {
return 1;
} else if (a[o] < b[o]) {
return -1;
} else {
if (a[n] > b[n]) {
return -1;
} else {
return 1;
}
}
});
};
var makeData2 = function(m, n, o, i, dir) {
var v = $.extend(true, [], data[m].base[i]);
var w = $.extend(true, [], data[m].base[i]);
data[m][dir][i] = w.sort(function(a, b) {
if (a[o] > b[o]) {
return -1;
} else if (a[o] < b[o]) {
return 1;
} else {
if (a[n] > b[n]) {
return 1;
} else {
return -1;
}
}
});
};
var makeData3 = function(m, n, o, i, dir) {
var v = $.extend(true, [], data[m].base[i]);
var w = $.extend(true, [], data[m].base[i]);
data[m][dir][i] = v.sort(function(a, b) {
if (a[o] > b[o]) {
return 1;
} else if (a[o] < b[o]) {
return -1;
} else {
if (a[n] > b[n]) {
return 1;
} else {
return -1;
}
}
});
};
var makeData4 = function(m, n, o, i, dir) {
var v = $.extend(true, [], data[m].base[i]);
var w = $.extend(true, [], data[m].base[i]);
data[m][dir][i] = w.sort(function(a, b) {
if (a[o] > b[o]) {
return -1;
} else if (a[o] < b[o]) {
return 1;
} else {
if (a[n] > b[n]) {
return -1;
} else {
return 1;
}
}
});
};
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': 0,
'y': i,
'z': 0
}, {
'x': 0,
'y': i,
'z': 1
}, {
'x': 0,
'y': i,
'z': 2
}, {
'x': 1,
'y': i,
'z': 0
}, {
'x': 1,
'y': i,
'z': 1
}, {
'x': 1,
'y': i,
'z': 2
}, {
'x': 2,
'y': i,
'z': 0
}, {
'x': 2,
'y': i,
'z': 1
}, {
'x': 2,
'y': i,
'z': 2
}];
data['z']['base'][i] = [{
'x': 0,
'y': 2,
'z': i
}, {
'x': 1,
'y': 2,
'z': i
}, {
'x': 2,
'y': 2,
'z': i
}, {
'x': 0,
'y': 1,
'z': i
}, {
'x': 1,
'y': 1,
'z': i
}, {
'x': 2,
'y': 1,
'z': i
}, {
'x': 0,
'y': 0,
'z': i
}, {
'x': 1,
'y': 0,
'z': i
}, {
'x': 2,
'y': 0,
'z': i
}];
makeData1('x', 'y', 'z', i, 'left');
makeData2('x', 'y', 'z', i, 'right');
makeData2('y', 'x', 'z', i, 'left');
makeData1('y', 'x', 'z', i, 'right');
makeData3('z', 'y', 'x', i, 'left');
makeData4('z', 'y', 'x', i, 'right');
}
var rotate3d = {
'x': '1,0,0,',
'y': '0,1,0,',
'z': '0,0,1,'
};
var $gripAxis;
var cubeRotationSpeed = 1.5;
var cache = {};
var canvas = {
'threshold': 10,
'block': false,
'down': false,
'axis': null,
'css': '',
'mouse': {
'distance': 0,
'time': 0
}
};
var randomNumber = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
var classWithPrefix = 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, direction) {
if (!turnAxis) {
return false;
}
var axis = ['x', 'y', 'z'];
var elements = [];
var oppositeDirection = direction === 'right' ? 'left' : 'right';
$.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) {
$.each(axis, function(j, ax) {
$(el).attr('data-' +
ax, data[turnAxis][oppositeDirection][level][i][ax]);
});
});
};
/**
* @jsdoc function
* @name rubics.performTurn
* @description
* performes the turn.
* allows a callback when the turn is done
*/
var performTurn = function(rotate3d, turnAxis, direction, callback) {
var degree = direction === 'right' ? 90 : -90;
$('.grip').find('.axis-grip:first').css({
transform: 'rotate3d(' +
rotate3d[turnAxis] +
degree +
'deg)'
}).one('transitionend', callback);
};
/**
* @jsdoc function
* @name rubics.rotateParts
* @description
* rotates the parts
*/
var rotateParts = function(rotate3d, turnAxis, direction) {
$('.grip .cube-part-wrapper').each(function(i, el) {
var degree = direction === 'right' ? 90 : -90;
var css = $(el).find('.axis-part')[0].style.transform;
css = css === 'none' ? '' : css;
css = 'rotate3d(' +
rotate3d[turnAxis] +
degree +
'deg) ' +
css;
$(el).find('.axis-part').css({
transform: css
});
});
};
/**
* @jsdoc function
* @name rubics.attachParts
* @description
* puts the parts back into the cube
*/
var attachParts = function(turnAxis, level) {
$('[data-' + turnAxis + '=' + level + ']')
.appendTo('.cube');
};
/**
* @jsdoc function
* @name rubics.detachParts
* @description
* puts the parts into the grip
*/
var detachParts = function(turnAxis, level) {
$('[data-' + turnAxis + '=' + level + ']')
.appendTo('.grip .axis-grip');
};
/**
* @jsdoc function
* @name rubics.autoTurn
* @description
* automatically turn
*/
var autoTurn = function(turnAxis, level, direction) {
if (!canvas.block) {
canvas.block = true;
turnAxis = turnAxis || 'x';
level = level || 0;
detachParts(turnAxis, level);
performTurn(rotate3d, turnAxis, direction, function() {
rotateParts(rotate3d, turnAxis, direction);
attachParts(turnAxis, level);
clearHelpers();
positionParts(turnAxis, level, direction);
window.setTimeout(function() {
canvas.block = false;
}, 2);
});
} else {
return;
}
};
/**
* @jsdoc function
* @name rubics.scrambleCube
* @description
* scramble the cube
*/
var scrambleCube = function(n) {
var axis = ['x', 'y', 'z'];
var direction = ['left', 'right'];
$gripAxis.addClass('fast');
var duration = $gripAxis.css('transition-duration');
duration = (parseFloat(duration) + 0.1) * 1000;
var play = setInterval(function() {
var dir = direction[randomNumber(0, 1)];
var axi = axis[randomNumber(0, 2)];
var level = randomNumber(0, 2);
dir = cache.dir === dir ? (dir === 'left' ? 'right' : 'left') : dir;
axi = cache.axi === axi ? (axi === 'x' ? 'y' : 'z') : axi;
axi = cache.axi === axi ? (axi === 'z' ? 'x' : 'y') : axi;
axi = cache.axi === axi ? (axi === 'y' ? 'z' : 'x') : axi;
level = level === 1 ? randomNumber(0, 2) : level;
level = level === 1 ? 2 : level;
level = cache.level === level ? (level === 0 ? 2 : 0) : level;
level = cache.level === level ? (level === 2 ? 0 : 2) : level;
cache = {
dir: dir,
axi: axi,
level: level
};
autoTurn(axi, level, dir);
}, duration);
setTimeout(function() {
$gripAxis.removeClass('fast');
if (play) {
clearTimeout(play);
}
}, duration * n);
};
/**
* @jsdoc function
* @name rubics.releaseSwiper
* @description
* release the Swiper
*/
var releaseSwiper = function(e) {
if (canvas.swiper && canvas.swiper.play) {
canvas.swiper.play = false;
if (!canvas.swiper.move) {
return false;
}
canvas.swiper.move = false;
if (canvas.swiper.degree >= -30 && canvas.swiper.degree <= 30) {
$gripAxis.removeClass('manual').css({
transform: 'rotate3d(0,0,0,0deg)'
}).one('transitionend', function() {
attachParts(canvas.swiper.axis, canvas.swiper.level);
clearHelpers();
});
} else {
var direction = canvas.swiper.degree > 0 ? 'right' : 'left';
$gripAxis.removeClass('manual').css({
transform: 'rotate3d(' +
rotate3d[canvas.swiper.axis] +
(canvas.swiper.degree > 0 ? '90' : '-90') + 'deg)'
}).one('transitionend', function() {
rotateParts(rotate3d, canvas.swiper.axis, direction);
attachParts(canvas.swiper.axis, canvas.swiper.level);
clearHelpers();
positionParts(canvas.swiper.axis, canvas.swiper.level, direction);
canvas.swiper = false;
});
}
}
};
/**
* @jsdoc function
* @name rubics.moveSwiper
* @description
* movement on the the Swiper
*/
var moveSwiper = function(e) {
if (canvas.swiper && canvas.swiper.play) {
e.preventDefault();
canvas.swiper.move = {
'x': e.offsetX || e.originalEvent.layerX,
'y': e.offsetY || e.originalEvent.layerY
};
canvas.swiper.distance = {};
canvas.swiper.distance.x = (canvas.swiper.start.x -
canvas.swiper.move.x) /
canvas.swiper.size.x * 90;
canvas.swiper.distance.y = (canvas.swiper.start.y -
canvas.swiper.move.y) /
canvas.swiper.size.x * 90;
if (!canvas.swiper.active &&
(canvas.swiper.distance.x > canvas.threshold ||
canvas.swiper.distance.x < -1 * canvas.threshold)) {
canvas.swiper.axis = canvas.swiper.sides.x;
canvas.swiper.degree = (canvas.swiper.start.x -
canvas.swiper.move.x) /
canvas.swiper.size.x * 90;
canvas.swiper.side = 'y';
canvas.swiper.turn = 'x';
canvas.swiper.active = true;
} else if (!canvas.swiper.active &&
(canvas.swiper.distance.y > canvas.threshold ||
canvas.swiper.distance.y < -1 * canvas.threshold)) {
canvas.swiper.axis = canvas.swiper.sides.y;
canvas.swiper.side = 'x';
canvas.swiper.turn = 'y';
canvas.swiper.active = true;
}
if (canvas.swiper.axis) {
if (!canvas.swiper.init) {
canvas.swiper.init = true;
if (canvas.swiper.delta[canvas.swiper.side] < 1.5) {
canvas.swiper.level = canvas.swiper.side === 'x' ? 0 : 2;
canvas.swiper.level = canvas.swiper.side === 'y' &&
canvas.swiper.control === 'right' ? 0 : canvas.swiper.level;
canvas.swiper.level = canvas.swiper.side === 'x' &&
canvas.swiper.control === 'front' ? 2 : canvas.swiper.level;
canvas.swiper.level = canvas.swiper.side === 'x' &&
canvas.swiper.control === 'bottom' ? 2 : canvas.swiper.level;
canvas.swiper.level = canvas.swiper.controls === 'front' &&
canvas.swiper.side === 'x' ? 0 : canvas.swiper.level;
} else if (canvas.swiper.delta[canvas.swiper.side] < 3) {
return false; // can't turn ceter slice
canvas.swiper.level = 1;
} else {
canvas.swiper.level = canvas.swiper.side === 'x' ? 2 : 0;
canvas.swiper.level = canvas.swiper.side === 'y' &&
canvas.swiper.control === 'right' ? 2 : canvas.swiper.level;
canvas.swiper.level = canvas.swiper.side === 'x' &&
canvas.swiper.control === 'front' ? 0 : canvas.swiper.level;
canvas.swiper.level = canvas.swiper.side === 'x' &&
canvas.swiper.control === 'bottom' ? 0 : canvas.swiper.level;
}
detachParts(canvas.swiper.axis, canvas.swiper.level);
$gripAxis
.addClass('manual');
}
var factor = 1;
factor = canvas.swiper.side === 'x' &&
canvas.swiper.control === 'front' ? -1 : factor;
factor = canvas.swiper.side === 'y' &&
canvas.swiper.control === 'right' ? -1 : factor;
factor = canvas.swiper.side === 'x' &&
canvas.swiper.control === 'bottom' ? -1 : factor;
canvas.swiper.degree = (canvas.swiper.start[canvas.swiper.turn] -
canvas.swiper.move[canvas.swiper.turn]) /
canvas.swiper.size[canvas.swiper.side] * 90 * factor;
$gripAxis.css({
transform: 'rotate3d(' +
rotate3d[canvas.swiper.axis] +
canvas.swiper.degree + 'deg)'
});
}
}
};
/**
* @jsdoc function
* @name rubics.initSwiper
* @description
* init the Swiper
*/
var initSwiper = function(e) {
canvas.swiper = {};
canvas.swiper.control = $(this).data('control');
canvas.swiper.play = true;
canvas.swiper.sides = {
'x': $(this).data('x'),
'y': $(this).data('y')
};
canvas.swiper.size = {
'x': e.target.clientWidth,
'y': e.target.clientHeight
};
canvas.swiper.start = {
'x': e.offsetX || e.originalEvent.layerX,
'y': e.offsetY || e.originalEvent.layerY
};
canvas.swiper.delta = {
'x': canvas.swiper.size.x / canvas.swiper.start.x,
'y': canvas.swiper.size.y / canvas.swiper.start.y
};
};
/**
* @jsdoc function
* @name rubics.moveCube
* @description
* rotates the cube itself
*/
var moveCube = function(e) {
if (!canvas.down) {
return false;
}
e.preventDefault();
var x = (e.pageX - canvas['mouse']['x']) / 4;
var y = (e.pageY - canvas['mouse']['y']) / -4;
var transformation = '';
if ((x > canvas.threshold ||
x < -1 * canvas.threshold) &&
canvas['axis'] !== 'x') {
canvas['axis'] = 'y';
transformation += 'rotate3d(0, 1, 0, ';
transformation += x * cubeRotationSpeed;
transformation += 'deg) ';
transformation += canvas['css'];
canvas['mouse']['distance'] = x;
canvas.moved = true;
} else if ((y > canvas.threshold ||
y < -1 * canvas.threshold) &&
canvas['axis'] !== 'y') {
canvas['axis'] = 'x';
transformation += 'rotate3d(1, 0, 0, ';
transformation += y * cubeRotationSpeed;
transformation += 'deg) ';
transformation += canvas['css'];
canvas['mouse']['distance'] = y;
canvas.moved = true;
} else {
canvas.moved = false;
return false;
}
if (canvas.moved) {
$('.cube-wrapper').css({
transform: transformation
});
}
};
/**
* @jsdoc function
* @name rubics.releaseCuber
* @description
* release the Cube
*/
var releaseCube = function(e) {
if (canvas.down) {
canvas.down = false;
if (!canvas.moved) {
return false;
}
canvas.moved = false;
canvas['mouse']['end'] = +new Date();
canvas['mouse']['time'] = canvas['mouse']['end'] -
canvas['mouse']['start'];
canvas['mouse']['bouce'] = (canvas['mouse']['distance'] /
canvas['mouse']['time']) *
100;
canvas['css'] = $('.cube-wrapper')[0].style.transform;
canvas['mouse']['bouce'] = Math.abs(canvas['mouse']['bouce']) <=
5 ? 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'] *
cubeRotationSpeed +
'deg) ' +
canvas['css']
}).one('transitionend', function() {
$('.cube-wrapper').css({
transitionDuration: ''
});
});
}
};
/**
* @jsdoc function
* @name rubics.onMouseDown
* @description
* check where we are then perform cubeRotation
* if not on buttons or cube
*/
var onMouseDown = function(e) {
e.preventDefault();
if ($(e.target).is('.swiper') ||
$(e.target).closest('.controls').length) {
return false;
}
canvas.down = true;
canvas['axis'] = false;
canvas['mouse']['x'] = e.pageX;
canvas['mouse']['y'] = e.pageY;
canvas['css'] = $('.cube-wrapper')[0].style.transform;
canvas['mouse']['start'] = +new Date();
};
$(function() {
var $themer = $('.themer');
var $canvas = $('.canvas');
$gripAxis = $('.grip').find('.axis-grip:first');
$(document)
.on('mousedown', onMouseDown)
.on('mouseup', releaseCube)
.on('mousemove', moveCube);
$('.swiper')
.on('mousedown', initSwiper)
.on('mouseleave mouseup', releaseSwiper)
.on('mousemove', moveSwiper);
$('.themer')
.on('click', function() {
var theme = $(this).data('theme');
$canvas.removeClass(classWithPrefix(/^theme-/));
$themer.removeClass('selected');
$canvas.addClass('theme-' + theme);
$(this).addClass('selected');
});
$('.scrambler')
.on('click', function() {
scrambleCube(30);
});
});
})(window.jQuery, window, document);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
// ██╗ ██╗ █████╗ ██████╗ ███████╗
// ██║ ██║██╔══██╗██╔══██╗██╔════╝
// ██║ ██║███████║██████╔╝███████╗
// ╚██╗ ██╔╝██╔══██║██╔══██╗╚════██║
// ╚████╔╝ ██║ ██║██║ ██║███████║
// ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝
//
@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: rgb(30, 30, 30);
@cube-hover-color: #f92672;
@fast: 200ms;
@medium: @fast * 2;
@slow: @medium * 2;
@base-mix-perc: 15%;
@hover-mix-perc: 35%;
@hover-base-mix-perc: 5%;
@button-color: #2b4746;
@base-font-size: 16px;
@rotater-size: 1.8rem;
@rotater-factor: 1;
@gutter-width: 1rem;
@radius: 0.1rem;
@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;
color: @white;
}
html,
body {
overflow: hidden;
}
body {
background: @button-color;
}
ul,
ol {
list-style: none;
li {
list-style: inherit;
}
}
h1 {
font-size: 1.5em;
margin: 0 @gutter-width 0.5em;
}
h2 {
font-size: 1.3em;
margin: 0 @gutter-width 0.5em;
}
h3 {
font-size: 1.1em;
margin: 0 @gutter-width 0.5em;
}
/**
* ███████╗██████╗ █████╗ ███╗ ███╗███████╗
* ██╔════╝██╔══██╗██╔══██╗████╗ ████║██╔════╝
* █████╗ ██████╔╝███████║██╔████╔██║█████╗
* ██╔══╝ ██╔══██╗██╔══██║██║╚██╔╝██║██╔══╝
* ██║ ██║ ██║██║ ██║██║ ╚═╝ ██║███████╗
* ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝
*
*/
body {
cursor: grab;
&:active {
cursor: grabbing;
}
}
.canvas {
position: absolute;
height: @cube-size * 1.5;
width: @cube-size;
overflow: visible;
top: 14em;
left: 50%;
margin-left: @cube-size/-2;
perspective: 700px;
&:hover {
cursor: grab;
}
&:active {
cursor: grabbing;
}
}
/**
* ███████╗ ██████╗ ██████╗ ███╗ ███╗███████╗
* ██╔════╝██╔═══██╗██╔══██╗████╗ ████║██╔════╝
* █████╗ ██║ ██║██████╔╝██╔████╔██║███████╗
* ██╔══╝ ██║ ██║██╔══██╗██║╚██╔╝██║╚════██║
* ██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████║
* ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝
*/
::-moz-focus-inner {
outline: 0;
}
button {
line-height: 1;
&:focus {
outline: 0;
}
}
button {
margin: 0 @gutter-width @gutter-width;
padding: 1em;
font-size: 0.6rem;
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;
}
&.selected {
color: #fff;
border-color: darken(@button-color, 10%);
background-color: darken(@button-color, 10%);
}
}
.controls {
position: absolute;
top: 0;
right: 0;
max-width: 20rem;
z-index: 5;
padding-left: @gutter-width;
padding-top: @gutter-width;
cursor: default;
}
/**
* ██████╗██╗ ██╗██████╗ ███████╗███████╗
* ██╔════╝██║ ██║██╔══██╗██╔════╝██╔════╝
* ██║ ██║ ██║██████╔╝█████╗ ███████╗
* ██║ ██║ ██║██╔══██╗██╔══╝ ╚════██║
* ╚██████╗╚██████╔╝██████╔╝███████╗███████║
* ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝
*/
.cube {
position: absolute;
top: 0;
left: 0;
height: inherit;
width: inherit;
transition: transform @medium linear;
transform-style: preserve-3d;
//backface-visibility: hidden;
transform: rotate3d(0, 1, 0, -35deg) rotate3d(1, 0, 0, 35deg);
.swiper {
position: absolute;
left: 0;
top: 0;
height: @cube-size;
width: @cube-size;
outline-offset: 10px;
visibility: visible;
//&:hover {
// box-shadow: 0 0 5px 15px @cube-hover-color;
//}
&.top {
transform: rotate3d(0,1,0,-180deg)
translate3d(0,0,@cube-size/-1.9);
}
&.bottom {
transform: translate3d(0,0,@cube-size/-1.9);
}
&.left {
transform: rotate3d(0,1,0,90deg)
translate3d(0,0,@cube-size/-1.9);
}
&.right {
transform: rotate3d(0,0,1,-180deg)
rotate3d(0,1,0,90deg)
translate3d(0,0,@cube-size/-1.9);
}
&.front {
transform: rotate3d(1,0,0,-180deg)
rotate3d(1,0,0,-90deg)
translate3d(0,0,@cube-size/-1.9);
}
&.back {
transform: rotate3d(0,1,0,-180deg)
rotate3d(1,0,0,-90deg)
translate3d(0,0,@cube-size/-1.9);
}
}
}
.cube-wrapper {
position: absolute;
top: 0;
left: 0;
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;
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;
transform-style: preserve-3d;
border-radius: @border-radius;
&.white ,
&.blue ,
&.orange ,
&.red ,
&.green ,
&.yellow {
background: @cube-color;
.sticker {
transform-style: preserve-3d;
visibility: visible;
}
}
&.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;
pointer-events: none;
visibility: hidden;
&[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;
pointer-events: none;
.axis {
&.manual {
transition: none;
}
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-radius: @border-width;
.cube-part-wrapper-112 {
.cube-part .side.white .sticker {
background-image:
url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/28359/rubik-logo.png');
background-size: 100% auto;
}
}
.cube-part {
.side {
//background: @cube-color;
background: none;
border-radius: 0;
&.white,
&.blue,
&.orange,
&.red,
&.green,
&.yellow {
.sticker {
transform: translateZ(1px);
position: absolute;
top: @border-width;
left: @border-width;
right: @border-width;
bottom: @border-width;
border-radius: @border-radius;
z-index: 2;
backface-visibility: hidden;
}
}
&.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-realistic {
.cube-part-wrapper-112 {
.cube-part .side.white .sticker {
background-image:
url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/28359/rubik-logo.png');
background-size: 100% auto;
}
}
.cube-part {
.side {
visibility: visible;
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;
background-color: @cube-color;
.sticker {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: @border-radius;
z-index: 2;
background-color: @cube-color;
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));
}
&.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,
&.blue,
&.orange,
&.red,
&.green,
&.yellow {
.sticker {
transform: translateZ(1px);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment