Last active
September 9, 2017 09:14
-
-
Save phonx/289f997e9c0249f13ef526a1469cfbd4 to your computer and use it in GitHub Desktop.
Morph Machine
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
<header> | |
<h1> | |
<span>Drag and Drop</span> | |
Shape Morpher | |
</h1> | |
<p>Works best with <code>viewBox="0 0 100 100"</code> SVGs with just one <code><path></code>. <a href="https://d.pr/f/C2BD/3qSgrJaN" target="_blank">Need some to play with</a>? Uses <a href="https://greensock.com/morphSVG" target="_blank">MorphSVG</a>.</p> | |
</header> | |
<div class="grid"> | |
<div>Morph this shape</div> | |
<div>into</div> | |
<div>this shape.</div> | |
</div> | |
<div class="grid"> | |
<div class="dropzone" id="dropzone-1"> | |
<svg id="shape-1" viewBox="0 0 100 100"> | |
<path id="shape-1-path" d="M99.36,40.93,87,31.53A15,15,0,0,0,85.26,27a23.47,23.47,0,0,0-41,0l-2,3.61A22,22,0,0,1,22.74,42,22,22,0,0,1,3.19,30.61a1.75,1.75,0,0,0-1.93-.84A1.62,1.62,0,0,0,0,31.36,43.94,43.94,0,0,0,13.18,62.75,44.59,44.59,0,0,0,42.72,75.67l4.53,11.58a1.72,1.72,0,0,0,1.59,1.09,1.43,1.43,0,0,0,.59-.08,1.7,1.7,0,0,0,.92-2.18l-4-10.32a40.08,40.08,0,0,0,6.38-.67l4.78,12.17a1.72,1.72,0,0,0,1.59,1.09,1.43,1.43,0,0,0,.59-.08,1.7,1.7,0,0,0,.92-2.18L56.06,74.5a39.83,39.83,0,0,0,5.37-1.68A46.73,46.73,0,0,0,75.7,64.18a35,35,0,0,0,8.64-11.75,23,23,0,0,0,1.26-3.36L98.86,44a1.77,1.77,0,0,0,1.09-1.34A1.6,1.6,0,0,0,99.36,40.93ZM17.46,55.87a1.66,1.66,0,1,1,2.35-2.35,28.46,28.46,0,0,0,20.06,8.22,29.33,29.33,0,0,0,10.41-1.93,28,28,0,0,0,9-5.45,1.7,1.7,0,0,1,2.35.08,1.63,1.63,0,0,1-.17,2.35A32.25,32.25,0,0,1,39.78,65,31.64,31.64,0,0,1,17.46,55.87Zm52-18a3.69,3.69,0,1,1,0-7.38,3.69,3.69,0,1,1,0,7.38Z"></path> | |
</svg> | |
</div> | |
<div class="morph-area"> | |
<svg viewBox="0 0 100 100"> | |
<path id="morph-path" d="M99.36,40.93,87,31.53A15,15,0,0,0,85.26,27a23.47,23.47,0,0,0-41,0l-2,3.61A22,22,0,0,1,22.74,42,22,22,0,0,1,3.19,30.61a1.75,1.75,0,0,0-1.93-.84A1.62,1.62,0,0,0,0,31.36,43.94,43.94,0,0,0,13.18,62.75,44.59,44.59,0,0,0,42.72,75.67l4.53,11.58a1.72,1.72,0,0,0,1.59,1.09,1.43,1.43,0,0,0,.59-.08,1.7,1.7,0,0,0,.92-2.18l-4-10.32a40.08,40.08,0,0,0,6.38-.67l4.78,12.17a1.72,1.72,0,0,0,1.59,1.09,1.43,1.43,0,0,0,.59-.08,1.7,1.7,0,0,0,.92-2.18L56.06,74.5a39.83,39.83,0,0,0,5.37-1.68A46.73,46.73,0,0,0,75.7,64.18a35,35,0,0,0,8.64-11.75,23,23,0,0,0,1.26-3.36L98.86,44a1.77,1.77,0,0,0,1.09-1.34A1.6,1.6,0,0,0,99.36,40.93ZM17.46,55.87a1.66,1.66,0,1,1,2.35-2.35,28.46,28.46,0,0,0,20.06,8.22,29.33,29.33,0,0,0,10.41-1.93,28,28,0,0,0,9-5.45,1.7,1.7,0,0,1,2.35.08,1.63,1.63,0,0,1-.17,2.35A32.25,32.25,0,0,1,39.78,65,31.64,31.64,0,0,1,17.46,55.87Zm52-18a3.69,3.69,0,1,1,0-7.38,3.69,3.69,0,1,1,0,7.38Z"></path> | |
</svg> | |
</div> | |
<div class="dropzone" id="dropzone-2"> | |
<svg id="shape-2" viewBox="0 0 100 100"> | |
<path id="shape-2-path" d="M76,73.55C93.14,56.41,97.16,0,97.16,0S85.51,6.07,66.91,7.67c-17.54,1.51-33.79,4-43.31,13.5-14.69,14.7-18.37,35.61-10,50.39C22.8,57.12,60.65,36.51,60.65,36.51,33.48,55.94,19.64,71,1,97.55L10.14,100s6.8-12.29,12.72-18.22C37.7,92.31,60.35,89.19,76,73.55Z"></path> | |
</svg> | |
</div> | |
</div> | |
<div class="center"> | |
<button id="run-again">Run Again</button> | |
</div> | |
<div class="elapsed-grid"> | |
<!-- div*10>svg[viewBox="0 0 100 100"]>path[d=""] --> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
<div> | |
<svg viewBox="0 0 100 100"> | |
<path d=""></path> | |
</svg> | |
</div> | |
</div> | |
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
/* events fired on the drop targets */ | |
document.addEventListener("dragover", function(event) { | |
// prevent default to allow drop | |
event.preventDefault(); | |
}, false); | |
document.addEventListener("dragenter", function(event) { | |
// highlight potential drop target when the draggable element enters it | |
if (event.target.className == "dropzone") { | |
event.target.style.background = "purple"; | |
} | |
}, false); | |
document.addEventListener("dragleave", function(event) { | |
// reset background of potential drop target when the draggable element leaves it | |
if (event.target.className == "dropzone") { | |
event.target.style.background = ""; | |
} | |
}, false); | |
document.addEventListener("drop", function(event) { | |
event.preventDefault(); | |
event.target.style.background = ""; | |
var files = event.target.files || event.dataTransfer.files; | |
if (files) { | |
if (files[0].type === "image/svg+xml") { | |
var reader = new FileReader(); | |
reader.onload = function(e) { | |
var doc = new DOMParser().parseFromString(e.target.result, "text/html"); | |
var svg = doc.body.firstChild; | |
var path = svg.querySelector("path"); | |
var pathData = path.getAttribute("d"); | |
var allElapsedPaths = document.querySelectorAll(".elapsed-grid path"); | |
var shape; | |
if (event.target.id == "dropzone-1") { | |
shape = document.getElementById("shape-1-path"); | |
var morphPath = document.getElementById("morph-path"); | |
morphPath.setAttribute("d", pathData); | |
[].forEach.call(allElapsedPaths, function(path) { | |
path.setAttribute("d", pathData); | |
}); | |
} else { | |
shape = document.getElementById("shape-2-path"); | |
} | |
shape.setAttribute("d", pathData); | |
playMorph(); | |
} | |
reader.readAsText(files[0]); | |
} | |
} | |
}, false); | |
function playMorph() { | |
var morph = new TimelineMax({ paused: true }); | |
morph | |
.to('#morph-path', 0, { | |
morphSVG: { shape: '#shape-1-path' } | |
}) | |
.to('#morph-path', 1, { | |
morphSVG: { shape: '#shape-2-path' }, | |
ease: Elastic.easeInOut | |
}); | |
morph.play(0); | |
var allElapsedPaths = document.querySelectorAll(".elapsed-grid path"); | |
var i = 1; | |
[].forEach.call(allElapsedPaths, function(path) { | |
var pathFreeze = new TimelineMax({ paused: true }); | |
var delay = i / 25; | |
console.log(delay); | |
pathFreeze | |
.to(path, 0, { | |
morphSVG: { shape: '#shape-1-path' } | |
}) | |
.to(path, 1, { | |
morphSVG: { shape: '#shape-2-path' }, | |
ease: Linear.easeNone | |
}) | |
.seek(delay); | |
i++; | |
}); | |
} | |
var runAgainButton = document.querySelector("#run-again"); | |
runAgainButton.addEventListener("click", function() { | |
playMorph(); | |
}); |
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://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"></script> | |
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.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; | |
} | |
html { | |
font-family: 'Nunito', sans-serif; | |
} | |
body { | |
margin: 0; | |
} | |
header { | |
text-align: center; | |
background: yellow; | |
padding: 2rem; | |
margin: 0 0 2rem 0; | |
} | |
h1 { | |
font-family: 'Rubik Mono One', sans-serif; | |
font-size: 3rem; | |
margin: 0; | |
span { | |
display: block; | |
color: coral; | |
font-size: 50%; | |
} | |
} | |
.grid { | |
width: 640px; | |
margin: 0 auto; | |
display: flex; | |
flex-wrap: wrap; | |
justify-content: space-between; | |
text-align: center; | |
> * { | |
width: 200px; | |
} | |
} | |
p { | |
margin: 0; | |
} | |
.dropzone { | |
height: 200px; | |
border: 2px black dashed; | |
padding: 10px; | |
background: lightblue; | |
} | |
.dropzone > svg { | |
width: 180px; | |
height: 180px; | |
pointer-events: none; | |
} | |
.morph-area { | |
height: 200px; | |
padding: 10px; | |
} | |
.morph-area > svg { | |
width: 180px; | |
height: 180px; | |
} | |
.center { | |
flex-basis: 100%; | |
text-align: center; | |
} | |
.elapsed-grid { | |
width: 640px; | |
margin: 50px auto; | |
display: flex; | |
flex-wrap: wrap; | |
justify-content: space-between; | |
> * { | |
flex: 0 0 120px; | |
height: 120px; | |
margin-bottom: 2%; | |
background: white; | |
padding: 10px; | |
} | |
svg { | |
width: 100px; | |
height: 100px; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment