A Pen by Stan Williams on CodePen.
Created
November 20, 2020 05:32
-
-
Save stanwmusic/e2f64cbc7fa9a8eb23c97eafaf03bda8 to your computer and use it in GitHub Desktop.
Tuggable Light Bulb! 💡(GSAP Draggable && MorphSVG)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
svg(class="toggle-scene" xmlns='http://www.w3.org/2000/svg' preserveaspectratio='xMinYMin' viewBox='0 0 197.451 481.081') | |
defs | |
marker#e(orient='auto' overflow='visible' refx='0' refy='0') | |
path.toggle-scene__cord-end(fill-rule='evenodd' stroke-width='.2666' d='M.98 0a1 1 0 11-2 0 1 1 0 012 0z') | |
marker#d(orient='auto' overflow='visible' refx='0' refy='0') | |
path.toggle-scene__cord-end(fill-rule='evenodd' stroke-width='.2666' d='M.98 0a1 1 0 11-2 0 1 1 0 012 0z') | |
marker#c(orient='auto' overflow='visible' refx='0' refy='0') | |
path.toggle-scene__cord-end(fill-rule='evenodd' stroke-width='.2666' d='M.98 0a1 1 0 11-2 0 1 1 0 012 0z') | |
marker#b(orient='auto' overflow='visible' refx='0' refy='0') | |
path.toggle-scene__cord-end(fill-rule='evenodd' stroke-width='.2666' d='M.98 0a1 1 0 11-2 0 1 1 0 012 0z') | |
marker#a(orient='auto' overflow='visible' refx='0' refy='0') | |
path.toggle-scene__cord-end(fill-rule='evenodd' stroke-width='.2666' d='M.98 0a1 1 0 11-2 0 1 1 0 012 0z') | |
clippath#g(clippathunits='userSpaceOnUse') | |
path(stroke-linecap='round' stroke-linejoin='round' stroke-width='4.677' d='M-774.546 827.629s12.917-13.473 29.203-13.412c16.53.062 29.203 13.412 29.203 13.412v53.6s-8.825 16-29.203 16c-21.674 0-29.203-16-29.203-16z') | |
clippath#f(clippathunits='userSpaceOnUse') | |
path(d='M-868.418 945.051c-4.188 73.011 78.255 53.244 150.216 52.941 82.387-.346 98.921-19.444 98.921-47.058 0-27.615-4.788-42.55-73.823-42.55-69.036 0-171.436-30.937-175.314 36.667z') | |
g.toggle-scene__cords | |
path.toggle-scene__cord(marker-end="url(#a)" fill='none' stroke-linecap='square' stroke-width='6' d='M123.228-28.56v150.493' transform='translate(-24.503 256.106)') | |
path.toggle-scene__cord(marker-end="url(#a)" fill='none' stroke-linecap='square' stroke-width='6' d='M123.228-28.59s28 8.131 28 19.506-18.667 13.005-28 19.507c-9.333 6.502-28 8.131-28 19.506s28 19.507 28 19.507' transform='translate(-24.503 256.106)') | |
path.toggle-scene__cord(marker-end="url(#a)" fill='none' stroke-linecap='square' stroke-width='6' d='M123.228-28.575s-20 16.871-20 28.468c0 11.597 13.333 18.978 20 28.468 6.667 9.489 20 16.87 20 28.467 0 11.597-20 28.468-20 28.468' transform='translate(-24.503 256.106)') | |
path.toggle-scene__cord(marker-end="url(#a)" fill='none' stroke-linecap='square' stroke-width='6' d='M123.228-28.569s16 20.623 16 32.782c0 12.16-10.667 21.855-16 32.782-5.333 10.928-16 20.623-16 32.782 0 12.16 16 32.782 16 32.782' transform='translate(-24.503 256.106)') | |
path.toggle-scene__cord(marker-end="url(#a)" fill='none' stroke-linecap='square' stroke-width='6' d='M123.228-28.563s-10 24.647-10 37.623c0 12.977 6.667 25.082 10 37.623 3.333 12.541 10 24.647 10 37.623 0 12.977-10 37.623-10 37.623' transform='translate(-24.503 256.106)') | |
g.line.toggle-scene__dummy-cord | |
line(marker-end="url(#a)" x1="98.7255" x2="98.7255" y1="240.5405" y2="380.5405") | |
circle.toggle-scene__hit-spot(cx="98.7255" cy="380.5405" r="60" fill="transparent") | |
g.toggle-scene__bulb.bulb(transform='translate(844.069 -645.213)') | |
path.bulb__cap(stroke-linecap='round' stroke-linejoin='round' stroke-width='4.677' d='M-774.546 827.629s12.917-13.473 29.203-13.412c16.53.062 29.203 13.412 29.203 13.412v53.6s-8.825 16-29.203 16c-21.674 0-29.203-16-29.203-16z') | |
path.bulb__cap-shine(d='M-778.379 802.873h25.512v118.409h-25.512z' clip-path='url(#g)' transform='matrix(.52452 0 0 .90177 -368.282 82.976)') | |
path.bulb__cap(stroke-linecap='round' stroke-linejoin='round' stroke-width='4' d='M-774.546 827.629s12.917-13.473 29.203-13.412c16.53.062 29.203 13.412 29.203 13.412v0s-8.439 10.115-28.817 10.115c-21.673 0-29.59-10.115-29.59-10.115z') | |
path.bulb__cap-outline(fill='none' stroke-linecap='round' stroke-linejoin='round' stroke-width='4.677' d='M-774.546 827.629s12.917-13.473 29.203-13.412c16.53.062 29.203 13.412 29.203 13.412v53.6s-8.825 16-29.203 16c-21.674 0-29.203-16-29.203-16z') | |
g.bulb__filament(fill='none' stroke-linecap='round' stroke-width='5') | |
path(d='M-752.914 823.875l-8.858-33.06') | |
path(d='M-737.772 823.875l8.858-33.06') | |
path.bulb__bulb(stroke-linecap='round' stroke-width='5' d='M-783.192 803.855c5.251 8.815 5.295 21.32 13.272 27.774 12.299 8.045 36.46 8.115 49.127 0 7.976-6.454 8.022-18.96 13.273-27.774 3.992-6.7 14.408-19.811 14.408-19.811 8.276-11.539 12.769-24.594 12.769-38.699 0-35.898-29.102-65-65-65-35.899 0-65 29.102-65 65 0 13.667 4.217 26.348 12.405 38.2 0 0 10.754 13.61 14.746 20.31z') | |
circle.bulb__flash(cx='-745.343' cy='743.939' r='83.725' fill='none' stroke-dasharray='10,30' stroke-linecap='round' stroke-linejoin='round' stroke-width='10') | |
path.bulb__shine(fill='none' stroke-linecap='round' stroke-linejoin='round' stroke-width='12' d='M-789.19 757.501a45.897 45.897 0 013.915-36.189 45.897 45.897 0 0129.031-21.957') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { | |
gsap: { registerPlugin, set, to, timeline }, | |
MorphSVGPlugin, | |
Draggable, | |
} = window | |
registerPlugin(MorphSVGPlugin) | |
// Used to calculate distance of "tug" | |
let startX | |
let startY | |
const AUDIO = { | |
CLICK: new Audio('https://assets.codepen.io/605876/click.mp3'), | |
} | |
const STATE = { | |
ON: false, | |
} | |
const CORD_DURATION = 0.1 | |
const CORDS = document.querySelectorAll('.toggle-scene__cord') | |
const HIT = document.querySelector('.toggle-scene__hit-spot') | |
const DUMMY = document.querySelector('.toggle-scene__dummy-cord') | |
const DUMMY_CORD = document.querySelector('.toggle-scene__dummy-cord line') | |
const PROXY = document.createElement('div') | |
// set init position | |
const ENDX = DUMMY_CORD.getAttribute('x2') | |
const ENDY = DUMMY_CORD.getAttribute('y2') | |
const RESET = () => { | |
set(PROXY, { | |
x: ENDX, | |
y: ENDY, | |
}) | |
} | |
RESET() | |
const CORD_TL = timeline({ | |
paused: true, | |
onStart: () => { | |
STATE.ON = !STATE.ON | |
set(document.documentElement, { '--on': STATE.ON ? 1 : 0 }) | |
set(DUMMY, { display: 'none' }) | |
set(CORDS[0], { display: 'block' }) | |
AUDIO.CLICK.play() | |
}, | |
onComplete: () => { | |
set(DUMMY, { display: 'block' }) | |
set(CORDS[0], { display: 'none' }) | |
RESET() | |
}, | |
}) | |
for (let i = 1; i < CORDS.length; i++) { | |
CORD_TL.add( | |
to(CORDS[0], { | |
morphSVG: CORDS[i], | |
duration: CORD_DURATION, | |
repeat: 1, | |
yoyo: true, | |
}) | |
) | |
} | |
Draggable.create(PROXY, { | |
trigger: HIT, | |
type: 'x,y', | |
onPress: e => { | |
startX = e.x | |
startY = e.y | |
}, | |
onDrag: function() { | |
set(DUMMY_CORD, { | |
attr: { | |
x2: this.x, | |
y2: this.y, | |
}, | |
}) | |
}, | |
onRelease: function(e) { | |
const DISTX = Math.abs(e.x - startX) | |
const DISTY = Math.abs(e.y - startY) | |
const TRAVELLED = Math.sqrt(DISTX * DISTX + DISTY * DISTY) | |
to(DUMMY_CORD, { | |
attr: { x2: ENDX, y2: ENDY }, | |
duration: CORD_DURATION, | |
onComplete: () => { | |
if (TRAVELLED > 50) { | |
CORD_TL.restart() | |
} else { | |
RESET() | |
} | |
}, | |
}) | |
}, | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script> | |
<script src="https://assets.codepen.io/16327/MorphSVGPlugin3.min.js"></script> | |
<script src="https://unpkg.com/gsap@3/dist/Draggable.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* | |
box-sizing border-box | |
:root | |
--on 0 | |
--bg 'hsl(%s, %s, %s)' % (calc(200 - (var(--on) * 160)) calc((20 + (var(--on) * 50)) * 1%) calc((20 + (var(--on) * 60)) * 1%)) | |
--cord 'hsl(0, 0%, %s)' % (calc((60 - (var(--on) * 50)) * 1%)) | |
--stroke 'hsl(0, 0%, %s)' % (calc((60 - (var(--on) * 50)) * 1%)) | |
--shine 'hsla(0, 0%, 100%, %s)' % calc(0.75 - (var(--on) * 0.5)) | |
--cap 'hsl(0, 0%, %s)' % calc((40 + (var(--on) * 30)) * 1%) | |
--filament 'hsl(45, %s, %s)' % (calc(var(--on) * 80%) calc((25 + (var(--on) * 75)) * 1%)) | |
body | |
min-height 100vh | |
display flex | |
align-items center | |
justify-content center | |
background var(--bg) | |
.toggle-scene | |
// !important for CodePen | |
overflow visible !important | |
height 50vmin | |
position absolute | |
&__cord | |
stroke var(--cord) | |
cursor move | |
// Hide all cords if there's no JavaScript? | |
&:nth-of-type(1) | |
display none | |
// Hide cords by default | |
&:nth-of-type(2) | |
&:nth-of-type(3) | |
&:nth-of-type(4) | |
&:nth-of-type(5) | |
display none | |
&-end | |
stroke var(--cord) | |
fill var(--cord) | |
.toggle-scene__dummy-cord | |
stroke-width 6 | |
stroke var(--cord) | |
.bulb | |
&__filament | |
stroke var(--filament) | |
&__shine | |
stroke var(--shine) | |
&__flash | |
stroke hsl(45, 80%, 80%) | |
display none | |
&__bulb | |
stroke var(--stroke) | |
fill 'hsla(%s, 80%, 80%, %s)' % (calc(180 - (95 * var(--on))) calc(0.1 + (0.4 * var(--on)))) | |
&__cap | |
fill var(--cap) | |
&-shine | |
fill var(--shine) | |
&-outline | |
stroke var(--stroke) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo or Fork: https://codepen.io/Stanssongs/pen/LYZoMoJ