One solution to the Drag and Drop Succulent Garden - Project Outline posted for the Creative Coding Club.
A Pen by Nat Cooper on CodePen.
One solution to the Drag and Drop Succulent Garden - Project Outline posted for the Creative Coding Club.
A Pen by Nat Cooper on CodePen.
| <!-- WOW THIS IS SUPER BROKEN NOW - Nat, 2019 --> | |
| <main> | |
| <div class="tut-wrap"> | |
| <a class="tutorial" href="https://codepen.io/natacoops/post/drag-and-drop-succulent-garden-project-outline" target="_blank">Project Outline</a> | |
| <a class="tutorial" href="https://codepen.io/natacoops/post/a-drag-and-drop-succulent-garden-project-solution" target="_blank">Project Solution</a> | |
| </div> | |
| <section class="plant-drawer"> | |
| <div class="small"> | |
| <img class="succulent original" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-agave.svg" alt="agave succulent"> | |
| </div> | |
| <div class="small"> | |
| <img class="succulent original smaller" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-barrel-cactus.svg" alt="barrel cactus"> | |
| </div> | |
| <div> | |
| <img class="succulent original" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-purple-agave.svg" alt="purple agave succulent"> | |
| </div> | |
| <div> | |
| <img class="succulent original smaller" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-cacti.svg" alt="three cacti grouped together"> | |
| </div> | |
| <div class="tall"> | |
| <img class="succulent original" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-purslane.svg" alt="purslane succulent"> | |
| </div> | |
| <div class="tall"> | |
| <img class="succulent original" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-snakeplant.svg" alt="snake plant succulent with two flowers"> | |
| </div> | |
| <div> | |
| <img class="succulent original smaller" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-gnome.svg" alt="a little gnome"> | |
| </div> | |
| <div> | |
| <img class="succulent original smaller" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/succulent-gemstone.svg" alt="decorative purple crystal"> | |
| </div> | |
| <p>drag the plants into your terrarium</p> | |
| </section> | |
| <section class="terrarium-container"> | |
| <div class="terr-wrap start"> | |
| <img class="soil" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-bottle-soil.svg" alt="Bottle-shaped terrarium soil" /> | |
| <img class="frame" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-bottle-frame.svg" alt="Bottle-shaped terrarium outline" /> | |
| </div> | |
| <div class="terr-wrap start"> | |
| <img class="soil" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-house-soil.svg" alt="House-shaped terrarium soil" /> | |
| <img class="frame" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-house-frame.svg" alt="House-shaped terrarium outline" /> | |
| </div> | |
| <div class="terr-wrap start"> | |
| <img class="soil" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-dome-soil.svg" alt="Dome-shaped terrarium soil" /> | |
| <img class="frame" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-dome-frame.svg" alt="Dome-shaped terrarium outline" /> | |
| </div> | |
| <div class="terr-wrap start"> | |
| <img class="soil" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-bowl-soil.svg" alt="Bowl-shaped terrarium soil" /> | |
| <img class="frame" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-bowl-frame.svg" alt="Bowl-shaped terrarium outline" /> | |
| </div> | |
| <div class="terr-wrap start"> | |
| <img class="soil" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-geo-soil.svg" alt="Geometric terrarium soil" /> | |
| <img class="frame" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/terrarium-geo-frame.svg" alt="Geometric terrarium outline" /> | |
| </div> | |
| <p>choose your terrarium</p> | |
| <div class="context-menu"> | |
| <a id="forwards"><i class="fa fa-arrow-up"></i></a> | |
| <a id="backwards"><i class="fa fa-arrow-down"></i></a> | |
| <a id="grow"><i class="fa fa-plus"></i></a> | |
| <a id="shrink"><i class="fa fa-minus"></i></a> | |
| <a id="trash"><i class="fa fa-trash"></i></a> | |
| <div class="thumb"></div> | |
| </div> | |
| <div class="button-wrap"> | |
| <a class="button clear">clear</a> | |
| <a class="button new">new terrarium</a> | |
| </div> | |
| </section> | |
| </main> |
| $('.terr-wrap.start').on('click', function(){ | |
| $(this).removeClass('start').addClass('selected'); | |
| $('.terr-wrap.start').fadeOut(); | |
| $('.terrarium-container p').fadeOut(); | |
| $('.terrarium-container').addClass('shrink'); | |
| $('.plant-drawer').addClass('open'); | |
| $(this).droppable({ | |
| drop: function(e, ui) { | |
| if ($(ui.helper).clone().hasClass('original')) { | |
| $(this).append($(ui.helper).clone()); | |
| $(this).find('.succulent').removeClass('original'); | |
| $(this).find('.succulent').draggable(); | |
| } | |
| } | |
| }); | |
| }); | |
| $('.original').draggable({ | |
| appendTo: ".terr-wrap.selected", | |
| helper: 'clone' | |
| }); | |
| // context menu | |
| $('.terr-wrap').on('click', '.succulent', function(){ | |
| $('.terr-wrap .succulent').removeClass('edit'); | |
| $(this).addClass('edit'); | |
| var bg = $(this).attr('src'); | |
| $('.thumb').css({ | |
| "background": "url(" + bg + ") no-repeat", | |
| "background-size": "contain", | |
| "background-position": "50% 50%", | |
| }); | |
| }); | |
| // calculate correct scale value | |
| function getScale() { | |
| // get the transform matrix of the clicked succulent | |
| var div = $('.edit').css('transform'); | |
| // turn the matrix string into an array of values | |
| var values = div.split('(')[1]; | |
| values = values.split(')')[0]; | |
| values = values.split(','); | |
| // return the transform scale values we need from the matrix array | |
| var a = values[0]; | |
| var b = values[1]; | |
| // this is how to get the correct scale value out of the css matrix | |
| return Math.sqrt(a*a + b*b); | |
| } | |
| // context menu icons | |
| $('.fa-plus').on('click',function(){ | |
| $('.edit').css('transform', 'scale(' + ( getScale() + 0.05 ) + ')') ; | |
| }); | |
| $('.fa-minus').on('click',function(){ | |
| $('.edit').css('transform', 'scale(' + ( getScale() - 0.05 ) + ')') ; | |
| }); | |
| $('.fa-arrow-up').on('click',function(){ | |
| var level = $('.edit').css('z-index'); | |
| $('.edit').css('z-index', level + 1); | |
| }); | |
| $('.fa-arrow-down').on('click',function(){ | |
| var level = $('.edit').css('z-index'); | |
| $('.edit').css('z-index', level - 1); | |
| }); | |
| $('.fa-trash').on('click',function(){ | |
| $('.edit').remove(); | |
| }); | |
| // Buttons | |
| $('.clear').on('click',function(){ | |
| $('.terr-wrap.selected .succulent').remove(); | |
| }); | |
| $('.new').on('click', function(){ | |
| $('.terr-wrap.selected .succulent').remove(); | |
| $('.terr-wrap.selected').removeClass('selected').addClass('start'); | |
| $('.terr-wrap.start').fadeIn(); | |
| $('.terrarium-container p').fadeIn(); | |
| $('.terrarium-container').removeClass('shrink'); | |
| $('.plant-drawer').removeClass('open'); | |
| }); |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> | |
| <script src="https://codepen.io/steveg3003/pen/MmqOpb/"></script> |
| .tut-wrap { | |
| position: absolute; | |
| z-index: 999; | |
| } | |
| .tutorial { | |
| color: #fff; | |
| background: rgba(0,0,0,0.7); | |
| padding: 10px; | |
| margin: 10px 0 0 10px; | |
| text-decoration: none; | |
| font-size: 16px; | |
| border: 1px solid #fff; | |
| display: inline-block; | |
| } | |
| .tutorial:hover { | |
| background: rgba(0,0,0,0.96); | |
| } | |
| body { | |
| background: #333; | |
| font-size: 24px; | |
| letter-spacing: 0.5px; | |
| font-family: 'EB Garamond', serif; | |
| line-height: 1.4; | |
| padding: 10px; | |
| } | |
| main { | |
| display: flex; | |
| width: 920px; | |
| margin: 0 auto; | |
| } | |
| .plant-drawer { | |
| padding: 20px 0; | |
| width: 0%; | |
| background: #DCEDC8; | |
| margin-right: 0px; | |
| display: flex; | |
| flex-wrap: wrap; | |
| position: relative; | |
| left: -100%; | |
| transition: 2s all; | |
| } | |
| .plant-drawer.open { | |
| left: 0; | |
| width: 40%; | |
| margin-right: 10px; | |
| } | |
| .plant-drawer div { | |
| width: 50%; | |
| text-align: center; | |
| background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/160607/circle.svg) no-repeat; | |
| background-position: bottom; | |
| min-height: 120px; | |
| position: relative; | |
| } | |
| .plant-drawer div.tall { | |
| height: 230px; | |
| } | |
| .plant-drawer div.small .succulent { | |
| width: 50%; | |
| } | |
| .plant-drawer p { | |
| position: absolute; | |
| left: 105%; | |
| width: 200px; | |
| z-index: 10; | |
| } | |
| .succulent { | |
| position: absolute; | |
| bottom: 3px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| max-height: 80%; | |
| max-width: 90%; | |
| opacity: 0.7; | |
| z-index: 20; | |
| } | |
| .succulent:hover { | |
| cursor: grab; | |
| opacity: 1; | |
| } | |
| .terrarium-container { | |
| width: 100%; | |
| background: #fff; | |
| position: relative; | |
| min-height: 100vh; | |
| } | |
| .terrarium-container p { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| } | |
| .terrarium-container.shrink { | |
| width: 60%; | |
| } | |
| .terr-wrap { | |
| position: absolute; | |
| width: 30%; | |
| transition: 1s all; | |
| } | |
| .terr-wrap .soil, | |
| .terr-wrap .frame { | |
| width: 100%; | |
| opacity: 0.8; | |
| } | |
| .terr-wrap .succulent { | |
| opacity: 1; | |
| z-index: 20; | |
| transform: scale(0.8); | |
| } | |
| .terr-wrap .succulent.smaller { | |
| transform: scale(0.6); | |
| } | |
| .frame { | |
| position: absolute; | |
| top: 0; | |
| z-index: 300; | |
| pointer-events: none; | |
| } | |
| .terr-wrap:hover { | |
| width: 33%; | |
| cursor: pointer; | |
| } | |
| .terr-wrap:hover img { | |
| opacity: 1; | |
| } | |
| .terr-wrap:first-child { | |
| left: 50%; | |
| transform: translateX(-50%); | |
| } | |
| .terr-wrap:nth-child(2), | |
| .terr-wrap:nth-child(3) { | |
| top: 25%; | |
| } | |
| .terr-wrap:nth-child(3) { | |
| right: 0%; | |
| } | |
| .terr-wrap:nth-child(4), | |
| .terr-wrap:nth-child(5) { | |
| bottom: 0%; | |
| left: 15%; | |
| } | |
| .terr-wrap:nth-child(5) { | |
| left: initial; | |
| right: 15%; | |
| } | |
| .context-menu { | |
| position: absolute; | |
| top: 10px; | |
| right: 10px; | |
| display: none; | |
| } | |
| .thumb { | |
| width: 80px; | |
| height: 80px; | |
| position: absolute; | |
| right: 0; | |
| opacity:0.4; | |
| } | |
| .fa { | |
| font-size: 28px; | |
| margin: 0 5px; | |
| color: #ccc; | |
| position: relative; | |
| } | |
| .fa:after { | |
| font-size: 12px; | |
| position: absolute; | |
| bottom: -26px; | |
| left: 0px; | |
| opacity: 0; | |
| } | |
| .fa:hover { | |
| color: rgba(0,0,0,1); | |
| cursor: pointer; | |
| } | |
| .fa:hover:after { | |
| opacity: 1; | |
| } | |
| .fa-arrow-up:after { | |
| content: 'bring forward'; | |
| } | |
| .fa-arrow-down:after { | |
| content: 'send back'; | |
| } | |
| .fa-minus:after { | |
| content: 'shrink'; | |
| } | |
| .fa-plus:after { | |
| content: 'grow'; | |
| } | |
| .fa-trash:after { | |
| content: 'delete'; | |
| } | |
| .button-wrap { | |
| position:absolute; | |
| bottom: 20px; | |
| left: 10px; | |
| display:none; | |
| } | |
| .button { | |
| text-decoration: none; | |
| padding: 12px 22px; | |
| border: 1px solid #333; | |
| left: 10px; | |
| font-size: 13px; | |
| color: #333; | |
| } | |
| .button:hover { | |
| cursor: pointer; | |
| background: #333; | |
| color: #FFF; | |
| } | |
| .shrink .terr-wrap { | |
| width: 100%; | |
| bottom: initial; | |
| top: 50%; | |
| left: 50%; | |
| transform: translateX(-50%) translateY(-50%); | |
| } | |
| .shrink .terr-wrap .soil, | |
| .shrink .terr-wrap .frame { | |
| opacity: 1; | |
| } | |
| .shrink .button-wrap, | |
| .shrink .context-menu { | |
| display: block; | |
| } |