Skip to content

Instantly share code, notes, and snippets.

@synecdocheNORTH
Created January 4, 2019 18:02
Show Gist options
  • Save synecdocheNORTH/cfc941021e3f081c5b59f43da18ab79b to your computer and use it in GitHub Desktop.
Save synecdocheNORTH/cfc941021e3f081c5b59f43da18ab79b to your computer and use it in GitHub Desktop.
11/12: Paint on Mouse Move

11/12: Paint on Mouse Move

Animated a little drawing I did with parallaxing and 3D transforms :) She paints in rainbow brush strokes wherever your mouse goes.

A Pen by Angela He on CodePen.

License.

<div class="frame perspective">
<div class="preserve-3d" id="avatar">
<div class="body">
<img src="https://zephyo.github.io/22Days/code/11/graphics/body.png">
<!-- head -->
<div class="head">
<div class="bun">
<img src="https://zephyo.github.io/22Days/code/11/graphics/bun.png">
</div>
<div class="eyes">
<img src="https://zephyo.github.io/22Days/code/11/graphics/eyes.png">
</div>
<img src="https://zephyo.github.io/22Days/code/11/graphics/head.png">
</div>
<!-- upper arm -->
<div class="upperarm">
<img src="https://zephyo.github.io/22Days/code/11/graphics/upperarm.png">
<div class="forearm">
<img src="https://zephyo.github.io/22Days/code/11/graphics/forearm.png">
<div class="hand">
<img src="https://zephyo.github.io/22Days/code/11/graphics/hand.png">
<div class="brush">
<img src="https://zephyo.github.io/22Days/code/11/graphics/brush.png">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="wrap">
</div>
<span class="sig">by angela he</span>
<div class="block-mobile">
<h3>this doesn't work on mobile</h3>
<p>try using a computer!</p>
</div>
//Day 11: Drew the artwork in Photoshop
//Day 12: Coded it up
$(document).ready(function($) {
//check if mobile
if (isMobile()) {
$('.block-mobile').css('display', 'flex');
return;
}
function isMobile() {
if (typeof window.orientation !== 'undefined') {
return true;
}
else {
return false;
}
}
var scale = 1;
var $parallax = $('#avatar'),
$eyes = $('.eyes'),
$upperarm=$('.upperarm'),
$forearm=$('.forearm'),
$hand=$('.hand'),
cx, cy, dx, dy, tiltx, tilty, radius, degree, ratioX, ratioY, transform,
eyeTransform = $eyes.css("transform"),
uArmTransform=$upperarm.css("transform"),
fArmTransform=$forearm.css("transform"),
handTransform=$hand.css("transform"),
newUpArm,
newForeArm,
newHand;
var mousePos = {}, hue=0;
//responsive resizing
var $window = $(window);
var width;
var height;
var maxWidth = $parallax.width();
var maxHeight = $parallax.height();
function resize() {
width = $window.width();
height = $window.height();
scale = Math.min(width/maxWidth, height/maxHeight) * 1.18;
$parallax.css({'transform': 'scale(' + scale + ')'});
}
$(window).resize(resize);
resize();
//parallaxing
$(document).mousemove(function(event) {
cx = Math.ceil(width / 1.8);
cy = Math.ceil(height / 1);
dx = mousePos.x - cx;
dy = mousePos.y - cy;
tiltx = (dy / cy);
tilty = -(dx / cx);
console.log(tiltx+', '+tilty);
radius = Math.sqrt(Math.pow(tiltx, 2) + Math.pow(tilty, 2));
degree = (radius * 20);
transform = 'scale('+scale+') rotate3d(' + -tiltx + ', ' + -tilty + ', 0, ' + degree + 'deg)';
$parallax.css({
'transform': transform
});
ratioX = mousePos.x/width;
ratioY = mousePos.y/height;
$eyes.css('transform',eyeTransform+" translate("+lerp(-8,8,ratioX)+"px, "+lerp(-3,4,ratioY)+"px)");
//upperarm
newUpArm = uArmTransform;
if (ratioY < 0.5){
newUpArm += " rotate("+lerp(95,-8,ratioX)+"deg)";
}else{
newUpArm += " rotate("+lerp(55,20,ratioX)+"deg)";
}
newUpArm += " rotateX("+lerp(40,-10,ratioY)+"deg)";
$upperarm.css('transform', newUpArm);
//forearm
newForeArm = fArmTransform;
if (ratioY < 0.5){
newForeArm += " rotate("+lerp(-145,65,ratioX)+"deg)";
}else{
newForeArm += " rotate("+lerp(-85,45,ratioX)+"deg)";
}
newForeArm += " rotateX("+lerp(0,-60,ratioY)+"deg)";
$forearm.css('transform', newForeArm);
//hand
newHand = handTransform;
if (ratioX < 0.5){
newHand +=" rotate("+lerp(30,0,ratioY)+"deg)";
}else{
newHand +=" rotate("+lerp(-10,10,ratioY)+"deg)";
}
$hand.css('transform', newHand);
});
function lerp(v0, v1, t) {
return v0*(1-t)+v1*t;
}
// color particles
function getRandomInt(min, max) {
return Math.round(Math.random() * (max - min + 1)) + min;
}
$(window).mousemove(function(e) {
mousePos.x = e.pageX;
mousePos.y = e.pageY;
});
$(window).mouseleave(function(e) {
mousePos.x = -1;
mousePos.y = -1;
});
var draw = setInterval(function(){
if(mousePos.x > 0 && mousePos.y > 0){
var range = 8;
var color = "background: hsla("+hue+",90%,60%,0.6);";
hue+=1;
if (hue>360){
hue=0;
}
var sizeInt = getRandomInt(15, 45);
size = "height: " + sizeInt + "px; width: " + sizeInt + "px;";
var left = "left: " + getRandomInt(mousePos.x-range-sizeInt, mousePos.x+range) + "px;";
var top = "top: " + getRandomInt(mousePos.y-range-sizeInt, mousePos.y+range) + "px;";
var style = left+top+color+size;
$("<div class='ball' style='" + style + "'></div>").appendTo('#wrap').one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function(){$(this).remove();});
}
}, 30);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
@import url('https://fonts.googleapis.com/css?family=Mali');
$bg-url: 'https://zephyo.github.io/22Days/code/11/graphics/Background.png';
.ball {
pointer-events: none;
position: absolute;
border-radius: 50%;
animation: implode 10s ease-in-out;
animation-delay: 0.2s;
animation-fill-mode: both;
}
@keyframes implode {
0% {
transform: scale(0)
}
5%, 30% {
transform: scale(1)
}
100% {
transform: scale(0)
}
}
.frame, #wrap, html, body, .block-mobile {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: hidden;
}
* {
background-repeat: no-repeat;
}
body {
font-family: 'Mali', cursive;
background-image: url($bg-url);
background-size: auto 100%;
background-repeat: repeat-x;
background-position: center top;
}
.perspective {
perspective: 1800px;
perspective-origin:50% 10%;
}
.preserve-3d {
transform-style: preserve-3d;
}
#avatar {
position: absolute;
transform-origin: bottom;
left: 0;
bottom: 0;
right: 9vw;
margin: auto;
width: 770px;
height: 890px;
z-index: 20;
// transition: transform 0.3s ease;
div {
position: absolute;
transform-style: preserve-3d;
}
}
.body {
bottom: -40px;
left: 0;
transform: translateZ(0px);
.head {
top: -195px;
left: 138px;
img {
transform: translateZ(15px);
}
.bun {
top: -70px;
left: 50px;
transform: translateZ(-50px);
}
.eyes {
top: 175px;
left: 97px;
transform: translateZ(-5px);
transition: transform 0.2s;
}
}
}
.upperarm {
top: 188px;
right: -190px;
transform: translateZ(40px);
transform-origin: 75px 70px;
transition: transform 0.3s;
.forearm {
bottom: -5px;
right: -5px;
transform-origin: 70% 88%;
transform: translateZ(15px) rotateX(-10deg);
transition: transform 0.2s;
.hand {
top: -202px;
left: -170px;
transform-origin: 70% 90%;
transform: translateZ(10px) rotateX(10deg);
transition: transform 0.2s ease;
.brush {
top: -165px;
left: 115px;
transform-origin: bottom;
transform: rotateX(-20deg) scale(1.1);
}
}
}
}
.sig {
position: absolute;
right: 1vh;
bottom: 1vh;
color: #986d5b;
}
.block-mobile {
background: linear-gradient(to right, rgba(#ffecd2,1) 0%, rgba(#fcb69f,0.6) 100%);
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
color: #c43a30;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment