Modules
Below are some interactive modules/plugins that are dependency free. For your own projects, download an MIT licensed copy at Github.
- CodePen Embed - ArtboardJS Demo
<div class="artboard__canvas">
<div class="artboard-modal">
<summary class="artboard-modal__summary"></summary>
<footer class="artboard-modal__footer">
<button class="artboard-modal__footer__no">No</button>
<button class="artboard-modal__footer__yes">Yes</button>
<button class="artboard-modal__footer__ok">OK</button>
</footer>
</div>
<div class="artboard__canvas__tools">
<var class="artboard__canvas__tools__size"></var>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__clear icon-bin" title="Clear"></button>
</div>
<!-- <div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__reset icon-spinner11">Reset</button>
</div> -->
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__undo icon-undo" title="Undo"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__redo icon-redo" title="Redo"></button>
</div>
<div class="artboard__canvas__tools__section">
<input type="checkbox" class="artboard__canvas__tools__section__single-touch" title="Toggle single & multi-touch">
<label class="artboard__canvas__tools__section__label icon-point-up" title="Toggle single & multi-touch"></label>
</div>
<div class="artboard__canvas__tools__section">
<input type="checkbox" checked="true" class="artboard__canvas__tools__section__rainbow" title="Rainbow color">
<label class="artboard__canvas__tools__section__label icon-paint-format" title="Rainbow color"></label>
</div>
<div class="artboard__canvas__tools__section">
<label class="artboard__canvas__tools__section__label" style="opacity:0.1;"></label>
<input type="color" value="#FFFFFF" disabled="true" class="artboard__canvas__tools__section__color" style="opacity:0.1;" title="Color picker (Deselect rainbow paint roller to use)">
</div>
<div class="artboard__canvas__tools__section">
<label class="artboard__canvas__tools__section__label icon-enlarge" title="Resize brush"></label>
<input type="range" value="10" min="1" max="100" class="artboard__canvas__tools__section__radius">
</div>
<div class="artboard__canvas__tools__section">
<label class="artboard__canvas__tools__section__label icon-sun" title="Glow"></label>
<input type="range" value="10" min="0.5" max="100" class="artboard__canvas__tools__section__shadow">
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__stop icon-stop" title="Stop playback"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__play icon-play2" title="Play"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__save icon-floppy-disk" title="Save"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__restore icon-folder-upload" title="Restore"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__download-image icon-image" title="Save artboard as image"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__advanced-options">Advanced</button>
</div>
<hr class="artboard__canvas__tools__hr" style="width:100%;">
<div class="artboard__canvas__tools--advanced">
<div class="artboard__canvas__tools__section" style="border:1px solid #fff;padding:5px;">
<input type="text" placeholder="Name this image download" class="artboard__canvas__tools__section__download-image-as-input">
<button class="artboard__canvas__tools__section__download-image-as icon-image" title="Save artboard as image with the specified name"></button>
</div>
<div class="artboard__canvas__tools__section" style="border:1px solid #fff;padding:5px;">
<input type="text" placeholder="Name & save this artboard" class="artboard__canvas__tools__section__save-as-input">
<button class="artboard__canvas__tools__section__save-as icon-floppy-disk" title="Save named artboard"></button>
</div>
<div class="artboard__canvas__tools__section" style="border:1px solid #fff;padding:5px;">
<input type="text" placeholder="Restore a named artboard" class="artboard__canvas__tools__section__restore--named-input">
<button class="artboard__canvas__tools__section__restore--named icon-folder-upload" title="Restore named artboard"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__saved icon-file-text" title="Show saved artboard names"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__delete-saved icon-bin" title="Delete saved artboards"></button>
</div>
<div class="artboard__canvas__tools__section">
<button class="artboard__canvas__tools__section__backup icon-database" title="Backup (for developers; see console)"></button>
</div>
</div>
</div>
<div class="artboard__canvas__canvas-wrap">
<canvas class="artboard__canvas__canvas"></canvas>
</div>
</div>
<div style="position:absolute;z-index:9999;top:0;right:0;display:block;width:100px;height:100px;border-radius:50% 0 50% 50%;padding:2px;color:#fff;box-shadow:inset 0 0 15px 0 #000;background:#333;font-family:'Georgia',sans-serif;font-size:14px;text-align:center;"><p style="margin-top:10px;"><span style="display:block;">On</span><a href="https://github.com/depthdev" target="_blank" style="display:block;color:#08f;">Github</a><span style="display:block;">and</span><a href="http://depthdev.com/" target="_blank" style="color:#08f;">Depth</a></p></div>
<script>
// Download plugin here: https://github.com/depthdev/artboardjs
/*!
ArtboardJS v1.2.0
(c) 2017 Depth Development. http://depthdev.com
License: MIT
!*/
!function(e,t){"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};e.Artboard=function(){function i(e){e.preventDefault(),e.stopPropagation(),S=0,P=0;for(var t=m;t;)S+=t.offsetTop,P+=t.offsetLeft,t=t.offsetParent}function n(e){b=[],C=[];for(var t=0,i=e.length;t<i;t++)b.push(e[t].pageX-P),C.push(e[t].pageY-S)}function o(e){e.preventDefault(),e.stopPropagation(),O.isPlaying||(i(e),n(e.touches),O.createEntry(),A(),O.rewrite())}function l(e){e.preventDefault(),e.stopPropagation(),O.isPlaying||(n(e.touches),A())}function r(e){e.preventDefault(),e.stopPropagation(),O.isPlaying||(D=!0,i(e),b=[e.pageX-P],C=[e.pageY-S],O.createEntry(),A(),O.rewrite())}function a(e){e.preventDefault(),e.stopPropagation(),!O.isPlaying&&D&&(b=[e.pageX-P],C=[e.pageY-S],A())}function u(e){D&&(D=!1,e.preventDefault(),e.stopPropagation())}function h(e){if(O.isPlaying)return!1;var i=e||{};return m.width=i.width||t.documentElement.clientWidth,m.height=i.height||m.width*(9/16),_.clearRect(0,0,m.width,m.height),p=i.multiTouch!==!1,v=i.rainbow!==!1,_.fillStyle=i.color||"#000000",_.shadowColor=_.fillStyle,_.shadowBlur=i.glow>=0?i.glow:10,T=0,E=i.radius>=0?i.radius:10,B=i.done||function(){},O.timeline=[],!0}function s(e){if(O.isPlaying)return!1;var t={multiTouch:p,rainbow:v,color:_.fillStyle,glow:_.shadowBlur,degree:T,radius:E,done:B},i=e||{};return m.width=i.width||m.width,m.height=i.height||m.height,_.clearRect(0,0,m.width,m.height),O.timeline=[],p=t.multiTouch,v=t.rainbow,_.fillStyle=t.color,_.shadowColor=_.fillStyle,_.shadowBlur=t.glow,T=t.degree,E=t.radius,B=t.done,!0}function d(){return!O.isPlaying&&(_.clearRect(0,0,m.width,m.height),O.timeline=[],!0)}function g(e){if(O.isPlaying)return!1;var t=e||{};return p=void 0!==t.multiTouch?t.multiTouch:p,v=void 0!==t.rainbow?t.rainbow:v,_.fillStyle=t.color||_.fillStyle,_.shadowColor=_.fillStyle,_.shadowBlur=t.glow>=0?t.glow:_.shadowBlur,E=t.radius>=0?t.radius:E,B=t.done||B,!0}function c(e){this.a=t.createElement("a"),this.a.href=m.toDataURL("image/png"),this.a.download=e&&"string"==typeof e?e:"ArtboardJS",this.a.click(),delete this.a}function f(){O.timeline=[],m.removeEventListener("touchstart",o),m.removeEventListener("touchmove",l),m.removeEventListener("mousedown",r),m.removeEventListener("mousemove",a),t.removeEventListener("mouseup",u)}var m=arguments[0],w="object"===_typeof(arguments[1])&&arguments[1];if(!m.getContext){var y=arguments[arguments.length-1];return"function"==typeof y&&y(),!1}var p=!0,v=!0,S=0,P=0,b=[],C=[],E=10,L=2*Math.PI,T=0,B=null,_=m.getContext("2d");_.fillStyle="#000000",_.shadowColor="#000000",_.shadowOffsetX=0,_.shadowOffsetY=0,_.shadowBlur=10;var A=null,D=!1,O={timeline:[],createEntry:function(){O.timeline.push([])},stopPlaying:!1,isPlaying:!1,play:function(){function t(){return p=O.timeline[i][n].multiTouch,v=O.timeline[i][n].rainbow,_.fillStyle=O.timeline[i][n].color,b=O.timeline[i][n].x,C=O.timeline[i][n].y,E=O.timeline[i][n].radius,T=O.timeline[i][n].degree,_.shadowBlur=O.timeline[i][n].glow,_.shadowColor=_.fillStyle,A(!0),n++,O.stopPlaying?void(O.stopPlaying=!1):void(n===l?i+1!==o?(i++,n=0,l=O.timeline[i].length,e.requestAnimationFrame(t)):(O.stopPlaying=!1,O.isPlaying=!1,B()):e.requestAnimationFrame(t))}var i=0,n=0,o=O.timeline.length,l=O.timeline[i].length;return!(O.isPlaying||!O.timeline.length||(O.isPlaying=!0,_.clearRect(0,0,m.width,m.height),t(),0))},stop:function(){O.stopPlaying=!0,e.setTimeout(function(){O.isPlaying=!1,O.stopPlaying=!1,O.change()},100)},undoCount:0,save:function(){return!(O.isPlaying||!O.timeline.length||(e.localStorage.artboard=JSON.stringify({width:m.width,height:m.height,timeline:O.timeline}),0))},saveAs:function(t,i){return!O.isPlaying&&O.timeline.length&&/^[a-zA-Z0-9_$]+$/.test(t)?(e.localStorage["artboard_"+t]=JSON.stringify({width:m.width,height:m.height,timeline:O.timeline}),!i||i(!0)):!!i&&i(!1)},saved:function(){var t=[];for(var i in e.localStorage)/^artboard_/.test(i)&&t.push(i.replace(/^artboard_/,""));return t},backup:function(){return!(O.isPlaying||!O.timeline.length)&&{width:m.width,height:m.height,timeline:O.timeline}},restore:function(t,i){if(O.isPlaying)return!1;if(!t||t instanceof Event){if(e.localStorage.artboard){var n=JSON.parse(e.localStorage.artboard);return m.width=n.width,m.height=n.height,O.timeline=n.timeline,O.undoCount=0,O.change(),!i||i(!0)}return!!i&&i(!1)}if("string"==typeof t){if(e.localStorage["artboard_"+t]){var o=JSON.parse(e.localStorage["artboard_"+t]);return m.width=o.width,m.height=o.height,O.timeline=o.timeline,O.undoCount=0,O.change(),!i||i(!0)}return!!i&&i(!1)}try{return m.width=t.width,m.height=t.height,O.timeline=t.timeline,O.undoCount=0,O.change(),!i||i(!0)}catch(l){return!!i&&i(!1)}},deleteSaved:function(){delete e.localStorage.artboard;for(var t in e.localStorage)/^artboard_/.test(t)&&delete e.localStorage[t]},rewrite:function(){O.undoCount&&(O.timeline.splice(O.timeline.length-1-O.undoCount,O.undoCount),O.undoCount=0)},log:function(){O.timeline[O.timeline.length-1].push({multiTouch:p,rainbow:v,color:_.fillStyle,x:b,y:C,radius:E,degree:T,glow:_.shadowBlur})},settings:function(){return{multiTouch:p,rainbow:v,color:_.fillStyle,radius:E,degree:T,glow:_.shadowBlur}},change:function(){_.clearRect(0,0,m.width,m.height);for(var e=0,t=0,i=O.timeline.length-O.undoCount,n=O.timeline[e].length;e<i;e++)for(t=0,n=O.timeline[e].length;t<n;t++)p=O.timeline[e][t].multiTouch,v=O.timeline[e][t].rainbow,_.fillStyle=O.timeline[e][t].color,b=O.timeline[e][t].x,C=O.timeline[e][t].y,E=O.timeline[e][t].radius,T=O.timeline[e][t].degree,_.shadowBlur=O.timeline[e][t].glow,_.shadowColor=_.fillStyle,A(!0);B()},undo:function(){return!O.isPlaying&&O.undoCount!==O.timeline.length&&(O.undoCount++,O.change(),!0)},redo:function(){return!O.isPlaying&&O.undoCount>0&&(O.undoCount--,O.change(),!0)},size:function(){return JSON.stringify({width:m.width,height:m.height,timeline:O.timeline}).length}};return A=function(e){v&&(_.fillStyle="hsl("+T+",100%,50%)",_.shadowColor="hsl("+T+",100%,50%)",T++);for(var t=0,i=b.length;t<i&&(_.beginPath(),_.arc(b[t],C[t],E,0,L,!1),_.fill(),p);t++);e||O.log()},m.addEventListener("touchstart",o),m.addEventListener("touchmove",l),m.addEventListener("mousedown",r),m.addEventListener("mousemove",a),t.addEventListener("mouseup",u),h(w),{adjust:g,backup:O.backup,clear:d,deleteSaved:O.deleteSaved,destroy:f,hardReset:h,image:c,play:O.play,redo:O.redo,reset:s,restore:O.restore,save:O.save,saveAs:O.saveAs,saved:O.saved,settings:O.settings,size:O.size,stop:O.stop,undo:O.undo}}}(window,document);
</script>
:root{font:400 18px/1.4 sans-serif}
*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;font-family:inherit;font-size:inherit;font-weight:normal;user-select:none;}
@font-face {
font-family: 'icomoon';
src: url(data:application/font-woff;base64,d09GRgABAAAAAA8MAAsAAAAADsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDxIHIWNtYXAAAAFoAAAArAAAAKx6XHp2Z2FzcAAAAhQAAAAIAAAACAAAABBnbHlmAAACHAAAClgAAApYsgzM9GhlYWQAAAx0AAAANgAAADYMqFB5aGhlYQAADKwAAAAkAAAAJAfCA9RobXR4AAAM0AAAAEwAAABMQgAAoGxvY2EAAA0cAAAAKAAAACgQ3BO4bWF4cAAADUQAAAAgAAAAIAAeAJVuYW1lAAANZAAAAYYAAAGGmUoJ+3Bvc3QAAA7sAAAAIAAAACAAAwAAAAMD4AGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA6hcDwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEAJAAAAAgACAABAAAAAEAIOkN6SLpNOli6Wbpe+mJ6azp1OoD6hXqF//9//8AAAAAACDpDOki6TTpYulk6Xvpiems6dTqA+oV6hf//f//AAH/4xb4FuQW0xamFqUWkRaEFmIWOxYNFfwV+wADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAAP/ABAADgAApAC0AAAERIzU0JiMhIgYdARQWMyEyNj0BMxEhFSMiBhURFBY7ATI2NRE0JisBNQEhNSEEAMAmGv1AGiYmGgLAGiaA/cAgDRMTDYANExMNIAFA/UACwAGAAYBAGiYmGsAaJiYaQP8AgBMN/sANExMNAUANE0ABgEAAAAQAAAAABAADgAAQACEALQA0AAABOAExETgBMSE4ATEROAExITUhIgYVERQWMyEyNjURNCYjBxQGIyImNTQ2MzIWEyE1EwEzNwPA/IADgPyAGiYmGgOAGiYmGoA4KCg4OCgoOED9AOABAEDgA0D9AAMAQCYa/QAaJiYaAwAaJuAoODgoKDg4/biAAYD+wMAAAAYAAP/AA8ADwAAPABMAFwAbAB8AIwAAASEiBhURFBYzITI2NRE0JgMhESEBIRUhFSEVIRUhFSERIRUhA2D9ACg4OCgDACg4OEj9QALA/cABwP5AAcD+QAHA/kABwP5AA8A4KPzAKDg4KANAKDj8gAMA/sBAQEBAQAHAQAACAAAAAAQAA0AABQAMAAABJyERIREFFyMRIxEjAkCA/kAEAP4A4KCAoALAgPzAAsDg4P8AAQAAAAMAAP/ABAADwAAEAAgAEQAAASERIREhMxEjASERMxEhETMXA4D8gAQA/gCAgAGA/QBAAkBLNQPA/AADgP8A/gADAP7AAUA1AAMAAP/ABAADwAAVACsAQQAAASIOAh0BFB4CMzI+Aj0BNC4CAyIuAjUVFB4CMzI+Aj0BFA4CAyIuAjUVFB4CMzI+Aj0BFA4CAgBqu4tQUIu7amq7i1BQi7tqaruLUFCLu2pqu4tQUIu7amq7i1BQi7tqaruLUFCLuwPAGSw6IYAhOiwZGSw6IYAhOiwZ/eAZLDohwCE6LBkZLDohwCE6LBn+4BksOiHAITosGRksOiHAITosGQAAAAABAAAAAAQAA4AAIQAAASIOAgcnESEnPgEzMh4CFRQOAgcXPgM1NC4CIwIANWRcUiOWAYCQNYtQUItpPBIiMB5VKEAtGFCLu2oDgBUnNyOW/oCQNDw8aYtQK1FJQRpgI1ZibDlqu4tQAAEAAAAABAADgAAgAAATFB4CFzcuAzU0PgIzMhYXByERBy4DIyIOAgAYLUAoVR4wIhI8aYtQUIs1kAGAliNSXGQ1aruLUAGAOWxiViNgGkFJUStQi2k8PDSQAYCWIzcnFVCLuwACACD/8AQAA7AAOgByAAABLgEnLgEnLgEnLgEHDgEHDgEHDgEHDgEXHgEXHgEXHgEXHgE3PgE3PgE3PgE3PgE3OgEzMjY1PAE1MQcOAQcOAQcOAScuAScuAScuAScuATc+ATc+ATc+ATc+ARceARceARceARceAQcxHAEVFBYXDgEHBAABFRUUOSQjVC4tYTExXywtTyEhNBESEAEBFBMTNiEiTisrWi4uWSkpSx4fMRAJDgMBAgEbJWYRMx8fSSgoVSoqUycmRR0dLA8PDgEBEhARLh0eQyUlTycnTSQjQBobKQ4NDQEhGAUPCwHAMmMtLlIiIzUSEhEBARUTFDcjIlEtLF4vL1wrK00gIDIQERABARQSEjQhIEwpGTQbJRsBAwGqKEceHi4QDw8BARIRETEeHkcmJ1EpKVAlJUIcGysODw0BAREQEC0cHEEkI0smAQMBGSQDGjMYAAAEAAD/wAQAA8AABgANABQAGwAAASEXBxc3FxkBBycHFwcpASc3JwcnGQE3FzcnNwQA/mCgwGDAoKDAYMCg/aABoKDAYMCgoMBgwKADwKDAYMCg/aABoKDAYMCgoMBgwKACYP5goMBgwKAAAAAHAED/wAOAA8AACQANABEAFQAZAC0AMQAAExEUFjMhMjY1EQEjETMTIxEzEyMRMxMjETMTIzU0JisBIgYdASMiBh0BITU0JiEjNTOAJhoCQBom/gBAQIBAQIBAQIBAQJDQHBTgFBzQFBwDQBz+3MDAAoD9gBomJhoCgP3AAcD+QAHA/kABwP5AAcABQFAUHBwUUBwUUFAUHD8AAAAKAAD/wAQAA8AADQAbACkANwBGAFQAYwByAIYAkgAAJTIWHQEUBiMiJj0BNDYTIiY9ATQ2MzIWHQEUBgEyFhUUBisBIiY1NDYzBRQGKwEiJjU0NjsBMhYFFxYUBwYiLwEmNDc2MhcBJyY0NzYyHwEWFAcGIiUGIicmND8BNjIXFhQPAQE2MhcWFA8BBiInJjQ/AQEiDgIVFB4CMzI+AjU0LgIDIiY1NDYzMhYVFAYCABslJRsbJSUbGyUlGxslJQGlGyUlG0AbJSUb/UAlG0AbJSUbQBslAn0tExMTNRIuEhITNRP9hi0TExM1Ei4SEhM1AmcTNRMSEi4SNRMTEy39hhM1ExISLhI1ExMTLQE9NV1GKChGXTU1XUYoKEZdNUJeXkJCXl6AJRtAGyUlG0AbJQKAJRtAGyUlG0AbJf8AJRsbJSUbGyVAGyUlGxslJf0uEjUTExMtEzUTEhIBxC4SNRMTEy0TNRMSEhISEzUTLRMTEzUSLv48EhITNRMtExMTNRIuAeIoRl01NV1GKChGXTU1XUYo/mBeQkJeXkJCXgAAAAADAED/wAPAA8AAPgBKAI4AAAE1NCYjIgYHLgEjIgYHLgEjIgYHNTQmIyIGFREnLgEjIgYVFBYXMhQxFyMiBh0BFBYzITI2PQE0JisBNz4BNQMUBiMiJjU0NjMyFjUHIQEuATU0NjMyFhcyFjEXFjI3PgE1ETQ2MzIWFREUFjMyNjU0NjMyFhUUFjMyNjU0NjMyFh0BFBYzMjY1NDYzMhYVA8A4KA0YCg0rGRIhDQ0hEggQCDgoKDiwCxgNKDgPDgHvLQ0TEw0CgA0TEw0sSQECQBMNDRMTDQ0TVP6A/t4FBRMNBAgDAQHgBxEHCAgTDQ0TEw0NExMNDRMTDQ0TEw0NExMNDRMTDQ0TAWCgKDgGBhQYDQwMDQMC5Sg4OCj+dV4GBzgoFCQNAdoTDcANExMNwA0TkgMHBP8ADRMTDQ0TE/uoAQkFCwcNEwICAXcEBQQPCAHADRMTDf7ADRMTDQ0TEw0NExMNDRMTDSANExMNDRMTDQADAAD/wAQAA8AAEwAnACoAAAEiDgIVFB4CMzI+AjU0LgIDIi4CNTQ+AjMyHgIVFA4CAw0BAgBqu4tQUIu7amq7i1BQi7tqVphxQUFxmFZWmHFBQXGY1gGA/oADwFCLu2pqu4tQUIu7amq7i1D8YEFxmFZWmHFBQXGYVlaYcUECgODgAAADAAD/wAQAA8AAEwAnACsAAAEiDgIVFB4CMzI+AjU0LgIDIi4CNTQ+AjMyHgIVFA4CASERIQIAaruLUFCLu2pqu4tQUIu7alaYcUFBcZhWVphxQUFxmP7qAYD+gAPAUIu7amq7i1BQi7tqaruLUPxgQXGYVlaYcUFBcZhWVphxQQJg/oAAAAAAAQAAAAAAAMXcSA9fDzz1AAsEAAAAAADUxQX+AAAAANTFBf4AAP/ABAADwAAAAAgAAgAAAAAAAAABAAADwP/AAAAEAAAAAAAEAAABAAAAAAAAAAAAAAAAAAAAEwQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAACAEAAAABAAAQAQAAAAEAABABAAAAAQAAAAAAAAAAAoAFAAeAGAAqADmAQIBJgGCAbYB6AKWAswDGgPsBKYE6AUsAAEAAAATAJMACgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAHAAAAAQAAAAAAAgAHAGAAAQAAAAAAAwAHADYAAQAAAAAABAAHAHUAAQAAAAAABQALABUAAQAAAAAABgAHAEsAAQAAAAAACgAaAIoAAwABBAkAAQAOAAcAAwABBAkAAgAOAGcAAwABBAkAAwAOAD0AAwABBAkABAAOAHwAAwABBAkABQAWACAAAwABBAkABgAOAFIAAwABBAkACgA0AKRpY29tb29uAGkAYwBvAG0AbwBvAG5WZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADBpY29tb29uAGkAYwBvAG0AbwBvAG5pY29tb29uAGkAYwBvAG0AbwBvAG5SZWd1bGFyAFIAZQBnAHUAbABhAHJpY29tb29uAGkAYwBvAG0AbwBvAG5Gb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('woff');
font-weight: normal;
font-style: normal;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
&:before {
font-family: 'icomoon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
color: inherit;
display: inline-block;
vertical-align: middle;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}
.icon-paint-format:before{content:"\e90c";}
.icon-image:before{content:"\e90d";}
.icon-file-text:before{content:"\e922";}
.icon-folder-upload:before{content:"\e934";}
.icon-floppy-disk:before{content:"\e962";}
.icon-database:before{content:"\e964";}
.icon-undo:before{content:"\e965";}
.icon-redo:before{content:"\e966";}
.icon-enlarge:before{content:"\e989";}
.icon-bin:before{content:"\e9ac";}
.icon-sun:before{content:"\e9d4";}
.icon-point-up:before{content:"\ea03";}
.icon-play2:before{content:"\ea15";}
.icon-stop:before{content:"\ea17";}
.icon-spinner2:before{content:"\e97b";}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.artboard-modal {
display: none;
justify-content: center;
flex-direction: column;
align-items: center;
position: fixed;
z-index: 100;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
padding: 50px;
background: rgba(0,0,0,0.9);
text-align: center;
user-select: none;
&.active {
display: flex;
}
&__summary {
display: block;
max-width: 400px;
color: #fff;
}
&__footer {
margin-top: 50px;
&__no {
display: none;
padding: 10px !important;
background: #08f !important;
&.active {
display: inline-block;
}
}
&__yes {
display: none;
padding: 10px !important;
background: #08f !important;
&.active {
display: inline-block;
}
}
&__ok {
display: none;
padding: 10px !important;
background: #08f !important;
&.active {
display: inline-block;
}
}
}
}
.artboard__canvas {
position: relative;
width: calc(100% - 100px);
margin-left: 50px;
min-height: 101vh;
margin-bottom: 80px;
&.active {
&:before {
content:"\e97b";
display: inline-block;
position: absolute;
z-index: 1;
top: 29px;
left: 18px;
font-family: "icomoon";
font-size: 18px;
line-height: 18px;
color: #fff;
animation: spin 1s linear infinite;
}
}
button {
border: none;
padding: 0 5px;
background: none;
color: #fff;
cursor: pointer;
&:focus,
&:hover {
&:before {
color: #08f;
text-shadow: 0 0 4px #fff;
}
}
}
input[type="checkbox"] {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.00001;
cursor: pointer;
&:focus,
&:hover {
& + label {
&:before {
color: #08f;
text-shadow: 0 0 4px #fff;
}
}
}
&:checked {
& + label {
opacity: 1;
}
}
& + label {
opacity: 0.25;
}
}
&__tools {
position: relative;
margin: 0 auto;
padding: 15px 20px;
background-color: #888;
vertical-align: middle;
//@media (min-width: 900px) {
display: flex;
align-items: center;
flex-wrap: wrap;
//}
&__size {
position: absolute;
bottom: 10px;
left: 7px;
color: #fff;
font-size: 10px;
font-style: normal;
line-height: 0;
}
&__section {
position: relative;
display: block;
vertical-align: middle;
color: #fff;
margin: 10px 0;
//@media (min-width: 900px) {
display: inline-block;
margin-left: 30px;
//}
&__label {
display: block;
margin-top: 10px;
color: #fff;
//@media (min-width: 900px) {
display: inline;
//}
}
&__rainbow {
width: auto;
-webkit-appearance: checkbox;
-moz-appearance: checkbox;
}
&__color {
width: 50px;
padding: 0;
border: none;
-webkit-appearance: square-button;
-moz-appearance: square-button;
}
&__radius {
width: 100px;
padding: 0;
border: none;
vertical-align: middle;
-webkit-appearance: slider-horizontal;
-moz-appearance: slider-horizontal;
}
&__shadow {
width: 100px;
padding: 0;
border: none;
vertical-align: middle;
-webkit-appearance: slider-horizontal;
-moz-appearance: slider-horizontal;
}
&__advanced-options {
background: #fff !important;
color: #888 !important;
}
}
&__hr {
display: none;
&.active {
display: block;
}
}
&--advanced {
display: none;
&.active {
display: block;
}
}
}
&__canvas-wrap {
display: inline-block;
border: 1px solid #888;
line-height: 0;
}
&__canvas {
user-select: none;
width: 100%;
}
}
function tools() {
// Get Elements By Class Name
function gebcn(str) {
return document.getElementsByClassName(str);
}
// Elements
const component = gebcn('artboard__canvas')[0];
const modal = gebcn('artboard-modal')[0];
const modalSummary = gebcn('artboard-modal__summary')[0];
const modalNo = gebcn('artboard-modal__footer__no')[0];
const modalYes = gebcn('artboard-modal__footer__yes')[0];
const modalOk = gebcn('artboard-modal__footer__ok')[0];
const canvas = gebcn('artboard__canvas__canvas')[0];
const tools = gebcn('artboard__canvas__tools')[0];
const size = gebcn('artboard__canvas__tools__size')[0];
const clear = gebcn('artboard__canvas__tools__clear')[0];
//const reset = gebcn('artboard__canvas__tools__reset')[0];
const color = gebcn('artboard__canvas__tools__section__color')[0];
const singleTouch = gebcn('artboard__canvas__tools__section__single-touch')[0];
const rainbow = gebcn('artboard__canvas__tools__section__rainbow')[0];
const radius = gebcn('artboard__canvas__tools__section__radius')[0];
const shadow = gebcn('artboard__canvas__tools__section__shadow')[0];
const undo = gebcn('artboard__canvas__tools__section__undo')[0];
const redo = gebcn('artboard__canvas__tools__section__redo')[0];
const stop = gebcn('artboard__canvas__tools__section__stop')[0];
const play = gebcn('artboard__canvas__tools__section__play')[0];
const save = gebcn('artboard__canvas__tools__section__save')[0];
const restore = gebcn('artboard__canvas__tools__section__restore')[0];
const saveAsInput = gebcn('artboard__canvas__tools__section__save-as-input')[0];
const saveAs = gebcn('artboard__canvas__tools__section__save-as')[0];
const restoreNamedInput = gebcn('artboard__canvas__tools__section__restore--named-input')[0];
const restoreNamed = gebcn('artboard__canvas__tools__section__restore--named')[0];
const backup = gebcn('artboard__canvas__tools__section__backup')[0];
const saved = gebcn('artboard__canvas__tools__section__saved')[0];
const deleteSaved = gebcn('artboard__canvas__tools__section__delete-saved')[0];
const downloadImage = gebcn('artboard__canvas__tools__section__download-image')[0];
const downloadImageAsInput = gebcn('artboard__canvas__tools__section__download-image-as-input')[0];
const downloadImageAs = gebcn('artboard__canvas__tools__section__download-image-as')[0];
const hr = gebcn('artboard__canvas__tools__hr')[0];
const advancedOptionsButton = gebcn('artboard__canvas__tools__section__advanced-options')[0];
const advancedOptions = gebcn('artboard__canvas__tools--advanced')[0];
// Alert callback
let modalCallbackConfirmFn = null;
// Alert hide
function modalHide() {
modal.classList.remove('active');
}
// Alert show
function modalShow(html, confirmCallback) {
modalSummary.innerHTML = html;
if (confirmCallback) {
modalCallbackConfirmFn = confirmCallback;
modalNo.classList.add('active');
window.setTimeout(() => {
modalNo.focus();
});
modalYes.classList.add('active');
modalOk.classList.remove('active');
} else {
modalNo.classList.remove('active');
modalYes.classList.remove('active');
modalOk.classList.add('active');
window.setTimeout(() => {
modalOk.focus();
});
}
modal.classList.add('active');
}
// Loading
function loading() {
component.classList.add('active');
}
// Stop Loading
function stopLoading() {
component.classList.remove('active');
}
// Replaying
let replaying = false;
// Done callback
function doneCallback() {
stopLoading();
replaying = false;
}
// Create a new Artboard instance
// In timeout because many times the browser can't get the rendered width of the toolbar in time to set the canvas size.
const ab = new Artboard(canvas, {
width: tools.offsetWidth - 2,
height: (tools.offsetWidth - 2) * (9/16),
multiTouch: true,
rainbow: true,
color: '#000000',
glow : 10,
radius: 10,
done: doneCallback // Called after playback finishes; or after restore, undo, redo, or stop is called
}, () => {
alert('The Artboard is not supported on this browser.');
});
// Reset onload, but timeout so the referenced toolbar width can be rendered and return an accurate width
window.setTimeout(() => {
ab.reset({
width: tools.offsetWidth - 2,
height: (tools.offsetWidth - 2) * (9/16)
});
});
// Canvas element and wrapper
function setColor() {
if (replaying) {
modalShow('Can\'t set color during playback.');
return;
}
ab.adjust({
color: color.value
});
}
function toggleSingleTouch() {
if (replaying) {
modalShow('Can\'t adjust touch type during playback.');
return;
}
if (singleTouch.checked) {
//singleTouch.checked = true;
ab.adjust({
multiTouch: false
});
} else {
//singleTouch.checked = false;
ab.adjust({
multiTouch: true
});
}
}
function toggleDisableColor() {
if (replaying) {
modalShow('Can\'t toggle color during playback.');
return;
}
if (color.hasAttribute('disabled')) {
color.removeAttribute('disabled');
color.style.opacity = 1;
color.previousElementSibling.style.opacity = 1;
ab.adjust({
rainbow: false,
color: color.value
});
} else {
color.setAttribute('disabled', 'true');
color.style.opacity = 0.1;
color.previousElementSibling.style.opacity = 0.1;
ab.adjust({
rainbow: true,
color: color.value
});
}
}
function setSize() {
size.textContent = (ab.size() / 1024 / 1024).toFixed(2) + ' MB';
}
function setRadius() {
if (replaying) {
modalShow('Can\'t set the radius during playback.');
return;
}
ab.adjust({
radius: window.parseFloat(radius.value)
});
}
function setShadow() {
if (replaying) {
modalShow('Can\'t set the shadow during playback.');
return;
}
ab.adjust({
glow: window.parseFloat(shadow.value)
});
}
modalNo.addEventListener('click', modalHide);
modalYes.addEventListener('click', () => {
modalCallbackConfirmFn();
modalHide();
});
modalOk.addEventListener('click', modalHide);
clear.addEventListener('click', () => {
if (replaying) {
modalShow('Can\'t reset/clear during playback.');
return;
}
modalShow('Are you sure you want to erase this artboard?', () => {
ab.clear();
setSize();
});
});
// reset.addEventListener('click', () => {
// ab.reset({
// width: tools.offsetWidth - 2,
// height: (tools.offsetWidth - 2) / 2
// });
// rainbow.checked = true;
// });
color.addEventListener('change', setColor);
singleTouch.addEventListener('click', toggleSingleTouch);
rainbow.addEventListener('click', toggleDisableColor);
radius.addEventListener('input', setRadius);
shadow.addEventListener('input', setShadow);
function restoreSettings(currSettings) {
if (replaying) {
modalShow('Can\'t restore during playback.');
return;
}
color.value = currSettings.color;
radius.value = currSettings.radius;
shadow.value = currSettings.glow;
rainbow.checked = currSettings.rainbow;
if (currSettings.rainbow) {
color.setAttribute('disabled', 'true');
color.style.opacity = 0.1;
color.previousElementSibling.style.opacity = 0.1;
} else {
color.removeAttribute('disabled');
color.style.opacity = 1;
color.previousElementSibling.style.opacity = 1;
}
singleTouch.checked = !currSettings.multiTouch;
setSize();
}
undo.addEventListener('click', function () {
if (replaying) {
modalShow('Can\'t undo during playback.');
return;
}
loading();
window.setTimeout(() => {
if (ab.undo()) {
restoreSettings(ab.settings());
} else {
modalShow('Nothing to undo.');
}
window.setTimeout(stopLoading,100);
},100);
});
redo.addEventListener('click', function () {
if (replaying) {
modalShow('Can\'t redo during playback.');
return;
}
loading();
window.setTimeout(() => {
if (ab.redo()) {
restoreSettings(ab.settings());
} else {
modalShow('Nothing to redo.');
}
window.setTimeout(stopLoading,100);
},100);
});
stop.addEventListener('click', ab.stop);
play.addEventListener('click', () => {
if (ab.play()) {
component.classList.add('active');
replaying = true;
}
});
save.addEventListener('click', () => {
if (replaying) {
modalShow('Can\'t save during playback.');
return;
}
if (ab.save()) {
modalShow('Saved!');
} else {
modalShow('There\'s nothing to save.');
}
});
restore.addEventListener('click', () => {
if (replaying) {
modalShow('Can\'t restore during playback.');
return;
}
loading();
window.setTimeout(() => {
if (ab.restore()) {
modalShow('Restored!');
} else {
stopLoading();
modalShow('Nothing to restore.');
}
});
});
function downloadImageAsFn() {
ab.image(downloadImageAsInput.value);
}
downloadImageAsInput.addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
downloadImageAsFn();
}
});
downloadImageAs.addEventListener('click', downloadImageAsFn);
function saveAsArtboard() {
if (replaying) {
modalShow('Can\'t save during playback.');
return;
}
ab.saveAs(saveAsInput.value, function(success) {
if (success) {
modalShow(`Saved: "${saveAsInput.value}"!`);
saveAsInput.value = '';
} else if (/^\s*$/.test(saveAsInput.value)) {
modalShow('An artboard name is required.');
} else if (!/^[a-zA-Z0-9_$]+$/.test(saveAsInput.value)) {
modalShow('The artboard name has characters other than: A-Z, a-z, 0-9, $, and _');
} else {
modalShow('There\'s nothing to save.');
}
});
}
saveAsInput.addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
saveAsArtboard();
}
});
saveAs.addEventListener('click', saveAsArtboard);
function restoreNamedArtboard() {
if (replaying) {
modalShow('Can\'t restore during playback');
return;
}
loading();
window.setTimeout(() => {
if (/^\s*$/.test(restoreNamedInput.value)) {
stopLoading();
modalShow('An artboard name is required.');
} else if (ab.restore(restoreNamedInput.value)) {
modalShow(`Restored "${restoreNamedInput.value}"`);
restoreNamedInput.value = '';
} else {
stopLoading();
modalShow('Nothing to restore by that name.');
}
});
}
restoreNamedInput.addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
restoreNamedArtboard();
}
});
restoreNamed.addEventListener('click', restoreNamedArtboard);
backup.addEventListener('click', () => {
if (replaying) {
modalShow('Can\'t backup during playback');
return;
}
const bu = ab.backup();
// ab.clear();
console.log(bu);
// window.setTimeout(() => {
// ab.restore(bu);
// }, 1000);
});
saved.addEventListener('click', () => {
const stored = ab.saved();
if (stored.length) {
modalShow('Your saved & named artboards are:<br>' + stored.toString().replace(/,/g,', '));
} else {
modalShow('No artboards are saved.');
}
});
deleteSaved.addEventListener('click', () => {
modalShow('Are you sure you want to delete all of your saved artboards? This action cannot be undone.', () => {
console.log('Saved before:');
console.log(ab.saved());
ab.deleteSaved();
console.log('Saved after:');
console.log(ab.saved());
});
});
downloadImage.addEventListener('click', ab.image);
color.setAttribute('disabled', 'true');
color.style.opacity = 0.1;
color.previousElementSibling.style.opacity = 0.1;
advancedOptionsButton.addEventListener('click', () => {
if (advancedOptions.classList.contains('active')) {
advancedOptions.classList.remove('active');
hr.classList.remove('active');
} else {
advancedOptions.classList.add('active');
hr.classList.add('active');
}
});
document.addEventListener('mouseup', setSize);
document.addEventListener('touchend', setSize);
} // end tools();
tools();
ArtboardJS Demo
Advanced
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - FlagstoneJS v4.0.0
<h1>FlagstoneJS <span class="yellow">4.0.0</span><span class="slogan">Dynamic & responsive tiling</span></h1>
<p class="quick-info"><span class="yellow">12.5 KB</span> | No dependencies | Loaded with options</p>
<div class="adjust">
<table>
<thead>
<tr>
<th>Property</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>margin:</td>
<td><input type="number" min="0" max="1000" disabled id="adjust-margin"></td>
</tr>
<tr>
<td>bedPadding:</td>
<td><input type="number" min="0" max="1000" value="10" id="adjust-bed-padding"></td>
</tr>
<tr>
<td>stonesMargin:</td>
<td><input type="number" min="0" max="1000" value="10" id="adjust-stones-margin"></td>
</tr>
<tr>
<td>minWidth:</td>
<td><input type="number" min="0" max="1000" value="280" id="adjust-min-width"></td>
</tr>
<tr>
<td>maxColumns:</td><td><input type="number" min="0" max="1000" value="5" id="adjust-max-columns"></td>
</tr>
<tr>
<td>dragAndDrop:</td>
<td><input type="checkbox" checked id="adjust-drag-and-drop"></td>
</tr>
<tr>
<td>dropCallback:</td>
<td><textarea id="adjust-drop-callback">function(dragElem, targetElem) {
return true;
}</textarea></td>
</tr>
<tr>
<td>callback:</td>
<td><textarea id="adjust-callback">function(elem, index) {
if (index === 3) {
elem.classList.add('highlight');
} else {
elem.classList.remove('highlight');
}
}</textarea></td>
</tr>
</tbody>
<tfoot>
<tr>
<td><button class="apply-adjustments">Apply</button></td>
<td></td>
</tr>
</tfoot>
</table>
<div class="toggle-widget">
<p>Toggle Adjust Widget</p>
<button>⇕</button>
</div>
</div>
<button class="add-card">Inject a card</button>
<article style="visibility:hidden;">
<section class="flagstone-drag-handle">
<h2>1</h2>
<button class="flagstone-remove">×</button>
<p class="p-animate">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<button class="toggle-more show-more flagstone-resize-height">Show More</button>
<button class="toggle-more show-less flagstone-resize-height">Show Less</button>
</section>
<section class="flagstone-drag-handle">
<h2>2</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<img src="http://placebear.com/160/160" alt="" style="float:left;width:80px;margin:10px 10px 10px 0;"/>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section class="flagstone-drag-handle">
<h2>3</h2>
<button class="flagstone-remove">×</button>
<img src="http://placebear.com/260/80" alt="" id="change-my-source"/>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</section>
<section class="flagstone-drag-handle">
<h2>4</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Lorem ipsum dolor sit amet hic cupiditate sapiente placeat temporibus.</p>
</section>
<section class="flagstone-drag-handle">
<h2>5</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet. Hic cupiditate sapiente placeat temporibus, placeat temporibus, fugiat eos.</p>
</section>
<section class="flagstone-drag-handle">
<h2>6</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section class="flagstone-drag-handle">
<h2>7</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus. Accusamus ducimus unde amet quam omnis.</p>
</section>
<section class="flagstone-drag-handle">
<h2>8</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam quibusdam placeat dolorum natus voluptatum reiciendis cupiditate, cum veritatis accusamus labore consectetur ab amet, sit commodi laudantium beatae molestiae iste repellendus.</p>
</section>
<section class="flagstone-drag-handle">
<h2>9</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section class="flagstone-drag-handle">
<h2>10</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section class="flagstone-drag-handle">
<h2>11</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus.</p>
</section>
</article>
<!-- <article>
<section>
<h2>1</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section>
<h2>2</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<img src="http://placebear.com/160/160" alt="" style="float:left;width:80px;margin:10px 10px 10px 0;"/>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section>
<h2>3</h2>
<button class="flagstone-remove">×</button>
<img src="http://placebear.com/260/80" alt="" />
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</section>
<section>
<h2>4</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Lorem ipsum dolor sit amet hic cupiditate sapiente placeat temporibus.</p>
</section>
<section>
<h2>5</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet. Hic cupiditate sapiente placeat temporibus, placeat temporibus, fugiat eos.</p>
</section>
<section>
<h2>6</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section>
<h2>7</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus. Accusamus ducimus unde amet quam omnis.</p>
</section>
<section>
<h2>8</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam quibusdam placeat dolorum natus voluptatum reiciendis cupiditate, cum veritatis accusamus labore consectetur ab amet, sit commodi laudantium beatae molestiae iste repellendus.</p>
</section>
<section>
<h2>9</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section>
<h2>10</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.</p>
</section>
<section>
<h2>11</h2>
<button class="flagstone-remove">×</button>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus.</p>
</section>
</article> -->
<script>
// Download plugin from https://github.com/depthdev/flagstonejs
/*
FlagstoneJS v4.0.0
(c) 2015-2018 Depth Development. http://depthdev.com
License: MIT
*/
!function(e,t){"use strict";e.flagstone=function(n,r){function a(n,r){function a(){for(var e=0,t=k.length;e<t;e++)Math.random()<q&&k.splice(e,0,!1)}function o(){L.style.visibility="hidden"}function s(){L.style.visibility="visible"}function i(){var t=[w],n=0,r=O.length;for(M=[];n<r;n++){if(n<w)k[n]?(k[n].style.transform="translate("+(A*n+(n?C*n+E:E))+"px,"+E+"px)",Z&&(k[n].style.height=k[n].style.width),t[n]=O[n]+E,ae(k[n],n),M.push([k[n]])):w>1&&(t[n]=A+E);else{var a=Math.min.apply(null,t),o=t.indexOf(a);k[n]?(k[n].style.transform="translate("+(A*o+(o?C*o+E:E))+"px,"+(a+C)+"px)",Z&&(k[n].style.height=k[n].style.width),t[o]+=O[n]+C,ae(k[n],n),M[o].push(k[n])):w>1&&(t[o]+=A+C)}b=(Math.max.apply(null,t)||O[0]+E)+E,L.style.height=b+"px"}e.setTimeout(s)}function l(t){if(k.length){y=L.offsetWidth,y<T+(E?2*E:0)&&(y=T),D=Math.floor(y/T),w=D>x?x:D,A=y/w-(C*(w-1)+2*E)/w,O=[];for(var n=0,r=k.length;n<r;n++)k[n]&&(k[n].style.width=A+"px",k[n].style.marginTop="0px"),O.push(Z||!k[n]?A:k[n].offsetHeight);y===L.offsetWidth||t?i():l(!0),t||e.setTimeout(function(){l(!0)},W)}}function g(t){if("keydown"!==t.type||13===t.keyCode||32===t.keyCode){for(var n=t.target;n&&!n.classList.contains(B);)n=n.parentElement;L.removeChild(n),e.MutationObserver||!oe&&!se||de()}}function d(t){"keydown"===t.type&&13!==t.keyCode&&32!==t.keyCode||e.setTimeout(l,Q)}function c(t){function n(){for(var t=0,n=M.length,r=0,a=0;t<n&&!g;t++)for(r=0,a=M[t].length;r<a;r++)g&&(i.push(M[t][r]),l.push(e.parseInt(M[t][r].style.marginTop,10)||0)),M[t][r]===o&&(g=!0)}function r(){for(var t=0,n=w,a=[];t<n;t++){var o=M[t][M[t].length-1],s=e.parseInt(o.style.transform.match(/\d+px/)[0],10)+(e.parseInt(o.style.marginTop,10)||0)+o.offsetHeight+E;a.push(s)}var i=Math.max.apply(null,a);L.style.height=i+"px",V=e[($?"request":"cancel")+"AnimationFrame"](r)}function a(){function t(){for(var r=o.offsetHeight+s,g=r-a,d=0;d<n;d++)i[d].style.marginTop=g+l[d]+"px";te=e[(ne?"request":"cancel")+"AnimationFrame"](t)}var n=i.length,a=e.parseInt(i[0].style.transform.match(/\d+px/)[0],10)-C+l[0];ne=!0,te=e.requestAnimationFrame(t),re=e.setTimeout(function(){ne=!1,e.cancelAnimationFrame(te)},U),$=!0,V=e.requestAnimationFrame(r),ee=e.setTimeout(function(){$=!1,e.cancelAnimationFrame(V)},U)}for(var o=t;o&&!o.classList.contains(B);)o=o.parentElement;var s=e.parseInt(o.style.transform.match(/\d+px/)[0],10)+(e.parseInt(o.style.marginTop,10)||0),i=[],l=[],g=!1;return n(),$=!1,e.cancelAnimationFrame(V),e.clearTimeout(ee),ne=!1,e.cancelAnimationFrame(te),e.clearTimeout(re),i.length?void a():($=!0,V=e.requestAnimationFrame(r),void(ee=e.setTimeout(function(){$=!1,e.cancelAnimationFrame(V)},U)))}function m(e){"keydown"===e.type&&13!==e.keyCode&&32!==e.keyCode||c(e.target)}function f(){e.clearTimeout(le),le=e.setTimeout(l,Y)}function v(){e.clearTimeout(ge),ge=e.setTimeout(de)}function u(){e.removeEventListener("resize",f),t.head.removeChild(t.getElementById("flagstone-"+S+"-styles"))}function h(e){e.margin||0===e.margin?(E=e.margin,C=e.margin):(E=e.bedPadding||E,C=e.stonesMargin||C),T=e.minWidth||T,x=e.maxColumns||x,G=e.dragAndDrop===!0||e.dragAndDrop===!1?e.dragAndDrop:G,K=e.dropCallback||K,ae=e.callback||ae,de()}var S=e.flagstone.index,p=r||{},L=n?"string"==typeof n?t.querySelector(n):n:t.getElementsByClassName("flagstone")[0],E=p.margin||0===p.margin?p.margin:p.bedPadding||0===p.bedPadding?p.bedPadding:10,y=0,b=0,T=p.minWidth||280,x=p.maxColumns||5,D=0,w=0,k=[],C=p.margin||0===p.margin?p.margin:p.stonesMargin||0===p.stonesMargin?p.stonesMargin:10,A=y/w-C*(w+1)/w,O=[],M=[],B="flagstone-"+S+"-bed__stone",F=p.flow,z=p.direction?p.direction.toLowerCase():"left",I=p.assignReverseZIndexes,P=p.random,q=p.spaceFrequency||.4,N=p.space,W=p.animationDuration||0,H=p.animationDuration/1e3,R=p.animationTimingFunction||"linear",_=p.heightAnimationDuration||0,X=p.heightAnimationDuration/1e3,j=p.heightAnimationTimingFunction||"linear",Y=p.resizeDelay||0===p.resizeDelay?p.resizeDelay:250,Z=p.square,G=p.dragAndDrop,J=p.dragAndDropAutoDelay,K=p.dropCallback||function(){return!0},Q=p.eventResetDelay||0,U=p.eventResizeHeightDuration||0,V=null,$=!1,ee=null,te=null,ne=!1,re=null,ae=p.callback||function(){},oe=p.watch!==!1,se=p.watchAll,ie=p.watchImages!==!1,le=null,ge=null,de=null,ce={targetElem:null,dragStone:null,targetStone:null,targetStoneOverLeft:0,autoDropTimer:null,autoDrop:function(){ce.targetStone&&ce.targetStone.classList.contains(B)&&(ce.targetStoneOverLeft?ce.dragStone!==ce.targetStone.previousElementSibling&&(ce.targetStone.parentElement.insertBefore(ce.dragStone,ce.targetStone),ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.remove("flagstone-dragover")):ce.dragStone!==ce.targetStone.nextElementSibling&&(ce.targetStone.parentElement.insertBefore(ce.dragStone,ce.targetStone.nextElementSibling),ce.targetStone.classList.remove("flagstone-right"),ce.targetStone.classList.remove("flagstone-dragover")),e.clearTimeout(ce.autoDropTimer),ce.autoDropTimer=e.setTimeout(ce.autoDrop,J))},clear:function(){ce.dragStone&&(ce.dragStone.classList.remove("flagstone-drag"),ce.dragStone=null),ce.targetStone&&(ce.targetStoneOverLeft=0,ce.targetStone.classList.remove("flagstone-dragover"),ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.remove("flagstone-right"),ce.targetStone=null),L.classList.remove("flagstone-dragover")},getTargetElem:function(e){for(ce.targetElem=e.target instanceof HTMLElement?e.target:e.target.parentElement;ce.targetElem&&!ce.targetElem.classList.contains("flagstone-drag-handle");)ce.targetElem=ce.targetElem.parentElement;if(ce.targetElem)for(ce.dragStone=ce.targetElem;ce.dragStone&&!ce.dragStone.classList.contains(B);)ce.dragStone=ce.dragStone.parentElement},mouseDown:function(e){ce.getTargetElem(e)},dragStart:function(e){return!!ce.targetElem&&(ce.dragStone.classList.add("flagstone-drag"),void(e.dataTransfer&&e.dataTransfer.setData("text",this.id)))},touchStart:function(e){ce.getTargetElem(e),ce.dragStart(e)},dragEnter:function(t){t.preventDefault(),t.stopPropagation(),this!==ce.dragStone&&this!==ce.targetStone&&this!==L&&(e.clearTimeout(ce.autoDropTimer),ce.autoDropTimer=e.setTimeout(ce.autoDrop,J))},touchMove:function(e){if(!ce.dragStone)return!1;e.preventDefault(),e.stopPropagation();for(var n=t.elementFromPoint(e.touches[0].clientX,e.touches[0].clientY),r=n;r&&!r.classList.contains(B);)r=r.parentElement;r?(L.classList.remove("flagstone-dragover"),ce.targetStoneOverLeft=r.getBoundingClientRect().left+r.offsetWidth/2>e.touches[0].clientX,ce.targetStone&&ce.targetStone!==r&&(ce.targetStone.classList.remove("flagstone-dragover"),ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.remove("flagstone-right")),ce.targetStone=r,ce.targetStone.classList.contains("flagstone-lock")||(ce.targetStone.classList.add("flagstone-dragover"),ce.targetStoneOverLeft?(ce.targetStone.classList.remove("flagstone-right"),ce.targetStone.classList.add("flagstone-left")):(ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.add("flagstone-right")))):n===L&&(ce.targetStone.classList.remove("flagstone-dragover"),ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.remove("flagstone-right"),L.classList.add("flagstone-dragover"),ce.targetStone=L)},dragOver:function(e){return!!ce.dragStone&&(e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="move",void(this!==ce.dragStone&&this.classList.contains(B)?(ce.targetStone=this,ce.targetStone.classList.add("flagstone-dragover"),ce.targetStoneOverLeft=this.getBoundingClientRect().left+this.offsetWidth/2>e.clientX,ce.targetStoneOverLeft?(ce.targetStone.classList.remove("flagstone-right"),ce.targetStone.classList.add("flagstone-left")):(ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.add("flagstone-right")),this.classList.remove("flagstone-dragover"),ce.targetStone!==L&&L.classList.remove("flagstone-dragover")):this===L&&this.classList.add("flagstone-dragover")))},dragEnd:function(){ce.clear()},touchEnd:function(){ce.dragStone&&ce.targetStone&&!ce.targetStone.classList.contains("flagstone-lock")&&K(ce.dropStone,ce.targetStone)&&(ce.targetStone===L?L.appendChild(ce.dragStone):ce.targetStoneOverLeft?L.insertBefore(ce.dragStone,ce.targetStone):L.insertBefore(ce.dragStone,ce.targetStone.nextElementSibling)),ce.clear()},dragLeave:function(){ce.targetStone&&(ce.targetStone.classList.remove("flagstone-dragover"),ce.targetStone.classList.remove("flagstone-left"),ce.targetStone.classList.remove("flagstone-right"),L.classList.remove("flagstone-dragover"))},drop:function(t){if(!ce.dragStone)return!1;if(t.stopPropagation(),e.clearTimeout(ce.autoDropTimer),ce.dragStone!==this&&(this.classList.contains(B)||this===L)){if(ce.targetStone=this,ce.targetStone===L){if(!K(ce.dragStone,ce.targetStone))return ce.clear(),!1;ce.targetStone.appendChild(ce.dragStone)}else if(ce.targetStoneOverLeft){if(!K(ce.dragStone,ce.targetStone))return ce.clear(),!1;ce.targetStone.parentElement.insertBefore(ce.dragStone,ce.targetStone)}else{if(!K(ce.dragStone,ce.targetStone.nextElementSibling))return ce.clear(),!1;ce.targetStone.parentElement.insertBefore(ce.dragStone,ce.targetStone.nextElementSibling)}ce.clear(),e.MutationObserver||!oe&&!se||de()}return!1}};return de=function(){k=Array.prototype.slice.call(L.children);for(var t=0,n=k.length;t<n;t++)k[t].classList.add(B),I&&(k[t].style.zIndex=n-t);if(ie)for(var r=L.getElementsByTagName("img"),o=0,s=r.length;o<s;o++)r[o].naturalWidth||(r[o].removeEventListener("load",l),r[o].addEventListener("load",l),r[o].removeEventListener("error",l),r[o].addEventListener("error",l));for(t=0;t<n;t++)k[t].removeAttribute("draggable"),k[t].removeEventListener("mousedown",ce.mouseDown),k[t].removeEventListener("dragstart",ce.dragStart),k[t].removeEventListener("touchstart",ce.touchStart),k[t].removeEventListener("touchmove",ce.touchMove),k[t].removeEventListener("dragover",ce.dragOver),k[t].removeEventListener("dragleave",ce.dragLeave),k[t].removeEventListener("dragend",ce.dragEnd),k[t].removeEventListener("touchend",ce.touchEnd),k[t].removeEventListener("drop",ce.drop),k[t].removeEventListener("touchend",ce.drop),k[t].removeEventListener("dragenter",ce.dragEnter);if(L.removeEventListener("dragover",ce.dragOver),L.removeEventListener("drop",ce.drop),G){for(t=0;t<n;t++)k[t].classList.contains("flagstone-lock")||(k[t].setAttribute("draggable","true"),k[t].addEventListener("mousedown",ce.mouseDown),k[t].addEventListener("dragstart",ce.dragStart),k[t].addEventListener("touchstart",ce.touchStart),k[t].addEventListener("touchmove",ce.touchMove),k[t].addEventListener("dragover",ce.dragOver),k[t].addEventListener("dragleave",ce.dragLeave),k[t].addEventListener("dragend",ce.dragEnd),k[t].addEventListener("touchend",ce.touchEnd),k[t].addEventListener("drop",ce.drop),k[t].addEventListener("touchend",ce.drop),J&&k[t].addEventListener("dragenter",ce.dragEnter),k[t].getElementsByClassName("flagstone-drag-handle").length||k[t].classList.add("flagstone-drag-handle"));L.addEventListener("dragover",ce.dragOver),L.addEventListener("drop",ce.drop)}(P||N)&&(P&&k.sort(function(){return.5-Math.random()}),N&&a());var i=L.getElementsByClassName("flagstone-remove");for(t=0,n=i.length;t<n;t++)i[t].removeEventListener("click",g),i[t].addEventListener("click",g),i[t].removeEventListener("keydown",g),i[t].addEventListener("keydown",g);for(i=L.getElementsByClassName("flagstone-reset"),t=0,n=i.length;t<n;t++)i[t].removeEventListener("click",d),i[t].addEventListener("click",d),i[t].removeEventListener("keydown",d),i[t].addEventListener("keydown",d);for(i=L.getElementsByClassName("flagstone-resize-height"),t=0,n=i.length;t<n;t++)i[t].removeEventListener("click",m),i[t].addEventListener("click",m),i[t].removeEventListener("keydown",m),i[t].addEventListener("keydown",m);l(),e.setTimeout(function(){l(!0)},W)},function(){if(o(),L.classList.add("flagstone-"+S+"-bed"),!t.getElementById("flagstone-"+S+"-styles")){var n=".flagstone-"+S+"-bed{box-sizing:border-box;list-style-type:none;overflow:hidden;position:relative;min-width:"+(T+2*E)+"px;}",r=".flagstone-"+S+"-bed__stone{box-sizing:border-box;position:absolute;top:0px;"+z+":0px;margin:0;}",a=".flagstone-"+S+"-bed__stone{transition:transform "+H+"s "+R+(F?",width "+H+"s "+R:"")+(_?",height "+X+"s "+j:"")+";}",s=n+r+a,i=t.createElement("style");i.type="text/css",i.id="flagstone-"+S+"-styles",i.appendChild(t.createTextNode(s)),t.head.appendChild(i)}if(de(),e.removeEventListener("resize",f),e.addEventListener("resize",f),e.MutationObserver&&(oe||se)){var l=new e.MutationObserver(v);se&&ie?l.observe(L,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src"]}):l.observe(L,{childList:!0,subtree:se})}}(),{adjust:h,destroy:u,resizeHeight:c,hide:o,reset:f,hardReset:de}}return e.flagstone.index++,new a(n,r)},e.flagstone.index=-1}(window,document);
</script>
@import url('https://fonts.googleapis.com/css?family=Open+Sans');
$white: #fff;
$gray--dark: #5d646e;
$gray: #868080;
$gray--light: #aaa;
$yellow: #ff0;
*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;}
html{background:#777;}
body{font:400 18px/1.4 "Open Sans", sans-serif;margin:0 2vw;background:inherit;min-height:1100px}
h1{margin:10px;padding-top:30px;font-size:48px;color:#aaa;text-shadow:0 0 5px $gray--dark;text-align:center}
h1 a{text-decoration:none;color:inherit;}
.slogan {display:block;font-size:10px;text-shadow: initial;text-transform:uppercase;letter-spacing:8px;text-indent:8px;}
.quick-info {display:block;margin: 10px 0;font-family:sans-serif;font-size:11px;text-shadow:initial;text-align:center;text-transform:uppercase;color:#aaa;}
button{border:none;outline:none;}
p{margin-top:1em;}
.adjust {
position: fixed;
z-index: 100;
top: -290px;
left: 0;
width: 350px;
height: 290px;
border-radius: 0 0 10px 0;
padding: 10px 10px 0 10px;
background-color: $gray--light;
color: $white;
font-size: 12px;
transition: top 0.25s ease;
box-shadow: 4px 4px 4px 0 $gray--dark;
&.active {
top: 0px;
}
.toggle-widget {
padding-top: 10px;
margin-top: 10px;
font-size: 16px;
color: $yellow;
cursor: pointer;
user-select: none;
&:after {
content: "";
display: table;
clear: both;
}
p {
float: left;
margin: 0;
}
button {
float: right;
background: none;
line-height: 1em;
font-size: 18px;
color: inherit;
}
}
table {
table-layout: fixed;
border-collapse: collapse;
}
th {
border-bottom: 1px solid $white;
padding-bottom: 4px;
font-weight: 800;
&:first-of-type {
width: 50%;
}
}
td {
padding-top: 4px;
}
tfoot {
button {
padding: 5px;
background: $yellow;
color: $gray--dark;
cursor: pointer;
&:focus {
box-shadow: 2px 2px 4px 0 #000;
}
}
}
input,
textarea {
color: $gray--dark;
}
textarea {
width: 100%;
height: 33px;
}
}
.add-card {
margin-bottom: 10px;
padding: 5px;
background: $yellow;
color: $gray--dark;
cursor: pointer;
&:focus {
box-shadow: 2px 2px 4px 0 #000;
}
}
article{margin-bottom:100px;background:#aaa;}
article section{overflow-y:auto;padding:15px;background-image:linear-gradient(to bottom right,$gray--dark,$gray);color:#fff;}
img{width:100%;}
iframe{width:100%;height:56.25%;}
.p-animate {
overflow: hidden;
max-height: 40px;
transition: max-height 0.25s ease;
&.active {
max-height: 200px;
& + .show-more {
display: none;
& + .show-less {
display: inline-block;
}
}
}
& + .show-more {
display: inline-block;
& + .show-less {
display: none;
}
}
}
.toggle-more {
padding: 5px;
background: $yellow;
color: $gray--dark;
cursor: pointer;
&:focus {
box-shadow: 2px 2px 4px 0 #000;
}
}
.highlight{
background: $yellow;
color: $gray--dark;
}
.flagstone-remove {
position: absolute;
top: 0;
right: 10px;
margin: 0;
opacity: 0.25;
padding: 0;
background: none;
cursor: pointer;
font-size: 24px;
&:focus,
&:hover {
opacity: 1;
}
}
.flagstone-0-bed.flagstone-dragover {
box-shadow: inset 0 0 4px 4px $yellow;
}
.flagstone-drag {
filter: grayscale(1) blur(4px);
opacity: 0.25;
}
.flagstone-left {
box-shadow: -8px 0 4px -4px $yellow;
}
.flagstone-right {
box-shadow: 8px 0 4px -4px $yellow;
}
// Full documentation: https://github.com/depthdev/flagstonejs
const fs = flagstone(document.getElementsByTagName('article')[0], {
//bedPadding: 10, // The padding around the area edge
//stonesMargin: 10, // Margin between stones in pixels (as an int)
margin: 10, // This overrides bedPadding & stonesMargin and is equivalent to setting them both to this value
minWidth: 280, // Minimum width you want an element to be in pixels (as an int)
maxColumns: 5, // Maximum number of columns to display (as an int)
flow: true, // Allows stone widths to flow during a resize event
direction: 'left', // Alternative is "right"; the default is "left"; and for top to bottom, use CSS's built in Columns or Flexbox
assignReverseZIndexes: false,
random: false, // Display stones in a random order; the default is false (as a boolean)
square: false, // Makes each flagstone square; default is false
space: false, // Spaces out stones randomly (as a boolean)
spaceFrequency: 0.4, // Adjusts the frequency of the amount of spaces (as a float 0.0 - 1.0); default is 0.4
animationDuration: 1000, // Animation duration (milliseconds as an int); default is 0
animationTimingFunction: 'ease', // CSS animation timing function as a string
heightAnimationDuration: 2500,
heightAnimationTimingFunction: 'ease',
resizeDelay: 250, // Delay to run resize/reset function after resizing the window in milliseconds (as an int); default is 250
dragAndDrop: true,
dragAndDropAutoDelay: 1000,
dropCallback: function(dragElem, targetElem) {
// console.log(dragElem);
// console.log(targetElem);
return true;
},
eventResetDelay: 250,
eventResizeHeightDuration: 250,
callback: function(elem, index) { // Warning! This gets called every soft reset, so if you're attaching listeners, you'll need to remove the listeners first!
if (index === 3) {
elem.classList.add('highlight');
} else {
elem.classList.remove('highlight');
}
}, // Callback function for each element with index and element arguments
watch: true,
watchAll: true,
watchImages: true
});
/* DEMO-ONLY FUNCTIONS */
function adjust() {
const $ = function(s){return document.getElementById(s);};
fs.adjust({
//margin: 10,
bedPadding: window.parseInt($('adjust-bed-padding').value,10),
stonesMargin: window.parseInt($('adjust-stones-margin').value,10),
minWidth: window.parseInt($('adjust-min-width').value,10),
maxColumns: window.parseInt($('adjust-max-columns').value,10),
dragAndDrop: $('adjust-drag-and-drop').checked,
dropCallback: window.eval('(' + $('adjust-drop-callback').value + ')'),
callback: window.eval('(' + $('adjust-callback').value + ')')
});
}
function toggleMore(e) {
const p = e.target.parentElement.getElementsByClassName('p-animate')[0];
if (p.classList.contains('active')) {
p.classList.remove('active');
} else {
p.classList.add('active');
}
}
function toggleWidget(e) {
const container = e.currentTarget.parentElement;
if (container.classList.contains('active')) {
container.classList.remove('active');
} else {
container.classList.add('active');
}
}
function addCard() {
const section = document.createElement('section');
section.classList.add('flagstone-drag-handle');
section.innerHTML = '<h2>New Card</h2><button class="flagstone-remove">×</button><p>Lorem ipsum dolor sit amet. Hic cupiditate sapiente placeat temporibus, placeat temporibus, fugiat eos.</p><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit tempora itaque maxime, enim, nam quas nobis voluptate, minus ex adipisci aperiam provident sequi soluta. Praesentium et, placeat porro dolorum voluptate.</p>';
document.getElementsByTagName('article')[0].appendChild(section);
}
Array.prototype.slice.call(document.getElementsByClassName('toggle-more')).forEach(function(e) {
e.addEventListener('click', toggleMore);
});
document.getElementsByClassName('toggle-widget')[0].addEventListener('click', toggleWidget);
document.getElementsByClassName('apply-adjustments')[0].addEventListener('click', adjust);
document.getElementsByClassName('add-card')[0].addEventListener('click', addCard);
window.setTimeout(function() {
document.getElementById('change-my-source').src = 'http://placebear.com/400/400';
}, 3000);
FlagstoneJS v4.0.0
FlagstoneJS 4.0.0Dynamic & responsive tiling
12.5 KB | No dependencies | Loaded with options
| Property | Value |
|---|---|
| margin: | |
| bedPadding: | |
| stonesMargin: | |
| minWidth: | |
| maxColumns: | |
| dragAndDrop: | |
| dropCallback: | |
| callback: | |
| Apply |
Toggle Adjust Widget
⇕
Inject a card
1
×
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.
Show MoreShow Less
2
×
3
×
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
4
×
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Lorem ipsum dolor sit amet hic cupiditate sapiente placeat temporibus.
5
×
Lorem ipsum dolor sit amet. Hic cupiditate sapiente placeat temporibus, placeat temporibus, fugiat eos.
6
×
Lorem ipsum dolor sit amet. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus.
7
×
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus. Accusamus ducimus unde amet quam omnis.
8
×
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus ducimus unde amet quam omnis aliquid aliquam culpa, explicabo ut officia illum doloremque debitis, fugiat eos. Hic cupiditate sapiente placeat temporibus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam quibusdam placeat dolorum natus voluptatum reiciendis cupiditate, cum veritatis accusamus labore consectetur ab amet, sit commodi laudantium beatae molestiae iste repellendus.
9
×
Lorem ipsum dolor sit amet.
10
×
11
×
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus.
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - Responsive 3D Carousel w/ Options (ES6)
<h1>ES6 Version</h1>
<section class="js-carousel1">
<nav><a class="left js-left" href="#"></a><a class="right js-right" href="#"></a></nav>
<ul>
<li><a><img src="https://placeimg.com/256/256/nature/1" alt="" draggable="false"/><span>1</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/2" alt="" draggable="false"/><span>2</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/3" alt="" draggable="false"/><span>3</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/4" alt="" draggable="false"/><span>4</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/5" alt="" draggable="false"/><span>5</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/6" alt="" draggable="false"/><span>6</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/7" alt="" draggable="false"/><span>7</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/8" alt="" draggable="false"/><span>8</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/9" alt="" draggable="false"/><span>9</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/10" alt="" draggable="false"/><span>10</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/11" alt="" draggable="false"/><span>11</span></a></li>
<li><a><img src="https://placeimg.com/256/256/nature/12" alt="" draggable="false"/><span>12</span></a></li>
</ul>
</section>
<input class="js-carousel1__range" type="range" min="0" max="360" value="0"/><div style="position:absolute;z-index:9999;top:0;right:0;display:block;width:100px;height:100px;border-radius:50% 0 50% 50%;padding:2px;color:#fff;box-shadow:inset 0 0 15px 0 #000;background:#333;font-family:'Georgia',sans-serif;font-size:14px;text-align:center;"><p style="margin-top:10px;"><span style="display:block;">On</span><a href="https://github.com/depthdev" target="_blank" style="display:block;color:#08f;">Github</a><span style="display:block;">and</span><a href="http://depthdev.com/" target="_blank" style="color:#08f;">Depth</a></p></div>
::-webkit-scrollbar{width:12px;background:#222;}
::-webkit-scrollbar-track{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.3)}
::-webkit-scrollbar-thumb{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.5)}
*{box-sizing:border-box;margin:0;padding:0;list-style-type:none;font-family:'Georgia', sans-serif;}
html {
background: #222;
&:hover {
nav {
a {
transform:scale(1,1);
}
.left {
left: -15vw;
}
.right {
right: -15vw;
}
}
input {
opacity: 0.25;
transform:scale(1,1);
}
}
body {
margin: 100px 0;
}
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
h1 {
position: absolute;
top: 1vw;
left: 1vw;
font-size: 2vw;
color: #444;
}
section {
position: relative;
width: 50%;
margin: 50px 25%;
margin: 0 auto;
}
nav {
a {
position: absolute;
z-index: 1000;
top: 50%;
text-decoration: none;
color: #444;
text-shadow: 0 0 10px #111;
font-size: 8vw;
line-height: 0;
transition: all 0.25s ease;
transform:scale(0,0);
&:active {
color: #fff;
}
&.left {
left: 0;
&:before {
content: "\3008";
}
}
&.right {
right: 0;
&:before {
content: "\3009";
}
}
}
}
input {
margin-top: 5vw;
width: 50%;
margin-left: 25%;
opacity: 0;
transition: all 0.25s ease;
transform:scale(0,0);
&:hover,
&:active {
opacity: 1;
}
}
ul {
/* border: 1px solid #08f;
border-radius: 50%;*/
li {
a {
position: relative;
display: block;
}
}
img {
width: 100%;
border: 0.75vw solid #000;
box-shadow: 0 20px 10px -10px #111,
0 0 10px 0 #111;
-webkit-filter: brightness(1.125);
-moz-filter: brightness(1.125);
-ms-filter: brightness(1.125);
-o-filter: brightness(1.125);
filter: brightness(1.125);
}
span {
position: absolute;
top: 5%;
right: 10%;
display: inline-block;
font-size: 2vw;
color: rgba(255,255,255,0.5);
text-shadow: 0 0 5px #888;
/* top: 50%;
left: 0;
margin-top: -2vw;
display: block;
width: 100%;
text-align: center;
font-size: 4vw;*/
//color: hsla(0,100%,100%,0.5);
//text-shadow: 0 0 10px #fff;
}
}
/*
Carousel3D v1.1.0
(c) 2015 Depth Development. http://depthdev.com
License: Apache 2.0
*/
'use strict';
// ES5 Version, 2.32KB Minified: function Carousel3D(t){var e=function(t){return document.querySelector(t)},a=function(t){for(var e=document.querySelectorAll(t),a=[],i=0,r=e.length;r>i;i++)a[i]=e[i];return a},i=t.carousel,r=e(i),n=t.items,o=a(n),s=t.itemsPercentOf||.25,l=t.perspective||0===t.perspective?t.perspective:.25,f=t.depth||0===t.depth?1/t.depth:2,h=t.float||"left",c=t.opacity?t.opacity:1,u=t.grayscale?t.grayscale:0,p=t.sepia?t.sepia:0,d=t.blur?t.blur:0,m="",M="",v=0,P=0,y=[],I=0,b=o.length,g=Math.ceil(b/2),x=360/b,w=t.animate||0===t.animate?t.animate:0,z=t.fps||0===t.fps?t.fps:62.5,T=w?w/z:0,k=w?w/T:1,q=0,E=null,L=0,S=function(){q+=L;var t=0>q?360- -1*q%360:q;C(t)},W=function(){setTimeout(function(){E?q>=I?clearTimeout(this):(S(),W()):I>=q?clearTimeout(this):(S(),W())},T)},A=function(t){if(w){var e=t;E=e>I,q=I,I=e,L=(I-q)/k,W()}else C(t)},C=function(t){for(var e=0,a=[];b>e;e++)a[e]=y[e]+t+90;for(e=0;b>e;e++){var i=a[e]*Math.PI/180,r=(y[e]+t)%360*Math.PI/180,n=r<Math.PI?r/Math.PI:(2*Math.PI-r)/Math.PI,s=r>Math.PI?1-(Math.PI-(r-Math.PI))/(Math.PI*f):1-r/(Math.PI*f),l=v*Math.cos(i)+v,h=P*Math.sin(i)+P,I=function(){var a=(y[e]+t+180)%360;return Math.round(a>180?(180-(a-180))/x:a/x)}(),g="position:absolute;z-index:"+I+";left:"+l+"px;top:"+h+"px;"+M+m+"-webkit-transform:scale("+s+","+s+");-moz-transform:scale("+s+","+s+");-ms-transform:scale("+s+","+s+");-o-transform:scale("+s+","+s+");transform:scale("+s+","+s+");",w="opacity:"+(1>c?1-(1-1*c)*n:1)+";",z="grayscale("+(u?1*u*n:0)+")",T="sepia("+(p?1*p*n:0)+")",k="blur("+(d?d*n:0)+"px)",q=w+"-webkit-filter:"+z+" "+T+" "+k+";-moz-filter:"+z+" "+T+" "+k+";-ms-filter:"+z+" "+T+" "+k+";-o-filter:"+z+" "+T+" "+k+";filter:"+z+" "+T+" "+k+";";o[e].style.cssText=g+q}},D=function(){var t=r.offsetWidth,e=t*l;r.style.height=e+"px";var a=o[0].offsetWidth,i=o[0].offsetHeight,n=i/a,f=t*s;m="width:"+f+"px;height:auto;",M="margin:-"+f*n/2+"px auto auto -"+f/2+"px;",v=t/2,P=e/2,y=["left"===h?360:0];for(var c=1;b>c;c++)y.push("left"===h?360-Math.floor(c*x):Math.floor(c*x));C(0)},H=function(){r=e(i),o=a(n),b=o.length,g=Math.ceil(b/2),x=360/b,D()};return function(){r.style.position="relative",D.bind(this)(),window.addEventListener("load",D.bind(this)),window.addEventListener("resize",D.bind(this))}.bind(this)(),{turn:A,reset:H}}
class Carousel3D {
constructor(o) {
// Helpers
const $=function(s){return document.querySelector(s)};
const $$=function(s){let nl=document.querySelectorAll(s),a=[];for(let i=0,l=nl.length;i<l;i++){a[i]=nl[i]}return a};
// General
let carouselStr = o.carousel;
let carousel = $(carouselStr);
let itemsStr = o.items;
let items = $$(itemsStr);
let itemsPercentOf = o.itemsPercentOf || 0.25;
let perspective = o.perspective || o.perspective === 0 ? o.perspective : 0.25;
let depth = o.depth || o.depth === 0 ? 1 / o.depth : 2;
let float = o.float || 'left';
// Filters
let filterOpacity = o.opacity ? o.opacity : 1;
let filterGrayscale = o.grayscale ? o.grayscale : 0;
let filterSepia = o.sepia ? o.sepia : 0;
let filterBlur = o.blur ? o.blur : 0;
// Math Dependencies
let itemWidthAndHeight = '';
let itemMargin = '';
let widthRadius = 0;
let heightRadius = 0;
let degrees = [];
let degree = 0;
let len = items.length;
let half = Math.ceil(len / 2);
let incBy = 360 / len;
// Animation
let animate = o.animate || o.animate === 0 ? o.animate : 0;
let fps = o.fps || o.fps === 0 ? o.fps : 62.5;
let speed = animate ? animate / fps : 0;
let divisions = animate ? animate / speed : 1;
let fromDegree = 0;
let toDegreeHigher = null;
let degreesToAnimateBy = 0;
let turning = function() {
fromDegree += degreesToAnimateBy;
let goToDegree = fromDegree < 0 ? 360 - ((-1 * fromDegree) % 360) : fromDegree;
turn(goToDegree);
};
let animating = function() {
setTimeout(function() {
toDegreeHigher ? fromDegree >= degree ? clearTimeout(this) : (turning(), animating()) : fromDegree <= degree ? clearTimeout(this) : (turning(), animating());
}, speed);
};
// Run
let run = function(extDegree) {
if (animate) {
let turnTo = extDegree;
toDegreeHigher = turnTo > degree;
fromDegree = degree;
degree = turnTo;
degreesToAnimateBy = (degree - fromDegree) / divisions;
animating();
} else {
turn(extDegree);
}
};
// Turn
let turn = function(deg) {
let i = 0;
var d = []; // new degrees array
for (;i<len;i++) {
d[i] = degrees[i] + deg + 90;
}
i = 0;
for (;i<len;i++) {
let r = d[i] * Math.PI / 180;
let rr = ((degrees[i] + deg) % 360) * Math.PI / 180;
let percentAsDecimal = rr < Math.PI ? rr / Math.PI : ((Math.PI * 2) - rr) / Math.PI;
let s = rr > Math.PI ? 1 - ((Math.PI - (rr - Math.PI)) / (Math.PI * depth)) : 1 - (rr / (Math.PI * depth));
let x = widthRadius * Math.cos(r) + widthRadius;
let y = heightRadius * Math.sin(r) + heightRadius;
let z = (function() {
var degreeMod360 = (degrees[i] + deg + 180) % 360;
return Math.round(degreeMod360 > 180 ? (180 - (degreeMod360 - 180)) / incBy : degreeMod360 / incBy);
}());
let p = 'position:absolute;z-index:' + z + ';left:' + x + 'px;top:' + y + 'px;' + itemMargin + itemWidthAndHeight +
'-webkit-transform:scale(' + s + ',' + s + ');' +
'-moz-transform:scale(' + s + ',' + s + ');' +
'-ms-transform:scale(' + s + ',' + s + ');' +
'-o-transform:scale(' + s + ',' + s + ');' +
'transform:scale(' + s + ',' + s + ');';
let fOpacity = 'opacity:' + (filterOpacity < 1 ? 1 - ((1 - (1 * filterOpacity)) * percentAsDecimal) : 1) + ';';
let fGrayscale = 'grayscale(' + (filterGrayscale ? (1 * filterGrayscale) * percentAsDecimal : 0) + ')';
let fSepia = 'sepia('+ (filterSepia ? (1 * filterSepia) * percentAsDecimal : 0) + ')';
let fBlur = 'blur('+ (filterBlur ? (filterBlur * percentAsDecimal) : 0) + 'px)';
let f = fOpacity +
'-webkit-filter:' + fGrayscale + ' ' + fSepia + ' ' + fBlur + ';' +
'-moz-filter:' + fGrayscale + ' ' + fSepia + ' ' + fBlur + ';' +
'-ms-filter:' + fGrayscale + ' ' + fSepia + ' ' + fBlur + ';' +
'-o-filter:' + fGrayscale + ' ' + fSepia + ' ' + fBlur + ';' +
'filter:' + fGrayscale + ' ' + fSepia + ' ' + fBlur + ';';
items[i].style.cssText = p + f;
}
}; // turn
// Reset
let reset = function() {
// Carousel size
let carouselWidth = carousel.offsetWidth;
let carouselHeight = carouselWidth * perspective;
carousel.style.height = carouselHeight + 'px';
// Items size
let aspectPointWidth = items[0].offsetWidth;
let aspectPointHeight = items[0].offsetHeight;
let itemAspectRatio = aspectPointHeight / aspectPointWidth;
let itemWidthNum = carouselWidth * itemsPercentOf;
itemWidthAndHeight = 'width:' + itemWidthNum + 'px;height:auto;';
itemMargin = 'margin:-' + ((itemWidthNum * itemAspectRatio) / 2) + 'px auto auto -' + (itemWidthNum / 2) + 'px;';
// Math
widthRadius = carouselWidth / 2;
heightRadius = carouselHeight / 2;
degrees = [float === 'left' ? 360 : 0]; // Reset degrees and first elem
for (let i=1;i<len;i++) {
degrees.push(float === 'left' ? 360 - Math.floor(i * incBy) : Math.floor(i * incBy));
}
// Position the items
turn(0);
};
// Hard reset
let hardReset = function() {
carousel = $(carouselStr);
items = $$(itemsStr);
len = items.length;
half = Math.ceil(len / 2);
incBy = 360 / len;
reset();
};
// Init
(function() {
carousel.style.position = 'relative';
reset.bind(this)();
window.addEventListener('load', reset.bind(this));
window.addEventListener('resize',reset.bind(this));
}.bind(this))()
// Dev API
return {
turn: run,
reset: hardReset
}
} // constructor
} // Carousel3D
////////////////////////////
// USE
////////////////////////////
/*
NOTE: The API only provides one method called "turn". For a small footprint, it's up to the developer to use the turn method in association with any features he/she wants; such as: click navigating, slider navigation, keyboard navigating, swiping, spinning with an ease, etc.
*/
var dev = {};
// CAROUSEL 1
dev.c1 = new Carousel3D({
carousel: '.js-carousel1 ul', // Required. Container for elements; as selector string
items: '.js-carousel1 li', // Required. Elements to move around; as selector string
itemsPercentOf: 0.25, // Optional. Percent of items width, relative to the carousel's width
perspective: 0.25, // Optional. Percent relative to the width; as a decimal
depth: 0.5, // Optional. Viewing depth percent; as a decimal
float: 'left', // Optional internationalization ordering. "Float" items to the 'left' or 'right'
animate: 250, // Optional. Animation duration in milleconds; as an int
fps: 60, // Optional. Frames Per Second; as an int
opacity: 0.125, // Optional. Opacity percent; as a decimal
//grayscale: 1, // Optional. Grayscale percent; as a decimal
//sepia: 1, // Optional. Sepia percent; as a decimal
blur: 10 // Optional. Blur in pixels; as a number
});
/////////////////////
// CUSTOM DEV STUFF
/////////////////////
let $=function(s){let nl=document.querySelectorAll(s),a=[];for(let i=0,l=nl.length;i<l;i++){a[i]=nl[i]}return a.length>1?a:a[0]};
dev.degree = 0;
dev.incrementBy = 360 / $('.js-carousel1 li').length;
// Left Arrow
$('.js-carousel1 .js-left').addEventListener('click', function() {
dev.degree -= dev.incrementBy;
dev.c1.turn(dev.degree);
});
// Right Arrow
$('.js-carousel1 .js-right').addEventListener('click', function() {
dev.degree += dev.incrementBy;
dev.c1.turn(dev.degree);
});
// Range Input
$('.js-carousel1__range').addEventListener('input', function(e) {
dev.c1.turn(parseInt(this.value,10));
}, true);
// Keyboard Navigation
window.addEventListener('keydown', function(e) {
if (e.keyCode === 37) {
dev.degree -= dev.incrementBy;
dev.c1.turn(dev.degree);
} else if (e.keyCode === 39) {
dev.degree += dev.incrementBy;
dev.c1.turn(dev.degree);
}
});
// Inject an item and then reset
/*
setTimeout(function() {
var li = document.createElement('li');
var a = document.createElement('a');
var img = document.createElement('img');
img.src = 'http://placebear.com/300/200';
var span = document.createElement('span');
span.textContent = $('.js-carousel1 li').length + 1;
a.appendChild(img);
a.appendChild(span);
li.appendChild(a);
$('section.js-carousel1 ul').appendChild(li);
dev.c1.reset();
}, 5000);
*/
// Click-item navigation
(function() {
let items = $('.js-carousel1 li');
for(let i=0,l=items.length;i<l;i++){
items[i].addEventListener('click', function(e) {
let elem = e.target;
while(elem.nodeName.toLowerCase() !== 'li') {
elem = elem.parentNode;
}
let index = 0;
while(elem.previousSibling) {
if (elem.previousSibling.nodeName.toLowerCase() === 'li') {
index++;
}
elem = elem.previousSibling;
}
dev.degree = 360 / (items.length / index);
dev.c1.turn(dev.degree);
});
}
}());
// Mouse wheel
window.addEventListener('wheel', function(e) {
dev.degree = e.wheelDeltaY < 0 ? dev.degree + dev.incrementBy : dev.degree - dev.incrementBy;
dev.c1.turn(dev.degree);
});
// Mouse swipe
var swipeInstance = new MouseSwipe({
area: document.querySelector('.js-carousel1'),
//change: function(){},
move: function(obj) {
var isSwipe = swipeInstance.swipe();
if (isSwipe === 'left') {
dev.degree += 1.5;
dev.c1.turn(dev.degree);
} else if (isSwipe === 'right') {
dev.degree -= 1.5;
dev.c1.turn(dev.degree);
} else {
console.log(isSwipe);
}
},
moving: function(obj) {
},
//down: function(){},
//up: function(obj){},
swipe: 4
});
/*
MouseSwipe v0.3.0
(c) 2015 Clearwave Designs, LLC. http://clearwavedesigns.com
License: Apache 2.0
*/
function MouseSwipe(e){var t={ms:0,x:0,y:0},a={ms:0,x:0,y:0},f=e.swipe,n=!1,o=function(a){t.ms=a.timeStamp,t.x=a.clientX-e.area.offsetLeft,t.x=t.x<0?0:t.x>e.area.offsetWidth?e.area.offsetWidth:t.x,t.y=event.clientY-e.area.offsetTop,t.y=t.y<0?0:t.y>e.area.offsetHeight?e.area.offsetHeight:t.y},i=function(t){a.ms=t.timeStamp,a.x=t.clientX-e.area.offsetLeft,a.x=a.x<0?0:a.x>e.area.offsetWidth?e.area.offsetWidth:a.x,a.y=event.clientY-e.area.offsetTop,a.y=a.y<0?0:a.y>e.area.offsetHeight?e.area.offsetHeight:a.y,e.change&&e.change(m())},s=function(f){var o=event.clientX-e.area.offsetLeft,i=event.clientY-e.area.offsetTop;a.ms=f.timeStamp,a.x=o,a.y=i,e.move&&n&&e.move({ms:f.timeStamp-t.ms,x:(0>o?0:o>e.area.offsetWidth?e.area.offsetWidth:o)-t.x,y:(0>i?0:i>e.area.offsetHeight?e.area.offsetHeight:i)-t.y}),e.moving&&e.moving({ms:f.timeStamp,x:0>o?0:o>e.area.offsetWidth?e.area.offsetWidth:o,y:0>i?0:i>e.area.offsetHeight?e.area.offsetHeight:i})},r=function(){if(f){var e=m(),t=Math.abs(e.x),a=Math.abs(e.y);return t/f>a?e.x>0?"right":"left":a/f>t?e.y>0?"down":"up":!1}},m=function(){return{ms:a.ms-t.ms,x:a.x-t.x,y:a.y-t.y}};return function(){e.area.addEventListener("mouseenter",function(){n=!1}),(e.change||e.move)&&(e.area.addEventListener("mousedown",function(t){n=!0,o(t),e.down&&e.down()},!1),e.area.addEventListener("mouseup",function(t){n=!1,i(t),e.up&&e.up()},!1)),(e.move||e.moving)&&e.area.addEventListener("mousemove",s,!1)}.bind(this)(),{swipe:r}}
Responsive 3D Carousel w/ Options (ES6)
ES6 Version
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - mENWYX
<h1>ScrollbarReloaded Demo</h1>
<div>
<article class="example" scrollbar-reloaded="slave-bird">
<header>
<h1>The Title</h1>
</header>
<section class="js-inject-more-here">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
</section>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<div style="width:161%;padding:1em;background:#FFFF00;">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente mollitia voluptate consequatur laborum autem rerum, sit itaque necessitatibus quibusdam tenetur. Qui et ducimus iure officiis omnis! Ullam nemo hic iusto.</p>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
</section>
<footer>
<p>Resources:</p>
<ul>
<li>Odio sint</li>
<li>Earum nobis sapiente</li>
</ul>
</footer>
</article>
</div>
<div>
<article class="example" scrollbar-reloaded="slave-bird">
<header>
<h1>The Title</h1>
</header>
<section>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<div style="width:200px;height:600px;padding:1em;background:#FFFF00;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur maxime, vitae quod dolore. Unde, a beatae blanditiis eos laboriosam. Cumque necessitatibus explicabo eos harum reprehenderit repellat deleniti, enim quas, officia.</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.</p>
</section>
<section class="js-inject-more-here1">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.</p>
</section>
<footer>
<p>Resources:</p>
<ul>
<li>Odio sint</li>
<li>Earum nobis sapiente</li>
</ul>
</footer>
</article>
</div>
<div style="float:left;margin-left:calc(5% - 25px);height:300px;" scrollbar-reloaded="master-bird" scrollbar-reloaded-x="false"></div>
<script>
// Download the plugin here: https://github.com/depthdev/ScrollbarReloaded
/*
ScrollbarReloaded v1.0.0
(c) 2016 Depth Development. http://depthdev.com
License: MIT
*/
!function(t){"use strict";return!t.ScrollbarReloaded&&void(t.ScrollbarReloaded=function(e){function a(e,a){function s(){}function r(){o(),u(),h.styles.left=-(h.styles.widthAvailable*h.x.scrollPercent),h.content.style.left=h.styles.left+"px",h.styles.top=-(h.styles.heightAvailable*h.y.scrollPercent),h.content.style.top=h.styles.top+"px",h.x.train.style.left=h.styles.width*h.x.scrollPercent-h.x.trainWidth*h.x.scrollPercent+"px",h.y.train.style.top=h.styles.height*h.y.scrollPercent-h.y.trainHeight*h.y.scrollPercent+"px",h.x.ignore="false"===h.instance.getAttribute("scrollbar-reloaded-x"),h.y.ignore="false"===h.instance.getAttribute("scrollbar-reloaded-y")}function i(){clearTimeout(h.resize),h.resize=setTimeout(r,d)}function l(t,e){h.styles.left+=t,h.styles.left=h.styles.left<-h.styles.widthAvailable?-h.styles.widthAvailable:h.styles.left>0?0:h.styles.left,h.x.scrollPercent=h.styles.left/-h.styles.widthAvailable,h.styles.top+=e,h.styles.top=h.styles.top<-h.styles.heightAvailable?-h.styles.heightAvailable:h.styles.top>0?0:h.styles.top,h.y.scrollPercent=h.styles.top/-h.styles.heightAvailable,h.scroll(h.x.ignore?0:h.styles.left,h.y.ignore?0:h.styles.top);var a=1-(h.styles.widthAvailable+h.styles.left)/h.styles.widthAvailable,s=h.styles.width*a,r=h.x.trainWidth*a;h.x.train.style.left=s-r+"px";var i=1-(h.styles.heightAvailable+h.styles.top)/h.styles.heightAvailable,l=h.styles.height*i,o=h.y.trainHeight*i;if(h.y.train.style.top=l-o+"px",h.master)for(var c=0,p=n[h.master].length;c<p;c++)n[h.master][c].update(h.x.scrollPercent||0,h.y.scrollPercent||0)}function o(){h.styles.height=h.instance.offsetHeight,h.styles.heightScroll=h.instance.scrollHeight,h.styles.heightAvailable=h.styles.heightScroll-h.styles.height,h.styles.heightMultiplier=h.styles.heightScroll/h.styles.height,h.styles.width=h.instance.offsetWidth,h.styles.widthScroll=h.instance.scrollWidth,h.styles.widthAvailable=h.styles.widthScroll-h.styles.width,h.styles.widthMultiplier=h.styles.widthScroll/h.styles.width}function c(){h.instance.addEventListener("wheel",function(t){t.preventDefault(),t.stopPropagation(),t.wheelDeltaX||t.wheelDeltaY?l(t.wheelDeltaX,t.wheelDeltaY):l(t.deltaMode?16*-t.deltaX:-t.deltaX,t.deltaMode?16*-t.deltaY:-t.deltaY)}),h.x.train.addEventListener("mousedown",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageXRange=[-t.target.offsetLeft+t.pageX,h.styles.width-t.target.offsetLeft+t.pageX-h.x.trainWidth],h.mouse.pageX=t.pageX,h.mouse.dirX=!0,h.x.track.style.opacity=1,h.x.track.setAttribute("scrollbar-reloaded-x-track","active"),h.y.track.style.opacity=0}),h.y.train.addEventListener("mousedown",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageYRange=[-t.target.offsetTop+t.pageY,h.styles.height-t.target.offsetTop+t.pageY-h.y.trainHeight],h.mouse.pageY=t.pageY,h.mouse.dirY=!0,h.x.track.style.opacity=0,h.y.track.style.opacity=1,h.y.track.setAttribute("scrollbar-reloaded-y-track","active")}),f.mousemove=function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageX?(l(h.mouse.dirX&&t.pageX>=h.mouse.pageXRange[0]&&t.pageX<=h.mouse.pageXRange[1]?(h.mouse.pageX-t.pageX)*h.styles.widthMultiplier:t.pageX<h.mouse.pageXRange[0]?-h.styles.left:-(h.styles.widthAvailable+h.styles.left),0),h.mouse.pageX=t.pageX):h.mouse.pageY&&(l(0,h.mouse.dirY&&t.pageY>=h.mouse.pageYRange[0]&&t.pageY<=h.mouse.pageYRange[1]?(h.mouse.pageY-t.pageY)*h.styles.heightMultiplier:t.pageY<h.mouse.pageYRange[0]?-h.styles.top:-(h.styles.heightAvailable+h.styles.top)),h.mouse.pageY=t.pageY)},document.addEventListener("mousemove",f.mousemove),f.mouseup=function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageX=0,h.mouse.pageY=0,h.mouse.dirX=!1,h.mouse.dirY=!1,h.x.track.style.removeProperty("opacity"),h.y.track.style.removeProperty("opacity"),h.x.track.setAttribute("scrollbar-reloaded-x-track",""),h.y.track.setAttribute("scrollbar-reloaded-y-track","")},document.addEventListener("mouseup",f.mouseup),h.x.train.addEventListener("touchstart",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageXRange=[-t.target.offsetLeft+t.touches[0].pageX,h.styles.width-t.target.offsetLeft+t.touches[0].pageX-h.x.trainWidth],h.mouse.pageX=t.touches[0].pageX,h.mouse.dirX=!0,h.x.track.style.opacity=1,h.x.track.setAttribute("scrollbar-reloaded-x-track","active"),h.y.track.style.opacity=0}),h.y.train.addEventListener("touchstart",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageYRange=[-t.target.offsetTop+t.touches[0].pageY,h.styles.height-t.target.offsetTop+t.touches[0].pageY-h.y.trainHeight],h.mouse.pageY=t.touches[0].pageY,h.mouse.dirY=!0,h.x.track.style.opacity=0,h.y.track.style.opacity=1,h.y.track.setAttribute("scrollbar-reloaded-y-track","active")}),h.content.addEventListener("touchstart",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageX=t.touches[0].pageX,h.mouse.pageY=t.touches[0].pageY,h.mouse.dirX=!0,h.mouse.dirY=!0,h.x.track.style.opacity=1,h.y.track.style.opacity=1}),h.x.train.addEventListener("touchmove",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageX&&(l((h.mouse.pageX-t.touches[0].pageX)*h.styles.widthMultiplier,0),h.mouse.pageX=t.touches[0].pageX)}),h.y.train.addEventListener("touchmove",function(t){t.preventDefault(),t.stopPropagation(),h.mouse.pageY&&(l(0,(h.mouse.pageY-t.touches[0].pageY)*h.styles.heightMultiplier),h.mouse.pageY=t.touches[0].pageY)}),h.content.addEventListener("touchmove",function(t){t.preventDefault(),t.stopPropagation(),(h.mouse.pageX||h.mouse.pageY)&&(l(t.touches[0].pageX-h.mouse.pageX,t.touches[0].pageY-h.mouse.pageY),h.mouse.pageX=t.touches[0].pageX,h.mouse.pageY=t.touches[0].pageY)}),h.x.train.addEventListener("touchend",function(t){t.preventDefault(),t.stopPropagation(),h.x.track.setAttribute("scrollbar-reloaded-x-track",""),h.y.track.setAttribute("scrollbar-reloaded-y-track","")}),h.y.train.addEventListener("touchend",function(t){t.preventDefault(),t.stopPropagation(),h.x.track.setAttribute("scrollbar-reloaded-x-track",""),h.y.track.setAttribute("scrollbar-reloaded-y-track","")}),h.x.rail.addEventListener("mouseover",function(t){t.preventDefault(),t.stopPropagation(),h.y.track.setAttribute(y+"y-track","hide")}),h.x.rail.addEventListener("mouseleave",function(t){t.preventDefault(),t.stopPropagation(),h.y.track.setAttribute(y+"y-track","")}),h.y.rail.addEventListener("mouseover",function(t){t.preventDefault(),t.stopPropagation(),h.x.track.setAttribute(y+"x-track","hide")}),h.y.rail.addEventListener("mouseleave",function(t){t.preventDefault(),t.stopPropagation(),h.x.track.setAttribute(y+"x-track","")}),h.x.rail.addEventListener("click",function(e){if(e.preventDefault(),e.stopPropagation(),e.target===h.x.rail){var a=e.offsetX<t.getComputedStyle(h.x.train,null).getPropertyValue("left").replace(/px/,"")?h.styles.height-20:-h.styles.height+20;l(a,0)}}),h.y.rail.addEventListener("click",function(e){if(e.preventDefault(),e.stopPropagation(),e.target===h.y.rail){var a=e.offsetY<t.getComputedStyle(h.y.train,null).getPropertyValue("top").replace(/px/,"")?h.styles.height-20:-h.styles.height+20;l(0,a)}}),t.addEventListener("resize",i)}function u(){h.x.trainWidth=h.styles.width*(h.styles.width/h.styles.widthScroll),h.x.trainWidth=h.x.trainWidth<h.trainMinLength?h.trainMinLength:h.x.trainWidth,h.x.trainWidth>=h.styles.width?(h.instance.overflowX="auto",h.x.track.style.display="none"):(h.x.track.style.display="block",h.x.train.style.width=h.x.trainWidth+"px"),h.y.trainHeight=h.styles.height*(h.styles.height/h.styles.heightScroll),h.y.trainHeight=h.y.trainHeight<h.trainMinLength?h.trainMinLength:h.y.trainHeight,h.y.trainHeight>=h.styles.height?(h.instance.overflowY="auto",h.y.track.style.display="none"):(h.y.track.style.display="block",h.y.train.style.height=h.y.trainHeight+"px")}function g(t,e){l(t*-h.styles.widthAvailable-h.styles.left,e*-h.styles.heightAvailable-h.styles.top)}var h={content:void 0,instance:e,master:a,mouse:{dirX:!1,dirY:!1,pageX:0,pageXRange:[0,0],pageY:0,pageYRange:[0,0]},resize:void 0,scroll:function(){},styles:{height:0,heightScroll:0,heightAvailable:0,heightMultiplier:0,width:0,widthScroll:0,widthAvailable:0,widthMultiplier:0,top:0,left:0},trainMinLength:p,x:{ignore:!1,rail:void 0,scrollPercent:0,track:void 0,train:void 0,trainWidth:0},y:{ignore:!1,rail:void 0,scrollPercent:0,track:void 0,train:void 0,trainHeight:0}},f={};return function(){for(h.content=document.createElement("DIV"),h.content.setAttribute(y+"content","");h.instance.firstChild;)h.content.appendChild(h.instance.firstChild);h.instance.appendChild(h.content),h.x.track=document.createElement("DIV"),h.x.track.setAttribute(y+"x-track",""),h.x.rail=document.createElement("DIV"),h.x.rail.setAttribute(y+"x-rail",""),h.x.train=document.createElement("DIV"),h.x.train.setAttribute(y+"x-train",""),h.x.rail.appendChild(h.x.train),h.x.track.appendChild(h.x.rail),h.instance.appendChild(h.x.track),h.y.track=document.createElement("DIV"),h.y.track.setAttribute(y+"y-track",""),h.y.rail=document.createElement("DIV"),h.y.rail.setAttribute(y+"y-rail",""),h.y.train=document.createElement("DIV"),h.y.train.setAttribute(y+"y-train",""),h.y.rail.appendChild(h.y.train),h.y.track.appendChild(h.y.rail),h.instance.appendChild(h.y.track),function(){var t=h.instance.getAttribute("scrollbar-reloaded-type");"scroll"===t?h.scroll=function(t,e){h.instance.scrollLeft=-t,h.instance.scrollTop=-e,h.instance.style.position="static",h.instance.parentElement.style.position="relative"}:"margin"===t?h.scroll=function(t,e){h.content.style.marginLeft=t+"px",h.content.style.marginTop=e+"px"}:(h.scroll=function(t,e){h.content.style.left=t+"px",h.content.style.top=e+"px"},h.content.style.position="relative")}(),c(),s=function(){t.removeEventListener("resize",i),document.removeEventListener("mousemove",f.mousemove),document.removeEventListener("mouseup",f.mouseup)},h.instance.setAttribute(y+"bootstrapped","true"),setTimeout(r,17)}(),{destroy:s,reset:r,update:g}}function s(t,e,a){for(var s in n)for(var r=0,i=n[s].length;r<i;r++)n[s][r][t](e,a)}function r(){Array.prototype.slice.call(document.querySelectorAll("["+u+"]:not(["+y+"bootstrapped])")).forEach(function(t){var e=t.getAttribute("scrollbar-reloaded");if(e.length){var s=e.replace(/[^\-]+\-/,"");n[s]||(n[s]=[]),/master/.test(e)?n["default"].push(new a(t,s)):n[s].push(new a(t))}else n["default"].push(new a(t))})}function i(){s("destroy")}function l(){s("reset")}function o(t,e){s("update",t,e)}var n={"default":[]},c=e||{},p=c.minHandleLength||10,u="scrollbar-reloaded",y=u+"-",d=c.resizeDelay||17;return{bootstrap:r,bootstrapped:n,destroy:i,reset:l,update:o}})}(window);
</script>
*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;}
body {
font:400 16px/1.4 'Georgia',sans-serif;
margin: 2.5% 5%;
& > div {
&:first-of-type,
&:nth-of-type(2) {
float: left;
display: inline-block;
width: 45%;
&:first-of-type {
margin-right: 5%;
}
}
}
}
.example {
max-height: 300px;
padding: 10px;
background-color: #f0f0f0;
p { margin-top: 1em; }
}
/*
ScrollbarReloaded v1.0.0
(c) 2016 Depth Development. http://depthdev.com
License: MIT
*/
[scrollbar-reloaded]{position:relative;overflow:hidden}[scrollbar-reloaded]:hover [scrollbar-reloaded-x-track],[scrollbar-reloaded]:hover [scrollbar-reloaded-y-track]{opacity:1}[scrollbar-reloaded][scrollbar-reloaded-x="false"] [scrollbar-reloaded-x-track]{opacity:0 !important}[scrollbar-reloaded][scrollbar-reloaded-y="false"] [scrollbar-reloaded-y-track]{opacity:0 !important}[scrollbar-reloaded^="master"]{width:25px}[scrollbar-reloaded^="master"] [scrollbar-reloaded-content]{height:200%}[scrollbar-reloaded^="master"] [scrollbar-reloaded-x-track],[scrollbar-reloaded^="master"] [scrollbar-reloaded-y-track]{opacity:1 !important}[scrollbar-reloaded-content]{width:100%}[scrollbar-reloaded-x-track],[scrollbar-reloaded-y-track]{position:absolute;z-index:1;width:100%;height:100%;opacity:0;border-radius:5px}[scrollbar-reloaded-x-track="hide"],[scrollbar-reloaded-y-track="hide"]{opacity:0 !important}[scrollbar-reloaded-x-rail],[scrollbar-reloaded-y-rail]{position:relative;width:inherit;height:inherit;border-radius:inherit;box-shadow:inset 0 0 6px 0 rgba(0,0,0,0.25)}[scrollbar-reloaded-x-train],[scrollbar-reloaded-y-train]{position:absolute;top:0;left:0;width:inherit;height:inherit;border-radius:inherit;background:rgba(0,0,0,0.125);box-shadow:inherit;cursor:pointer}[scrollbar-reloaded-x-track]{bottom:0;left:0;height:10px;transition:height 0.125s linear, opacity 0.25s linear}[scrollbar-reloaded-x-track]:before{content:"";display:inline-block;position:absolute;z-index:-1;top:-6px;left:0;width:inherit;height:inherit;transition:top 0.125s linear}[scrollbar-reloaded-x-track]:hover,[scrollbar-reloaded-x-track][scrollbar-reloaded-x-track="active"]{height:16px;border-radius:8px}[scrollbar-reloaded-x-track]:hover:before,[scrollbar-reloaded-x-track][scrollbar-reloaded-x-track="active"]:before{top:0}[scrollbar-reloaded-y-track]{top:0;right:0;width:10px;transition:width 0.125s linear, opacity 0.25s linear}[scrollbar-reloaded-y-track]:before{content:"";display:inline-block;position:absolute;z-index:-1;top:0;left:-6px;width:inherit;height:inherit;transition:left 0.25s linear}[scrollbar-reloaded-y-track]:hover,[scrollbar-reloaded-y-track][scrollbar-reloaded-y-track="active"]{width:16px;border-radius:8px}[scrollbar-reloaded-y-track]:hover:before,[scrollbar-reloaded-y-track][scrollbar-reloaded-y-track="active"]:before{left:0}
const scrollbarReloaded = new ScrollbarReloaded({
minHandleLength: 4,
resizeDelay: 250
});
scrollbarReloaded.bootstrap();
CodePen - A Pen by Adam
ScrollbarReloaded Demo
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est, aut suscipit neque aperiam nobis saepe recusandae. Nobis, aspernatur, et reprehenderit tenetur, sed recusandae sint velit impedit nulla incidunt tempora blanditiis.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit esse aliquam delectus non explicabo. Beatae quas quibusdam, odio sint, asperiores illum quam earum nobis sapiente, accusamus harum excepturi molestiae fuga.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente mollitia voluptate consequatur laborum autem rerum, sit itaque necessitatibus quibusdam tenetur. Qui et ducimus iure officiis omnis! Ullam nemo hic iusto.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur maxime, vitae quod dolore. Unde, a beatae blanditiis eos laboriosam. Cumque necessitatibus explicabo eos harum reprehenderit repellat deleniti, enim quas, officia.
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - Image, Iframe & Script Lazy-loader (v1.3.1)
article
header
h1 Image, Iframe & Script
span Lazy-loader
p
| v1.3.1 |
span 1.08 KB.
span No dependencies.
| Preloading. Custom attribute/source reference.
section
h2 Scroll down for an example
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
img(data-src="http://placebear.com/300/200", alt="")
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
section
h2 Are you watching your network tab?
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
img(data-src="http://placebear.com/g/200/300", alt="")
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
section
h2 Two images side-by-side load at the same time
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
img(data-src="http://placebear.com/600/400", alt="")
img(data-src="http://placebear.com/103/358", alt="")
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
section
h2 Here's an image and script (don't worry, it's just jQuery)
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
img(data-src="http://placebear.com/100/300", alt="")
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
script(data-src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js")
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
section
h2 Before the iframe, another image
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
img(data-src="http://placebear.com/g/150/200", alt="")
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
section
h2 Iframe, hooray! (and an image at the very end)
iframe(data-src="https://www.youtube.com/embed/UPgV8X1sJxo?enablejsapi=1&autoplay=1;autohide=1&color=white&controls=1&playsinline=1&rel=0&showinfo=0&theme=light&wmode=transparent", width="1920", height="1080", allowfullscreen)
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
img(data-src="http://placebear.com/g/800/800", alt="")
::-webkit-scrollbar{width:12px;background:#222;} ::-webkit-scrollbar-track{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.3)} ::-webkit-scrollbar-thumb{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.5)} ,:before,*:after{box-sizing:border-box;margin:0;padding:0;} body{max-width:960px;margin:0 auto;padding:0 40px;font:400 18px/1.4 'Georgia',sans-serif;} h1{margin-top:60px; span{ &:nth-of-type(1){display:block;font-size:52px;} &:nth-of-type(2){display:block;font-size:52px;} } &+p{ span { &:nth-of-type(1){color:#f08;} &:nth-of-type(2){color:#80f;} } }} p{margin-top:20px;} section{margin-top:60px;} section:after{content:"";display:table;clear:both;} img{float:left;margin:20px 20px 20px 0;box-shadow:5px 5px 5px 0 #ccc;} iframe{width:960px;height:540px;border:none;box-shadow:5px 5px 5px 0 #ccc;}
/* Lazyload v1.3.0 (c) 2015 Depth Development. http://depthdev.com License: Apache 2.0 */
new Lazyload({ attr: 'data-src', // Required. Full attribute name. This doubles as the selector AND source for the src attribute. preload: 500 // Required. The distance in pixels from the bottom of the viewport to start loading the next elements src. });
// 0.85 KB minified: function Lazyload(t){var n=function(){for(var n=[],e=document.querySelectorAll("["+t.attr+"]"),o=0,r=e.length;r>o;o++)n[o]=e[o];return n}(),e=innerHeight,o=!1,r=function(){for(var e=0,o=i.length;o>e;e++)n[0].setAttribute("src",n[0].getAttribute(t.attr)),n.shift();d()},i=[],f=function(t){for(var n=t,e=0;n;)e+=n.offsetTop,n=n.offsetParent;return e},d=function(){i=[];for(var t=0,e=n.length;e>t;t++)if(i[t]=f(n[t]),t>0&&i[t]>i[t-1]){i.pop();break}o=!1};(function(){d(),addEventListener("scroll",function(){!o&&i[0]<e+t.preload+document.body.scrollTop&&(o=!0,r())}.bind(this)),addEventListener("load",function(){setTimeout(function(){for(var o=e+t.preload+document.body.scrollTop,d=0,a=n.length;a>d;d++)if(i[d]=f(n[d]),i[d]>o){i.pop();break}r()}.bind(this),0)}.bind(this)),addEventListener("resize",function(){e=innerHeight}.bind(this))}).bind(this)()}
// a = array // d = distances (from top) // e = elements // g = grandparent (parent element) // n = node list // o = options object // p = pause // r = reset // s = set // t = top // v = viewport height
'use strict';
function Lazyload(o) { // Elems (img,iframe,script) var e = (function () { var a = [], n = document.querySelectorAll('[' + o.attr + ']'), i = 0, l = n.length;for (; i < l; i++) { a[i] = n[i]; }return a; }()); // Viewport Height var v = innerHeight; // Pause var p = false; // Set var s = function() { for (var i = 0, l = d.length; i < l; i++) { e[0].setAttribute('src', e[0].getAttribute(o.attr)); e.shift(); // Remove t image from the array } r(); }; // Distances var d = []; // Top var t = function(e) { var g = e, c = 0; while (g) { c += g.offsetTop; g = g.offsetParent; } return c; }; // Reset var r = function() { d = []; // Reset distances for next set of images for (var i = 0, l = e.length; i < l; i++) { // Parent Element (starting off with current element) d[i] = t(e[i]); // Remove element if farther down the page and not side-by-side and exit if (i > 0 && d[i] > d[i - 1]) { d.pop(); break; } } p = false; }; // Init (function () { r(); addEventListener('scroll', function () { if (!p && d[0] < v + o.preload + (document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop)) { p = true; s(); } }.bind(this)); addEventListener('load', function() { // setTimeout is used because (document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop) is inaccurate onload setTimeout(function() { var scrolled = v + o.preload + (document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop); for (var i = 0, l = e.length; i < l; i++) { d[i] = t(e[i]); if (d[i] > scrolled) { d.pop(); break; } } s(); }.bind(this), 0); }.bind(this)); addEventListener('resize', function () { v = innerHeight; }.bind(this)); }.bind(this)()); } // LAZYLOAD
Image, Iframe & Script Lazy-loader (v1.3.1)
## Scroll down for an example
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus obcaecati distinctio, recusandae inventore beatae maiores architecto enim itaque fuga amet. Recusandae enim quas, facere maiores nihil eaque deserunt saepe. Autem.
## Are you watching your network tab?
## Two images side-by-side load at the same time
## Here's an image and script (don't worry, it's just jQuery)
## Before the iframe, another image
## Iframe, hooray! (and an image at the very end)
On [Github](https://github.com/depthdev) and [Depth](/content/site-root.html)
This Pen is owned by [Adam](https://codepen.io/depthdev) on [CodePen](https://codepen.io/).
[See more by @depthdev on CodePen](https://codepen.io/depthdev)
### External CSS
This Pen doesn't use any external CSS resources.
### External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - FlexFileJS
FlexFileJS
Flexible browser file uploader
This example uses image uploading.
*{box-sizing:border-box;margin:0;padding:0;font-family:'Georgia',sans-serif;}
html{color:#444;}
#completed-message{display:none;padding:10px;background:#0c0;color:#fff;text-align:center;animation:fade 4s infinite;}
h1{margin-top:25px;text-align:center;}
h2{text-align:center;}
p{margin:10px 0;text-align:center;}
form{padding:10px;background:#444;color:#fff;}
form.active{background:#c00;}
input[type="button"]{width:50px;height:50px;border-radius:50%;border:1px solid #fff;padding:3px 5px;background:#c00;background-image:radial-gradient(circle,#f00,#800);color:#fff;font-size:10px;text-transform:uppercase;cursor:pointer;}
@keyframes fade{0%{background: #0c0;}50%{background:#06c;}}
#drag-and-drop-area{position:relative;min-height:300px;cursor:move;}
#drag-and-drop-area:before{content:"Choose files above OR drag and drop images here.";position:absolute;z-index:-1;top:45%;left:0;display:block;width:100%;text-align:center;color:#444;}
img{width:20%;}
/*
FlexFile v1.0.0
(c) 2015 Depth Development. http://depthdev.com
License: Apache 2.0
*/
'use strict';
function FlexFile(o) {
var $ = function(s) {
return document.querySelector(s);
};
// SCOPED VARIABLES
var _files = []; // This is where all processed file data will be stored
var _rawFiles = [];
var _reader = new FileReader();
var _totalFiles = 0;
var _totalFilesCompleted = 0;
var _readAs = o.readAs || 'DataURL';
var _multiple = o.multiple === false ? false : true;
// SELECTORS PROVIDED?
if (!o.dropListener && !o.fileListener) {
throw 'ERROR: No "fileListener" and/or "dropListener" property provided for FlexFile.';
}
// CALLBACKS
var _callbackAbort = function() {
if (o.abort) { o.abort(); }
if (o.fileListener) { $(o.fileListener).value = null; }
};
var _callbackComplete = function() {
if (o.complete) {
o.complete(_multiple ? _files : _files[0], _multiple ? _rawFiles : _rawFiles[0], _totalFilesCompleted, _totalFiles);
}
};
var _callbackStatus = function() {
_totalFilesCompleted++;
if (o.status) {
o.status(_totalFilesCompleted, _totalFiles);
}
if (_totalFilesCompleted !== _totalFiles) {
_queue();
} else {
_callbackComplete();
}
};
var _callbackError = function(e) {
if (e.target.error) {
if (o.error) {
o.error(e.target.error);
}
}
};
var _callbackLoad = function(e) {
var data = e.target.result;
_files.push(data);
_callbackStatus();
if (o.load) {
o.load(data);
}
};
var _callbackPreload = o.preload ? function(f) {
return o.preload(f);
} : false;
var _callbackProgress = function(e) {
if (o.progress) {
if (e.lengthComputable) {
o.progress(e.loaded, e.total);
}
}
};
var _callbackReset = function() {
_files = [];
_rawFiles = [];
_totalFiles = 0;
_totalFilesCompleted = 0;
if (o.fileListener) { $(o.fileListener).value = null; }
if (o.reset) { o.reset(); }
};
var _callbackStart = o.start || function(){};
// ABORT UPLOAD
var _abort = function() {
_reader.abort();
};
// GET RAW FILES (RETURN THE RAW FILES)
var _getRawFile = function() {
return _rawFiles[0];
};
var _getRawFiles = function() {
return _rawFiles;
};
// GET FILES (RETURN THE PROCESSED FILES)
var _getFile = function() {
return _files[0];
};
var _getFiles = function() {
return _files;
};
// FILE READER API
var _init = function(files) {
// Has one or more files been selected?
if (!files.length) { return false; }
// Convert files to array
var f = [];
for(var i=files.length;i--;f.unshift(files[i]));
// Run through dev preload callback
f = o.preload ? _callbackPreload(_multiple ? f : f[0]) : f;
// Reset global variables
_callbackReset();
// Set files to array if dev preload callback returned a single object
_rawFiles = Array.isArray(f) ? f : [f];
// If preload was used, did the user return
if (!_rawFiles.length || !_rawFiles[0]) { console.log('ERROR: Nothing was returned from the FlexFile "preload" callback.'); return false; }
// Set methods
_totalFiles = _rawFiles.length;
_reader.onerror = _callbackError;
_reader.onabort = _callbackAbort;
_reader.onloadstart = _callbackStart;
_reader.onprogress = _callbackProgress;
_reader.onload = _callbackLoad;
_queue();
};
var _queue = function() {
_reader['readAs' + _readAs](_rawFiles[_totalFilesCompleted]);
};
// LISTENERS
if (o.abortListener) {
$(o.abortListener).addEventListener('click', _abort);
}
if (o.dropListener) {
$(o.dropListener).addEventListener('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}, false);
$(o.dropListener).addEventListener('drop', function(e) {
e.stopPropagation();
e.preventDefault();
_init(e.dataTransfer.files);
}, false);
}
if (o.fileListener) {
var sf = $(o.fileListener);
sf.addEventListener('change', function() { _init(this.files); }, false);
if (_multiple) {
sf.setAttribute('multiple', true);
} else {
sf.removeAttribute('multiple');
}
}
// EXPOSE FLEXFILE API
return {
reset: _callbackReset,
getRawFile: _getRawFile,
getRawFiles: _getRawFiles,
getFile: _getFile,
getFiles: _getFiles
}
}; // FlexFile
/*
FLEXFILE METHODS
ff.getFile();
ff.getFiles();
ff.getRawFile();
ff.getRawFiles();
ff.reset();
*/
// Global selectors for example
var $ = function(s) {
return document.querySelector(s)
};
var uploadForm = $('form');
var progress = $('progress');
var output = $('output');
var span = $('span');
var completedMessage = $('#completed-message');
var div = $('#drag-and-drop-area');
// NOTE: Only the "dropListener" or "fileListener" is required in this entire object
// var ff = new FlexFile({ fileListener: 'input[type="file"]' });
// OR with other options:
var ff = new FlexFile({
readAs: 'DataURL', // or "BinaryString"
multiple: true, // true by default, set to `false` if multiple file selection isn't allowed
abortListener: 'input[type="button"]',
dropListener: '#drag-and-drop-area', // A file input and/or drag-n-drop selector is required.
fileListener: 'input[type="file"]', // A file input and/or drag-n-drop selector is required.
abort: function() {
uploadForm.className = 'active';
console.log('Image preview aborted.');
ff.reset();
},
complete: function(files, rawFiles, uploaded, total) {
console.log(files[0]);
console.log(rawFiles[0]);
completedMessage.textContent = 'All ' + total + ' images/files are currently accessible using the "get()" method.';
completedMessage.style.display = 'block';
},
error: function(error) {
console.log(error.message);
},
load: function(data) {
var img = document.createElement('img');
img.src = data;
img.alt = '';
div.appendChild(img);
},
preload: function(files) {
// Optionally, filter selected files/images before returning them for processing (file reading)
var images = [];
for (var i = 0, l = files.length; i < l; i++) {
var size = (files[i].size / 1048576).toFixed(3) + ' MB';
if (files[i].size > 10485760) {
alert('This image is ' + size + ' and will not be uploaded.\n\nImages at or below 10.0 MB will still be uploaded.');
} else if (files[i].type != 'image/png' && files[i].type != 'image/jpg' && files[i].type != 'image/gif' && files[i].type != 'image/jpeg' ) {
alert('Please upload an image with the type of ".jpg," ".png," or ".gif."');
} else {
images.push(files[i]);
}
}
return images;
},
progress: function(loaded, total) {
progress.value = loaded / total;
output.textContent = (loaded / total * 100).toFixed(2) + '%';
console.log((loaded / total * 100).toFixed(2) + '%');
},
reset: function() {
// This reset also clears any previously uploaded files
console.clear();
completedMessage.style.display = 'none';
uploadForm.className = '';
progress.value = 0;
output.textContent = '';
span.textContent = 'See the console for more details.';
div.innerHTML = '';
},
start: function() {
console.log('Reading...');
},
status: function(uploaded, total) {
span.textContent = uploaded + '/' + total + ' images loaded. See the console for more details.';
}
});
FlexFileJS
FlexFileJS
Flexible browser file uploader
This example uses image uploading.
See the console for more details.
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - Animated Number Incrementor (Pure/Vanilla JavaScript)
<h1>VIO Inc – Dynamic Animated Number Incrementor Plugin (Vanilla JS)</h1>
<ul>
<li>
<span data-inc-value="1000000" data-inc-duration="5000" data-inc-delay="1000">0</span>
</li>
<li>
<span data-inc-value="4200" data-inc-duration="4000" data-inc-delay="2000">0</span>
</li>
<li>
<input data-inc-value="96.23" data-inc-duration="4000" data-inc-delay="2000" value="0"/>
</li>
</ul>
<table>
<thead>
<tr>
<td>Property</td>
<td>Description</td>
<td>Required?</td>
<td>Default</td>
</tr>
</thead>
<tbody>
<tr>
<td>elem</td>
<td>Targeted element</td>
<td>Required</td>
<td>—</td>
</tr>
<tr>
<td>value</td>
<td>Int or Float</td>
<td>Required</td>
<td>—</td>
</tr>
<tr>
<td>duration</td>
<td>Animation duration in milliseconds</td>
<td>Optional</td>
<td>1000 (ms)</td>
</tr>
<tr>
<td>speed</td>
<td>Animation speed in milliseconds</td>
<td>Optional</td>
<td>30 (ms)</td>
</tr>
<tr>
<td>delay</td>
<td>Delay until animation starts in milliseconds</td>
<td>Optional</td>
<td>0 (ms)</td>
</tr>
<tr>
<td>decimal</td>
<td>Decimal places to show (0-2)</td>
<td>Optional</td>
<td>0</td>
</tr>
<tr>
<td>currency</td>
<td>Currency symbol as string (i.e. '$')</td>
<td>Optional</td>
<td>—</td>
</tr>
<tr>
<td>reset()</td>
<td>A function that restarts the animation</td>
<td>Optional</td>
<td>—</td>
</tr>
</tbody>
</table>
::-webkit-scrollbar{width:12px;background:#222;} ::-webkit-scrollbar-track{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.3)} ::-webkit-scrollbar-thumb{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.5)} ,:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;}
body { font-family: 'Georgia', sans-serif; } h1 { font-size: 32px; text-align: center; } ul { padding-left: 0; list-style-type: none; } ul { position: absolute; top: 50px; right: 50%; margin-right: 25px; } table { position: absolute; top: 62px; left: 50%; margin-left: 25px; border-collapse: collapse; } thead tr { border-bottom: 1px solid #4c9; } td { padding: 5px 12px; } li { position: relative; margin-top: 25px; font-size: 50px; text-align: right; color: #4c9; } li:after { content: " [click]"; position: absolute; bottom: -10px; right: 0; font-size: 10px; } span { cursor: pointer; } input { width: 350px; text-align: right; font-family: inherit; font-size: inherit; color: #4c9; }
/* Inc v1.0.0 (c) 2014 Depth Development. http://depthdev.com License: Apache 2.0 */
'use strict';
function Inc(obj) { var elem = obj.elem; var input = (elem.nodeName.toLowerCase() === 'input') ? true: false; var value = parseFloat(elem.getAttribute('data-inc-value')) || 0; var duration = parseInt(elem.getAttribute('data-inc-duration')) || 0; var delay = parseInt(elem.getAttribute('data-inc-delay')) || 0; var decimal = ((obj.decimal > 2) ? 2 : obj.decimal) || 0; var currency = obj.currency || ''; var speed = ((obj.speed < 30) ? 30 : obj.speed) || 30; var count = 0; var increment = value / (duration / speed); var interval = null; var regex = /\B(?=(\d{3})+(?!\d))/g; var run = function() { count += increment; if (count < value) { (input) ? elem.value = currency + (count).toFixed(decimal).toString().replace(regex, ',') : elem.innerHTML = currency + (count).toFixed(decimal).toString().replace(regex, ','); } else { clearInterval(interval); (input) ? elem.value = currency + (value).toFixed(decimal).toString().replace(regex, ',') : elem.innerHTML = currency + (value).toFixed(decimal).toString().replace(regex, ','); } }; setTimeout(function() { interval = setInterval(run.bind(this), speed); }.bind(this), delay); this.reset = function() { clearInterval(interval); value = parseFloat(elem.getAttribute('data-inc-value')) || 0; duration = parseInt(elem.getAttribute('data-inc-duration')) || 0; increment = value / (duration / speed); delay = parseInt(elem.getAttribute('data-inc-delay')) || 0; count = 0; interval = setInterval(run, speed); }.bind(this); } // Inc
var elems = [
document.querySelector('li:nth-of-type(1) span'),
document.querySelector('li:nth-of-type(2) span'),
document.querySelector('li:nth-of-type(3) input')
];
var objs = [];
for (var i = 0, l = elems.length; i < l; i++) { objs.push( new Inc({ elem: elems[i], speed: 50, decimal: 2, currency: '$' }) ); } elems[0].addEventListener('click', function() { objs[0].reset(); }); elems[1].addEventListener('click', function() { objs[1].reset(); }); elems[2].addEventListener('click', function() { objs[2].reset(); });
Animated Number Incrementor (Pure/Vanilla JavaScript)
# VIO Inc – Dynamic Animated Number Incrementor Plugin (Vanilla JS)
- $290,000.00
- $472.50
| Property | Description | Required? | Default |
| --- | --- | --- | --- |
| elem | Targeted element | Required | — |
| value | Int or Float | Required | — |
| duration | Animation duration in milliseconds | Optional | 1000 (ms) |
| speed | Animation speed in milliseconds | Optional | 30 (ms) |
| delay | Delay until animation starts in milliseconds | Optional | 0 (ms) |
| decimal | Decimal places to show (0-2) | Optional | 0 |
| currency | Currency symbol as string (i.e. '$') | Optional | — |
| reset() | A function that restarts the animation | Optional | — |
On [Github](https://github.com/depthdev) and [Depth](/content/site-root.html)
This Pen is owned by [Adam](https://codepen.io/depthdev) on [CodePen](https://codepen.io/).
[See more by @depthdev on CodePen](https://codepen.io/depthdev)
### External CSS
This Pen doesn't use any external CSS resources.
### External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - ObjectsFilter
Objects Filter v1.3.0
Filter lists/JSON objects by keywords, partial words, and groups of words. Optionally, specify paths with JSON syntax and/or ask for case-sensitive results.
1 KB (minified)
::-webkit-scrollbar{width:12px;background:#222;}
::-webkit-scrollbar-track{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.3)}
::-webkit-scrollbar-thumb{border-radius:4px;-webkit-box-shadow:inset 0 0 4px rgba(0,0,0,0.5)}
html{font-family:'Georgia',sans-serif;}
.left {
float: left;
width: 45%;
}
.right {
float: right;
width: 45%;
}
/*
ObjectsFilter v1.3.0
(c) 2015 Depth Development. http://depthdev.com
License: Apache 2.0
*/
// Minified:
// function ObjectsFilter(t,r){for(var t=t,e=/[\-\[\]\/\{\}\(\)\*\+\?\:\.\\\^\$\|]/g,i=function(r){if(r.filter&&/\S+/.test(r.filter)){for(var i=r.filter.split(/\s+/),s=[],n=0,a=i.length;a>n;n++){var f=i[n].replace(e,"\\$&"),o=r.caseSensitive?"":"i";s[n]=new RegExp(f,o)}for(var l=function(t){for(var r=!0,e=0,n=i.length;n>e&&r;e++)for(var a=0,f=s.length;f>a;a++)if(!s[a].test(t)){r=!1;break}return r},h=[],n=0,a=t.length;a>n;n++){if(r.paths){var p=[];if(Array.isArray(r.paths))for(var g=0,v=r.paths.length;v>g;g++){for(var y=r.paths[g].split(/\./),c=t[n],u=0,S=y.length;S>u;u++)c.hasOwnProperty(y[u])&&(c=c[y[u]]);p.push("object"==typeof c?JSON.stringify(c):c)}else{for(var y=r.paths.split(/\./),c=t[n],g=0,v=y.length;v>g;g++)c.hasOwnProperty(y[g])&&(c=c[y[g]]);p.push("object"==typeof c?JSON.stringify(c):c)}for(var w=!1,g=0,v=p.length;v>g;g++)r.caseSensitive?(r.filter===p[g]||l(p[g]))&&(w=!0):(r.filter.toString().toLowerCase()===p[g].toString().toLowerCase()||l(p[g]))&&(w=!0)}else l(JSON.stringify(t[n]))&&(w=!0);w&&h.push(t[n])}t=h}},s=0,n=r.length;n>s;s++)i(r[s]);return t}
function ObjectsFilter(data, filters) {
var data = data;
var escape = /[\-\[\]\/\{\}\(\)\*\+\?\:\.\\\^\$\|]/g; // RegEx to escape regex characters in user's search fields
// Query all matches from data set
var query = function(obj) {
// If there is some text, and it's not a space in the provided text input...
if (obj.filter && /\S+/.test(obj.filter)) {
// Get all values from input
var vals = obj.filter.split(/\s+/);
var regexes = [];
for (var i = 0, l = vals.length; i < l; i++) {
var v = vals[i].replace(escape,'\\$&');
var flag = obj.caseSensitive ? '' : 'i';
regexes[i] = new RegExp(v, flag);
}
var searchStr = function(str) {
// Get all filter values
var foundAll = true;
// Loop through object to find if all filter values exist; if so, return the result
for (var i = 0, l = vals.length; i < l; i++) {
if (foundAll) {
for (var ii = 0, ll = regexes.length; ii < ll; ii++) {
if (!regexes[ii].test(str)) {
foundAll = false; break;
}
}
} else {
break;
}
}
// Return search result boolean
return foundAll;
}; // end searchStr
// Loop through all projects
var temp = [];
for (var i = 0, l = data.length; i < l; i++) {
/*
* If exact match, push to new temp array;
* otherwise, see if all provided words exist somewhere in the provided object property using the "searchStr" function;
* and, if so, push it to the temp array
*/
if (obj.paths) {
// Set object property paths
var propPaths = [];
if (Array.isArray(obj.paths)) {
for (var ii = 0, ll = obj.paths.length; ii < ll; ii++) {
var props = obj.paths[ii].split(/\./);
var prop = data[i];
for (var iii = 0, lll = props.length; iii < lll; iii++) {
if (prop.hasOwnProperty(props[iii])) {
prop = prop[props[iii]];
}
}
propPaths.push(typeof prop === 'object' ? JSON.stringify(prop) : prop);
}
} else {
var props = obj.paths.split(/\./);
var prop = data[i];
for (var ii = 0, ll = props.length; ii < ll; ii++) {
if (prop.hasOwnProperty(props[ii])) {
prop = prop[props[ii]];
}
}
propPaths.push(typeof prop === 'object' ? JSON.stringify(prop) : prop);
}
var keepObj = false;
// Loop through each path's values, and if an object itself, search all children;
for (var ii = 0, ll = propPaths.length; ii < ll; ii++) {
// Find matches
if (obj.caseSensitive) {
if (obj.filter === propPaths[ii] || searchStr(propPaths[ii])) {
keepObj = true;
}
} else {
if (obj.filter.toString().toLowerCase() === propPaths[ii].toString().toLowerCase() || searchStr(propPaths[ii])) {
keepObj = true;
}
}
} // end ii for loop
} else {
if (searchStr(JSON.stringify(data[i]))) {
keepObj = true;
}
}
// If all values were found, push this object to the temp array
if (keepObj) {
temp.push(data[i]);
}
} // end i for loop
// Replace pointer variable with filtered data set
data = temp;
}
}; // query()
// Run queries
for (var i = 0, l = filters.length; i < l; i++) {
query(filters[i]);
}
// Return the filtered data set
return data;
} // end ObjectsFilter
// EXAMPLE USE
var _ = function(s) { return document.querySelector(s); };
var apples = [\
{\
name: 'Gala',\
color: {\
pedals: 'White?',\
apple: 'Red and green',\
notes: 'This apple may have shades of yellow at times.'\
},\
size: {\
diameter: 3.2,\
unit: 'centimeters'\
}\
},\
{\
name: 'Pink Lady',\
color: {\
pedals: 'White and yellow?',\
apple: 'Red with pink hue',\
notes: 'Unlike Granny Smith these are sweet but not sour.'\
},\
size: {\
diameter: 3.125,\
unit: 'inches'\
}\
},\
{\
name: 'Granny Smith',\
color: {\
pedals: 'White?',\
apple: 'Green',\
notes: 'Some types have hundreds of small white dots.'\
},\
size: {\
diameter: 2.7,\
unit: 'inches'\
}\
},\
{\
name: 'Macintosh',\
color: {\
pedals: 'White?',\
apple: 'Red and green',\
notes: 'Some types have hundreds of small white dots. This apple has a tart flavor to it.'\
},\
size: {\
diameter: 2.9,\
unit: 'inches'\
}\
}\
];
var sort = function() {
var list = ObjectsFilter(apples, [\
{\
filter: _('#filter-name').value,\
paths: 'name', // Optional\
caseSensitive: false // Optional\
},\
{\
filter: _('#filter-color').value,\
paths: [\
'color.apple',\
'size.diameter'\
], // Optional\
caseSensitive: false // Optional\
}\
]);
// Build HTML
var ulContent = '';
for (var i = 0; i < list.length; i++) {
ulContent += '<li><h2>' + list[i].name + '</h2><p>' + list[i].color.apple + '</p></li>';
}
_('#foods').innerHTML = ulContent;
}; // end sort()
// Initialize components
sort();
_('form').addEventListener('keyup', sort, false);
_('#object-view').innerHTML = JSON.stringify(apples)
.replace(/{/g,'<div>')
.replace(/\}/g,'</div>')
.replace(/("\w+"\:"\w+",)/g,'<div>$1</div>')
.replace(/"(\w+)"\:/g,'<strong>$1:</strong>')
.replace(/,/g,'<br/>')
.replace(/[\[\]]/g,'')
.replace(/\:/g,': ')
.replace(/(pedals|apple|notes|diameter|unit):/g,'    $1:')
.replace(/(name\:)/g,'<hr/>$1');
ObjectsFilter
Objects Filter v1.3.0
Filter lists/JSON objects by keywords, partial words, and groups of words. Optionally, specify paths with JSON syntax and/or ask for case-sensitive results.
1 KB (minified)
Gala
Red and green
Pink Lady
Red with pink hue
Granny Smith
Green
Macintosh
Red and green
name:"Gala"
color:
pedals:"White?"
apple:"Red and green"
notes:"This apple may have shades of yellow at times."
size:
diameter: 3.2
unit:"centimeters"
name:"Pink Lady"
color:
pedals:"White and yellow?"
apple:"Red with pink hue"
notes:"Unlike Granny Smith these are sweet but not sour."
size:
diameter: 3.125
unit:"inches"
name:"Granny Smith"
color:
pedals:"White?"
apple:"Green"
notes:"Some types have hundreds of small white dots."
size:
diameter: 2.7
unit:"inches"
name:"Macintosh"
color:
pedals:"White?"
apple:"Red and green"
notes:"Some types have hundreds of small white dots. This apple has a tart flavor to it."
size:
diameter: 2.9
unit:"inches"
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - Mouse Swipe
<h1>Mouse Swipe</h1>
<p>Check out the console, as well as the instantiation object (line 157) on the JS pane.</p>
<div id="swipe-area">
<i></i>
<img src="http://placebear.com/100/100" alt="" draggable="false" />
</div>
,:before,*:after{box-sizing:border-box;margin:0;padding:0;} html{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;font-family:'Georgia',sans-serif;} #swipe-area { position: relative; margin: 12.5vh 0 0 12.5vw; border: 2px dashed #ccc; width: 75vw; height: 75vh; cursor: none; &:before { content: "Mouse Swipe Here"; position: absolute; top: 50%; left: 0; width: 100%; margin-top: -1.5vw; text-align: center; opacity: 0.125; font-size: 3vw; text-transform: uppercase; } } i { position: absolute; top: 0; left: 0; display: block; width: 10px; height: 10px; border-radius: 50%; background: #ccc; box-shadow: 0 0 10px 10px #ccc; } img { position: absolute; top: 0; left: 0; width: 100px; margin-left: calc(50% - 50px); display: block; background: #ccc; box-shadow: 0 0 10px 10px #ccc; cursor: not-allowed; }
/* MouseSwipe v0.3.0 (c) 2015 Depth Development. http://depthdev.com License: Apache 2.0 */
'use strict';
// Minified: function MouseSwipe(e){var t={ms:0,x:0,y:0},a={ms:0,x:0,y:0},f=e.swipe,n=!1,o=function(a){t.ms=a.timeStamp,t.x=a.clientX-e.area.offsetLeft,t.x=t.x<0?0:t.x>e.area.offsetWidth?e.area.offsetWidth:t.x,t.y=event.clientY-e.area.offsetTop,t.y=t.y<0?0:t.y>e.area.offsetHeight?e.area.offsetHeight:t.y},i=function(t){a.ms=t.timeStamp,a.x=t.clientX-e.area.offsetLeft,a.x=a.x<0?0:a.x>e.area.offsetWidth?e.area.offsetWidth:a.x,a.y=event.clientY-e.area.offsetTop,a.y=a.y<0?0:a.y>e.area.offsetHeight?e.area.offsetHeight:a.y,e.change&&e.change(m())},s=function(f){var o=event.clientX-e.area.offsetLeft,i=event.clientY-e.area.offsetTop;a.ms=f.timeStamp,a.x=o,a.y=i,e.move&&n&&e.move({ms:f.timeStamp-t.ms,x:(0>o?0:o>e.area.offsetWidth?e.area.offsetWidth:o)-t.x,y:(0>i?0:i>e.area.offsetHeight?e.area.offsetHeight:i)-t.y}),e.moving&&e.moving({ms:f.timeStamp,x:0>o?0:o>e.area.offsetWidth?e.area.offsetWidth:o,y:0>i?0:i>e.area.offsetHeight?e.area.offsetHeight:i})},r=function(){if(f){var e=m(),t=Math.abs(e.x),a=Math.abs(e.y);return t/f>a?e.x>0?"right":"left":a/f>t?e.y>0?"down":"up":!1}},m=function(){return{ms:a.ms-t.ms,x:a.x-t.x,y:a.y-t.y}};return function(){e.area.addEventListener("mouseenter",function(){n=!1}),(e.change||e.move)&&(e.area.addEventListener("mousedown",function(t){n=!0,o(t),e.down&&e.down()},!1),e.area.addEventListener("mouseup",function(t){n=!1,i(t),e.up&&e.up()},!1)),(e.move||e.moving)&&e.area.addEventListener("mousemove",s,!1)}.bind(this)(),{swipe:r}}
function MouseSwipe(o) {
// Local variables var start = { ms: 0, x: 0, y: 0 }; var end = { ms: 0, x: 0, y: 0 }; var swipe = o.swipe; var mousePressed = false;
// Internal Methods var mouseEnter = function(e) {
}; // mouseEnter
var mouseDown = function(e) { start.ms = e.timeStamp; start.x = e.clientX - o.area.offsetLeft; start.x = start.x < 0 ? 0 : start.x > o.area.offsetWidth ? o.area.offsetWidth : start.x; start.y = event.clientY - o.area.offsetTop; start.y = start.y < 0 ? 0 : start.y > o.area.offsetHeight ? o.area.offsetHeight : start.y; }; // mouseDown
var mouseUp = function(e) { end.ms = e.timeStamp; end.x = e.clientX - o.area.offsetLeft; end.x = end.x < 0 ? 0 : end.x > o.area.offsetWidth ? o.area.offsetWidth : end.x; end.y = event.clientY - o.area.offsetTop; end.y = end.y < 0 ? 0 : end.y > o.area.offsetHeight ? o.area.offsetHeight : end.y;
if (o.change) { o.change(mouseDiff()); }
}; // mouseUp
var mouseMove = function(e) {
var x = event.clientX - o.area.offsetLeft; var y = event.clientY - o.area.offsetTop;
end.ms = e.timeStamp; end.x = x; end.y = y;
if (o.move && mousePressed) { o.move({ ms: e.timeStamp - start.ms, x: (x < 0 ? 0 : x > o.area.offsetWidth ? o.area.offsetWidth : x) - start.x, y: (y < 0 ? 0 : y > o.area.offsetHeight ? o.area.offsetHeight : y) - start.y }); } if (o.moving) { o.moving({ ms: e.timeStamp, x: x < 0 ? 0 : x > o.area.offsetWidth ? o.area.offsetWidth : x, y: y < 0 ? 0 : y > o.area.offsetHeight ? o.area.offsetHeight : y }); } }; // mouseMove
var mouseSwipe = function() { if (swipe) { var diff = mouseDiff(); var x = Math.abs(diff.x); var y = Math.abs(diff.y); return x / swipe > y ? diff.x > 0 ? 'right' : 'left' : y / swipe > x ? diff.y > 0 ? 'down' : 'up' : false; } }; // mouseSwipe
var mouseDiff = function() { return { ms: end.ms - start.ms, x: end.x - start.x, y: end.y - start.y } };
// Init (function() { o.area.addEventListener('mouseenter', function(e) { mousePressed = false; }); if(o.change || o.move){ o.area.addEventListener('mousedown', function(e) { mousePressed = true; mouseDown(e); if (o.down) { o.down(); } }, false); //o.area.addEventListener('touchstart', mouseDown, false); o.area.addEventListener('mouseup', function(e) { mousePressed = false; mouseUp(e); if (o.up) { o.up(); } }, false); //o.area.addEventListener('touchend', mouseUp, false); } if(o.move || o.moving){ o.area.addEventListener('mousemove', mouseMove, false); //o.area.addEventListener('touchmove', mouseMove, false); } }.bind(this)());
return { swipe: mouseSwipe } }; // MouseSwipe
// CUSTOM DEV STUFF var dev = { touchLikeArea: document.querySelector('i'), img: document.querySelector('img'), imgCurrentLeft: 0, imgGoLeft: 0, /* change: function(obj) { var isSwipe = swipeInstance.swipe(); if (isSwipe === 'left' || isSwipe === 'right') { // Move img var px = parseFloat(dev.img.style.left.replace(/(-?\d*)/,'$1'),10); dev.img.style.left = (obj.x + (px ? px : 0)) + 'px'; } },*/ move: function(obj) { var isSwipe = swipeInstance.swipe(); if (isSwipe === 'left' || isSwipe === 'right') { dev.imgGoLeft = obj.x; dev.img.style.left = dev.imgCurrentLeft + (dev.imgGoLeft) + 'px'; } else { console.log(isSwipe); } }, moving: function(obj) { dev.touchLikeArea.style.cssText = 'top:'+(obj.y-5)+'px;left:'+(obj.x-5)+'px;'; }, up: function() { //console.log('up'); var isSwipe = swipeInstance.swipe(); if (isSwipe === 'left' || isSwipe === 'right') { dev.imgCurrentLeft = dev.imgCurrentLeft + dev.imgGoLeft; } }, down: function() { //console.log('down'); } };
// INSTANTIATE A NEW MOUSESWIPE OBJECT var swipeInstance = new MouseSwipe({ area: document.querySelector('#swipe-area'), // Area to track as an element. change: dev.change, // Optional. Function. Returns an object with ms, x, and y as the difference between the mouseup and mousedown events. move: dev.move, // Optional. Function. Returns an object with ms, x, and y as the ellapsed current datetime ms stamp, x and y coordinates since mousedown. moving: dev.moving, // Optional. Function. Returns an object with ms, x, and y as the current datetime ms stamp, x and y coordinates. down: dev.down, // Optional. Function. Fires when mouse button is pressed. up: dev.up, // Optional. Function. Fires when mouse button is released. swipe: 3 // Optional. Number. Default === 0 (no swipe). The precision of what is considered a swipe. 1 === 45 degrees, 2 === 22.5 degrees, 3 === 15 degrees, etc. Returns swipe directions as lowercase strings 'left','right','up' or 'down'. }); //var swipe = new MouseSwipe(document);
document.querySelector('img').addEventListener('click', function() { alert("Clicking is fine, but don't drag me for this demo.\nTry swiping in the box somewhere."); });
Mouse Swipe
# Mouse Swipe
Check out the console, as well as the instantiation object (line 157) on the JS pane.
On [Github](https://github.com/depthdev) and [Depth](/content/site-root.html)
This Pen is owned by [Adam](https://codepen.io/depthdev) on [CodePen](https://codepen.io/).
[See more by @depthdev on CodePen](https://codepen.io/depthdev)
### External CSS
This Pen doesn't use any external CSS resources.
### External JavaScript
This Pen doesn't use any external JavaScript resources.
- CodePen Embed - InRealTime
In Real Time
Enables user's around the world to see the same from a specified timezone.
Options: callback, custom formatting, offset time, and update frequency (ensure's single threading time is accurate).
API: stop, start.
*{box-sizing:border-box;font-family:'Georgia',sans-serif;}
time {
font-size: 10vw;
color: #08f;
}
/*
InRealTimeJS v1.0.0
(c) 2016 Depth Development. http://depthdev.com
License: Apache 2.0
*/
'use strict';
let timeElem = document.querySelector('time');
//let timer = inRealTime(); console.log(timer);
// OR
let timer = new inRealTime({
callback: function(formattedTime, dateObj) {
timeElem.textContent = formattedTime;
}, // Callback to to run during each update
format: 'hh:mm:ssa', // 'HH,H,hh,h,mm,ss,sss,a'
offset: -4, // Timezone offset in hours as int/float (remember to account for daylight savings, usually between the 2nd Sunday in March @ 2am to the 1st Sunday in November @ 2am the time is increased by 1 hour)
update: 100 // Update frequency in milliseconds as int
});
// setTimeout(() => {
// timer.stop();
// }, 5000);
// setTimeout(() => {
// timer.start();
// }, 10000);
function inRealTime(obj) {
const o = (() => {
let tmp = obj || {};
tmp.callback = tmp.callback || function() {};
tmp.format = tmp.format || 'hh:mm:ss';
tmp.update = tmp.update || 1000;
tmp.timestamp = (() => {
const d = new Date();
return d.getTime() + (d.getTimezoneOffset() * 60000) + (tmp.offset ? tmp.offset * 3600000 : 0);
})();
tmp.now = Date.now();
return tmp;
})();
const format = (date) => {
const h = date.getHours();
const m = date.getMinutes();
const s = date.getSeconds();
const ms = date.getMilliseconds();
let formatted = o.format;
// Create hours
if (/h/i.test(formatted)) {
// 'HH': Hour in day, padded (00-23)
// 'H': Hour in day (0-23)
// 'hh': Hour in AM/PM, padded (01-12)
// 'h': Hour in AM/PM, (1-12)
const caseH = formatted.replace(/(h+).*/i,'$1');
switch (caseH) {
case 'HH':
formatted = formatted.replace(/HH/,h < 10 ? '0' + h : h);
break;
case 'H':
formatted = formatted.replace(/H/,h);
break;
case 'hh':
let tmp = h > 12 ? h - 12 : h;
formatted = formatted.replace(/hh/,tmp < 10 ? '0' + tmp : tmp);
break;
case 'h':
formatted = formatted.replace(/h/,h > 12 ? h - 12 : h);
break;
}
}
// Create minutes
if (/m/.test(formatted)) {
// 'mm': Minute in hour, padded (00-59)
// 'm': Minute in hour (0-59)
if (/(m{2})/.test(formatted)) {
formatted = formatted.replace(/mm/,m < 10 ? '0' + m : m);
} else {
formatted = formatted.replace(/m/,m);
}
}
// Create milliseconds
if (/s{3}/.test(formatted)) {
// 'sss': Millisecond in second, padded (000-999)
formatted = formatted.replace(/sss/,ms < 10 ? '00' + ms : ms < 100 ? '0' + ms : ms);
}
// Create seconds
if (/s{1,2}/.test(formatted)) {
// 'ss': Second in minute, padded (00-59)
// 's': Second in minute (0-59)
if (/(s{2})/.test(formatted)) {
formatted = formatted.replace(/ss/,s < 10 ? '0' + s : s);
} else {
formatted = formatted.replace(/s/,s);
}
}
// Create period
if (/a/.test(formatted)) {
// 'a': AM/PM marker
formatted = formatted.replace(/a/,h < 12 ? 'AM' : 'PM');
}
return formatted;
};
const date = () => {
return new Date(o.timestamp + (Date.now() - o.now));
};
let run = undefined;
const start = () => {
run = setInterval(() => {
const d = date();
o.callback(format(d), d);
}, o.update);
};
const stop = () => {
clearInterval(run);
};
if (!obj) {
return new Date(o.timestamp);
} else {
start();
return {
start: start,
stop: stop
}
}
} // inRealTime();
InRealTime
In Real Time
Enables user's around the world to see the same from a specified timezone.
Options: callback, custom formatting, offset time, and update frequency (ensure's single threading time is accurate).
API: stop, start.
01:04:21AM
This Pen is owned by Adam on CodePen.
See more by @depthdev on CodePen
External CSS
This Pen doesn't use any external CSS resources.
External JavaScript
This Pen doesn't use any external JavaScript resources.