Skip to content

Instantly share code, notes, and snippets.

@matt-daniel-brown
Created January 2, 2019 05:21
Show Gist options
  • Select an option

  • Save matt-daniel-brown/2a0a6b1803c54547102af99645f7936f to your computer and use it in GitHub Desktop.

Select an option

Save matt-daniel-brown/2a0a6b1803c54547102af99645f7936f to your computer and use it in GitHub Desktop.
Pressure Sensitive Dot Matrix in CSS
- var blocksPerRow= 8
- var numBlocks= blocksPerRow*blocksPerRow
body(ontouchstart="")
.mouse
.circle
section
.wrapper
- for (var i= 0; i < numBlocks; i++)
div.selector
- for (var i= 0; i < numBlocks; i++)
span.visible
.el(data-delay=Math.ceil(Math.random()*10))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
@import "breakpoint";
@import "modularscale@3.*";
@import "bourbon@5.*";
$blocksPerRow: 8;
$numBlocks: $blocksPerRow*$blocksPerRow;
$marginCalc: 3%;
$dimensions: 100/$blocksPerRow *1%;
$transEase: cubic-bezier(.5, -0.5, .5, 1.5);
$transEase: ease-in-out;
$pulseDur: 2;
.custom-cursor * {
cursor: none;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
@mixin flexCode() {
display: flex;
justify-content: center;
align-items: center;
}
* {
box-sizing: border-box;
}
html, body {
background: darken(blue, 45%);
}
section {
width: 100vw;
height: 100vh;
perspective: 1000px;
transform-style: preserve-3d;
@include flexCode();
}
.wrapper {
$size: 65vmin;
width: $size;
height: $size;
position: relative;
transform-style: preserve-3d;
flex-wrap: wrap;
transform: rotateX(60deg);
// transition: transform .5s ease-out;
will-change: transform;
@include flexCode();
}
span,
div {
$dimensions: 100/$blocksPerRow *1%;
width: $dimensions;
height: $dimensions;
// margin: $marginCalc;
display: block;
// border-radius: 50% 50%;
position: relative;
z-index: 99999;
}
$trans-position: translateY( $blocksPerRow * -100%);
span.visible {
transform: $trans-position;
position: relative;
z-index: 1;
transform-style: preserve-3d;
@include flexCode();
.el {
$size: 15%;
width: $size;
height: $size;
border-radius: 50% 50%;
transition: transform .4s $transEase;
will-change: transform;
}
@for $i from 1 through $numBlocks {
&:nth-of-type(#{$i}) .el {
background: mix(cyan, blue, 100/$numBlocks*$i);
}
}
@for $i from 1 through 10 {
& .el[data-delay='#{$i}'] {
animation: animateIn 1.2s ease-out;
animation-delay: $i*.12s;
animation-fill-mode: backwards;
}
}
}
div.selector {
@for $i from 1 through $numBlocks {
&:active:nth-of-type(#{$i}) {
$outerLayer: .5, .75, 1;
$midLayer: 1.5, 2;
$centerLayer: 2.5;
$trans-amt: -30px;
//center
& ~ span.visible:nth-of-type(#{$i}) .el {
transform: translateZ($trans-amt*$centerLayer);
}
//make sure theres not a split depression on the left side when pressing a 10th dot
@if $i % $blocksPerRow !=0 {
//right
& ~ span.visible:nth-of-type(#{$i + 1}) .el {
transform: translateZ($trans-amt*nth($midLayer, 2));
}
//midLayer - above right
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow + 1}) .el {
transform: translateZ($trans-amt*nth($midLayer, 1));
}
//midLayer - below right
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow + 1}) .el {
transform: translateZ($trans-amt*nth($midLayer, 1));
}
//outerLayer - above right mid
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow*2 + 1}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
//outerLayer - below mid right
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow*2 + 1}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
//make sure theres not a split depression on left side when pressing a 9th dot
@if ($i + 1) % $blocksPerRow !=0 {
//outerLayer - mid right mid
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow + 2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
//outerLayer - mid right
& ~ span.visible:nth-of-type(#{$i + 2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 3));
}
//outerLayer - below mid right
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow + 2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
}
}
//make sure theres not a split depression on left side when pressing a 1st dot
@if ($i - 1) % $blocksPerRow !=0 {
//left
& ~ span.visible:nth-of-type(#{$i - 1}) .el {
transform: translateZ($trans-amt*nth($midLayer, 2));
}
//midLayer - above left
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow - 1}) .el {
transform: translateZ($trans-amt*nth($midLayer, 1));
}
//midLayer - below left
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow - 1}) .el {
transform: translateZ($trans-amt*nth($midLayer, 1));
}
//outerLayer - above left mid
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow*2 - 1}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
//outerLayer - below mid left
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow*2 - 1}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
//make sure theres not a split depression on left side when pressing a 2nd dot
@if ($i - 2) % $blocksPerRow !=0 {
//outerLayer - mid left mid
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow - 2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
//outerLayer - mid left
& ~ span.visible:nth-of-type(#{$i - 2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 3));
}
//outerLayer - below mid left
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow - 2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 2));
}
}
}
//midLayer - above mid
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow}) .el {
transform: translateZ($trans-amt*nth($midLayer, 2));
}
//midLayer - below mid
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow}) .el {
transform: translateZ($trans-amt*nth($midLayer, 2));
}
//outerLayer - above mid
& ~ span.visible:nth-of-type(#{$i - $blocksPerRow*2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 3));
}
//outerLayer - below mid mid
& ~ span.visible:nth-of-type(#{$i + $blocksPerRow*2}) .el {
transform: translateZ($trans-amt*nth($outerLayer, 3));
}
}
}
}
@keyframes animateIn {
0% {opacity: 0; transform: translateZ(-100px);}
50% {opacity: .2}
100% {opacity: 1; transform: translateZ(0px);}
}
.mouse {
visibility: hidden;
position: fixed;
pointer-events: none;
width: 50px;
height: 50px;
animation: showMouse .75s ease-in-out;
animation-delay: 3s;
animation-fill-mode: both;
.circle {
width: 40px;
height: 40px;
background: radial-gradient(circle at 50% -10%, rgba(255,255,255,1) 0%, rgba(255,255,255,0.4) 100%);
border-radius: 100%;
transition: all .2s ease-in-out;
pointer-events: none;
opacity: .3;
}
&.active .circle {
opacity: .2;
transform: scale(.9);
}
}
.custom-cursor .mouse {
visibility: visible;
}
@keyframes showMouse {
0% {opacity: 0}
100% {opacity: 1}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment