Skip to content

Instantly share code, notes, and snippets.

@rulers
Created February 22, 2017 03:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rulers/7f4d0b71ff6b6d4335b264bd4ab5e302 to your computer and use it in GitHub Desktop.
Save rulers/7f4d0b71ff6b6d4335b264bd4ab5e302 to your computer and use it in GitHub Desktop.
Longcat Scroll
- var gridSize = 5;
.achiev-banner(id="banner")
.achiev-name="Name"
.achiev-req="req"
- for (var i = 0;i < Math.pow(gridSize, 2); ++i) {
.eye-track-cell
- }
.longcat
.right-ear
.left-ear
.right-arm
.right-paw
.torso
.bottom
.tail
.tail-outer
.right-leg
.right-lower-leg
.right-foot
.left-leg
.left-lower-leg
.left-foot
.head
.right-eye
.left-eye
.nose-mouth
.right-cheek
.left-cheek
- for (var i = 0;i < 10; ++i) {
.whisker
- }
.left-arm
.left-paw

Longcat Scroll

This cat is loooooooooooooooooooooooooooooong. Make her even longer by scrolling down! This concept is based on endless.horse. Plus, I included an achievement system for reaching certain lengths, and a banner will slide down from the top after each achievement.

Update 2/15: Fixed gradient transparency issues in Safari, added wagging animation to tail

Body Length Achievement
1000px Looooong
2000px Loooooooooong
5280px The Mile Stone
10000px Leviacat
15000px Catzilla
20000px Piercing the Clouds
25000px Catching the White Dots
35000px Catching Poptart Cats
99999px To Felinity and Beyond!

A Pen by Jon Kantner on CodePen.

License.

(function longcat(){
var growthAmount = 50,
grow = function grow(eleClass, amount, achievOffset) {
var ele = document.querySelector(eleClass),
eleH = ele.offsetHeight,
achievBanner = document.querySelector("#banner"),
achievName = document.querySelector(".achiev-name"),
achievReq = document.querySelector(".achiev-req"),
achievements = [
[1000, "Looooong"],
[2000, "Loooooooooong"],
[5280, "The Mile Stone"],
[10000, "Leviacat"],
[15000, "Catzilla"],
[20000, "Piercing the Clouds"],
[25000, "Catching the White Dots"],
[35000, "Catching Poptart Cats"],
[99999, "To Felinity and Beyond!"]
];
if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
eleH += amount;
ele.style.height = eleH + "px";
// achievements
for (let i in achievements) {
if (eleH >= achievements[i][0] && eleH <= achievements[i][0] + achievOffset) {
achievBanner.className = "achiev-banner achiev-earned";
setTimeout(function(){
achievBanner.className = "achiev-banner";
}, 4000);
achievName.innerHTML = achievements[i][1];
achievReq.innerHTML = "Reached " + achievements[i][0] + " pixels";
}
}
}
};
window.addEventListener('scroll', function(){
grow('.torso', growthAmount, growthAmount);
});
})();
$torsoH: 280px;
$dur: 1s;
$hair: rgba(232,232,232,1);
$hairT: rgba(232,232,232,0);
$hairDark: rgba(209,209,209,1);
$hairDarkT: rgba(209,209,209,0);
$ear: rgba(240,192,192,1);
$earT: rgba(240,192,192,0);
$mouth: rgba(224,112,112,1);
$spacer: rgba(162,162,162,1);
$spacerT: rgba(162,162,162,0);
$pawPrint: rgba(139,139,139,1);
$pawPrintT: rgba(139,139,139,0);
$belly: rgba(197,197,197,1);
$whisker: rgba(255,255,255,1);
$whiskerRad: 2px;
$t: transparent;
$gridSize: 5; // must match gridSize in Pug code
$gridSizeHalved: $gridSize / 2;
$areaW: 100% / $gridSize;
$bannerH: 80px;
body {
background-color: rgb(150,125,70);
font-family: "Catamaran", sans-serif;
/* Yes, Cat-amaran! :3 */
margin: 0;
}
div {
position: absolute;
}
.achiev-banner,
.eye-track-cell {
position: fixed;
}
.achiev-banner {
background-color: rgba(255,255,255,0.8);
height: $bannerH;
text-align: center;
top: -$bannerH;
width: 100%;
z-index: 2;
> div {
position: static;
}
.achiev-name {
font: {
size: 18pt;
weight: bold;
};
height: $bannerH * 0.6;
line-height: $bannerH * 0.6;
}
.achiev-req {
font-size: 13pt;
height: $bannerH * 0.4;
line-height: $bannerH * 0.4;
}
}
.achiev-earned {
animation: achievement 4s linear;
}
/* Longcat cursor tracking with eyes */
.eye-track-cell {
width: $areaW;
height: $areaW;
z-index: 1;
@for $y from 1 through $gridSize {
@for $x from 1 through $gridSize {
$int: ($y - 1)*$gridSize + $x + 1;
&:nth-of-type(#{$int}) {
$top: $areaW * ($y - 1);
$left: $areaW * ($x - 1);
// strip units if 0
@if $top == 0 {
$top: 0;
}
@if $left == 0 {
$left: 0;
}
top: $top;
left: $left;
&:hover ~ .longcat {
.right-eye, .left-eye {
// 1. make center square 0 if $gridSize is odd or skip 0 if even
// 2. get adjusted $x values by subtracting $gridSize cut in half from $x
// if even $gridSize
@if $gridSize % 2 == 0 {
@if $x <= $gridSizeHalved {
$x: $x - ($gridSizeHalved + 1);
} @else {
$x: $x - $gridSizeHalved;
}
}
// if odd $gridSize
@else {
$x: $x - ceil($gridSizeHalved);
}
$deg: atan(-$x / ($y - 1)) * 180/pi();
// for odd $gridSize, make the eyes use 0deg for cell 0,0 instead of NaN
@if $int == ceil($gridSizeHalved) + 1 and $gridSize % 2 != 0 {
$deg: 0;
}
transform: rotate(0deg + $deg);
}
}
}
}
}
}
/* Longcat herself */
.longcat {
margin: auto;
position: relative;
width: 345px;
height: 100vh;
}
.right-ear,
.left-ear,
.right-arm,
.right-paw,
.head,
.right-cheek,
.left-cheek,
.left-arm,
.left-paw,
.tail,
.tail-outer,
.tail-outer::after {
background-color: $hair;
}
.right-arm,
.right-paw,
.right-eye,
.left-eye,
.head,
.right-leg,
.left-leg {
border-radius: 50%;
}
/* Top */
.right-ear {
background-image: radial-gradient(
75% 225% at 25% 100%,
$ear,
$ear 50%,
$earT 51%
);
border-radius: 40px 40px 0px 0px / 160px 160px 0px 0px;
width: 20px;
height: 40px;
top: 10px;
left: 115px;
transform: rotate(-40deg);
}
.left-ear {
background-image: radial-gradient(
75% 188% at 50% 100%,
$ear,
$ear 50%,
$t 51%
);
border-radius: 80px 80px 0 0 / 160px 160px 0 0;
width: 30px;
height: 40px;
left: 205px;
transform: rotate(30deg);
}
.right-arm {
background-image: linear-gradient(
$hairDarkT,
$hairDarkT 30%,
$hairDark 31%
);
width: 130px;
height: 45px;
top: 70px;
left: 35px;
transform: rotate(15deg);
}
.right-paw {
background-image:
radial-gradient(
24px 26px at 18px 13px,
$hairDark,
$hairDark 50%,
$hairDarkT 51%
),
radial-gradient(
24px 23px at 21px 10px,
$spacer,
$spacer 50%,
$hairDarkT 51%
),
radial-gradient(
24px 26px at 38px 13px,
$hairDark,
$hairDark 50%,
$hairDarkT 51%
),
radial-gradient(
24px 24px at 41px 12px,
$spacer,
$spacer 50%,
$spacerT 51%
),
radial-gradient(
24px 26px at 49px 13px,
$hairDark,
$hairDark 50%,
$hairDarkT 51%
),
radial-gradient(
24px 24px at 52px 12px,
$spacer,
$spacer 50%,
$spacerT 51%
),
linear-gradient(
$hairDark,
$hairDark 72%,
$hairDarkT 73%
);
border-radius: 30px;
width: 72px;
height: 36px;
top: 8px;
left: 0;
transform: rotate(165deg) {
origin: 18px 18px;
};
}
.head {
background-image:
radial-gradient(
20px 20px at 38% 53%,
$hair,
$hair 50%,
$hairT 51%
),
radial-gradient(
95% 80% at 45% 63%,
$hairDark,
$hairDark 50%,
$hairDarkT 51%
);
width: 120px;
height: 90px;
top: 28px;
left: 120px;
transform: rotate(-5deg);
}
.right-eye, .left-eye {
background-color: rgb(0,0,0);
box-shadow: 0 2px 0 2px rgb(160,160,80) inset;
width: 20px;
height: 20px;
top: 25px;
transition: transform 0.2s linear;
transform: rotate(-135deg);
}
.right-eye {
left: 15px;
}
.left-eye {
left: 55px;
}
.nose-mouth {
background-color: $mouth;
background-image:
radial-gradient(
5px 5px at 8px 7px,
rgb(0,0,0),
rgb(0,0,0) 50%,
$t 60%
),
radial-gradient(
5px 5px at 16px 7px,
rgb(0,0,0),
rgb(0,0,0) 50%,
$t 60%
),
radial-gradient(
16px 1px at 12px 22px,
rgb(0,0,0),
rgb(0,0,0) 50%,
$t 60%
);
border-radius: 50% 50% 33% 33%;
width: 25px;
height: 25px;
top: 45px;
left: 32px;
}
.right-cheek, .left-cheek {
background: {
color: $hairDark;
image:
radial-gradient(
$whiskerRad $whiskerRad at 6px 6px,
$spacer,
$spacer 50%,
$spacerT 60%
),
radial-gradient(
$whiskerRad $whiskerRad at 12px 3px,
$spacer,
$spacer 50%,
$spacerT 60%
),
radial-gradient(
$whiskerRad $whiskerRad at 18px 6px,
$spacer,
$spacer 50%,
$spacerT 60%
),
radial-gradient(
$whiskerRad $whiskerRad at 6px 12px,
$spacer,
$spacer 50%,
$spacerT 60%
),
radial-gradient(
$whiskerRad $whiskerRad at 12px 9px,
$spacer,
$spacer 50%,
$spacerT 60%
),
radial-gradient(
$whiskerRad $whiskerRad at 18px 12px,
$spacer,
$spacer 50%,
$spacerT 60%
),
radial-gradient(
$whiskerRad $whiskerRad at 12px 15px,
$spacer,
$spacer 50%,
$spacerT 60%
);
};
border-radius: 50%;
width: 25px;
height: 20px;
top: 50px;
}
.right-cheek {
left: 20px;
transform: rotate(-8deg);
}
.left-cheek {
left: 44px;
transform: rotate(8deg);
}
.left-arm {
background-image: linear-gradient($hairDarkT,$hairDarkT 30%,$hairDark 31%);
border-radius: 50%;
width: 105px;
height: 45px;
top: 65px;
left: 189px;
transform: rotate(40deg);
}
.left-paw {
background-image:
radial-gradient(
6px 9px at 20% 60%,
$pawPrint,
$pawPrint 50%,
$pawPrintT 55%
),
radial-gradient(
6px 9px at 38% 40%,
$pawPrint,
$pawPrint 50%,
$pawPrintT 55%
),
radial-gradient(
6px 9px at 60% 40%,
$pawPrint,
$pawPrint 50%,
$pawPrintT 55%
),
radial-gradient(
6px 9px at 80% 60%,
$pawPrint,
$pawPrint 50%,
$pawPrintT 55%
),
radial-gradient(
15px 15px at 50% 75%,
$pawPrint,
$pawPrint 50%,
$pawPrintT 55%
),
radial-gradient(
87% 87% at 54% 55%,
$hairDark,
$hairDark 50%,
$pawPrintT 51%
);
border-radius: 30px;
width: 45px;
height: 45px;
top: 0;
left: -10px;
transform: rotate(-50deg);
}
.whisker {
border-top: 1px solid rgb(255,255,255);
width: 60px;
height: 0;
&:nth-child(n+6):nth-child(-n+10) {
transform-origin: 100% 0;
}
&:nth-child(n+11):nth-child(-n+15) {
transform-origin: 0 0;
}
&:nth-child(6) {
transform: rotate(5deg);
top: 52px;
left: -28px;
}
&:nth-child(7) {
transform: rotate(-3deg);
top: 56px;
left: -34px;
}
&:nth-child(8) {
transform: rotate(-13deg);
top: 59px;
left: -28px;
}
&:nth-child(9) {
transform: rotate(-20deg);
top: 62px;
left: -34px;
}
&:nth-child(10) {
transform: rotate(-29deg);
top: 65px;
left: -27px;
}
&:nth-child(11) {
transform: rotate(5deg);
top: 52px;
left: 57px;
}
&:nth-child(12) {
transform: rotate(7deg);
top: 56px;
left: 62px;
}
&:nth-child(13) {
transform: rotate(12deg);
top: 58px;
left: 56px;
}
&:nth-child(14) {
transform: rotate(18deg);
top: 62px;
left: 62px;
}
&:nth-child(15) {
transform: rotate(21deg);
top: 65px;
left: 55px;
}
}
/* Body */
.torso {
animation: hang $dur linear infinite alternate;
background-color: $belly;
border-radius: 25px / 160px 160px 20px 20px;
box-shadow: -3px 0 0 20px $hairDark inset;
top: 84px;
left: 135px;
min-height: $torsoH;
height: calc(100vh - 320px);
width: 115px;
position: relative;
transform: rotate(0deg) {
origin: 57px 0;
};
transition: height 0.25s ease-out;
}
.bottom {
background-color: $belly;
border-radius: 0px 0px 80px 80px / 0px 0px 160px 160px;
box-shadow: -3px -20px 0 20px $hairDark inset;
top: calc(100% - 20px);
width: 100%;
height: 100px;
&::after {
content: "";
display: block;
width: 100%;
height: 300px;
}
}
.tail, .tail-outer {
background-image: linear-gradient($hairDarkT,$hairDarkT 30%,$hairDark 31%);
border-radius: 0 20px 20px 0;
height: 40px;
}
.tail {
animation: wagTail $dur*2 ease-in infinite alternate;
width: 100px;
top: 0;
left: 50%;
transform: rotate(30deg) {
origin: 0 20px;
};
z-index: -1;
}
.tail-outer {
animation: wagOuterTail $dur*2 ease-in infinite alternate;
transform: rotate(-30deg) {
origin: 0 20px;
};
width: 80px;
left: 80px;
&::after {
background-image: linear-gradient(160deg,$hairDarkT,$hairDarkT 40%,$hairDark 41%);
border: {
left: 1px solid $hair * 0.7;
radius: 50%;
};
content: "";
display: block;
margin: 0 0 0 auto;
height: 40px;
width: 40px;
}
}
.right-leg,
.left-leg,
.right-lower-leg,
.left-lower-leg,
.right-foot,
.left-foot {
background-color: $hairDark;
z-index: -2;
}
.right-leg, .left-leg {
animation: pivotLeg $dur linear infinite alternate;
top: 20px;
height: 130px;
width: 55px;
transform-origin: 27px 27px;
}
.left-leg {
right: 0;
}
.right-lower-leg,
.left-lower-leg {
border-radius: 15% 15% 50% 50%;
top: 73%;
height: 90px;
width: 44px;
transform-origin: 22px 22px;
}
.right-lower-leg {
left: 6px;
transform: rotate(-5deg);
}
.left-lower-leg {
left: 3px;
transform: rotate(5deg);
}
.right-foot, .left-foot {
background-image:
radial-gradient(
3px 15px at 25% 93%,
$spacer,
$spacer 50%,
$t 60%
),
radial-gradient(
3px 15px at 50% 93%,
$spacer,
$spacer 50%,
$t 60%
),
radial-gradient(
3px 15px at 75% 93%,
$spacer,
$spacer 50%,
$t 60%
);
border-radius: 20px;
transform-origin: 10px 10px;
top: 67%;
left: 5px;
height: 84px;
width: 35px;
}
.right-foot {
transform: rotate(15deg);
}
.left-foot {
transform: rotate(-15deg);
}
@keyframes hang {
from {
transform: rotate(0.5deg);
}
to {
transform: rotate(-0.5deg);
}
}
@keyframes pivotLeg {
from {
transform: rotate(1.5deg);
}
to {
transform: rotate(-1.5deg);
}
}
@keyframes wagTail {
from, 50% {
transform: rotate(30deg);
}
to {
transform: rotate(20deg);
}
}
@keyframes wagOuterTail {
from, 50% {
transform: rotate(-30deg);
}
to {
transform: rotate(-60deg);
}
}
@keyframes achievement {
from {
transform: translateY(0);
}
10%, 90% {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
<link href="https://fonts.googleapis.com/css?family=Catamaran" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment