Initializing
Liveweave
Web
expand_more
home
Home
data_object
CSS Explorer
arrow_outward
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
outbox_alt
Generative AI
arrow_outward
frame_source
Python Playground
New
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Save
account_circle
Login
settings
Settings
expand_more
14
px
Live mode
Night mode
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
<!DOCTYPE html> <!-- All credit goes to http://jsfiddle.net/aKr8D/21/ --> <html> <head> <title>Falling Sakura leaves</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <style> @-webkit-keyframes fall { 0% { opacity: 0.9; top: 0 } 100% { opacity: 0.2; top: 100% } } @keyframes fall { 0% { opacity: 0.9; top: 0 } 100% { opacity: 0.2; top: 100% } } @-webkit-keyframes blow-soft-left { 0% { margin-left: 0 } 100% { margin-left: -50% } } @keyframes blow-soft-left { 0% { margin-left: 0 } 100% { margin-left: -50% } } @-webkit-keyframes blow-medium-left { 0% { margin-left: 0 } 100% { margin-left: -100% } } @keyframes blow-medium-left { 0% { margin-left: 0 } 100% { margin-left: -100% } } @-webkit-keyframes blow-soft-right { 0% { margin-left: 0 } 100% { margin-left: 50% } } @keyframes blow-soft-right { 0% { margin-left: 0 } 100% { margin-left: 50% } } @-webkit-keyframes blow-medium-right { 0% { margin-left: 0 } 100% { margin-left: 100% } } @keyframes blow-medium-right { 0% { margin-left: 0 } 100% { margin-left: 100% } } @-webkit-keyframes sway-0 { 0% { -webkit-transform: rotate(-5deg) } 40% { -webkit-transform: rotate(28deg) } 100% { -webkit-transform: rotate(3deg) } } @keyframes sway-0 { 0% { -ms-transform: rotate(-5deg); transform: rotate(-5deg) } 40% { -ms-transform: rotate(28deg); transform: rotate(28deg) } 100% { -ms-transform: rotate(3deg); transform: rotate(3deg) } } @-webkit-keyframes sway-1 { 0% { -webkit-transform: rotate(10deg) } 40% { -webkit-transform: rotate(43deg) } 100% { -webkit-transform: rotate(15deg) } } @keyframes sway-1 { 0% { -ms-transform: rotate(10deg); transform: rotate(10deg) } 40% { -ms-transform: rotate(43deg); transform: rotate(43deg) } 100% { -ms-transform: rotate(15deg); transform: rotate(15deg) } } @-webkit-keyframes sway-2 { 0% { -webkit-transform: rotate(15deg) } 40% { -webkit-transform: rotate(56deg) } 100% { -webkit-transform: rotate(22deg) } } @keyframes sway-2 { 0% { -ms-transform: rotate(15deg); transform: rotate(15deg) } 40% { -ms-transform: rotate(56deg); transform: rotate(56deg) } 100% { -ms-transform: rotate(22deg); transform: rotate(22deg) } } @-webkit-keyframes sway-3 { 0% { -webkit-transform: rotate(25deg) } 40% { -webkit-transform: rotate(74deg) } 100% { -webkit-transform: rotate(37deg) } } @keyframes sway-3 { 0% { -ms-transform: rotate(25deg); transform: rotate(25deg) } 40% { -ms-transform: rotate(74deg); transform: rotate(74deg) } 100% { -ms-transform: rotate(37deg); transform: rotate(37deg) } } @-webkit-keyframes sway-4 { 0% { -webkit-transform: rotate(40deg) } 40% { -webkit-transform: rotate(68deg) } 100% { -webkit-transform: rotate(25deg) } } @keyframes sway-4 { 0% { -ms-transform: rotate(40deg); transform: rotate(40deg) } 40% { -ms-transform: rotate(68deg); transform: rotate(68deg) } 100% { -ms-transform: rotate(25deg); transform: rotate(25deg) } } @-webkit-keyframes sway-5 { 0% { -webkit-transform: rotate(50deg) } 40% { -webkit-transform: rotate(78deg) } 100% { -webkit-transform: rotate(40deg) } } @keyframes sway-5 { 0% { -ms-transform: rotate(50deg); transform: rotate(50deg) } 40% { -ms-transform: rotate(78deg); transform: rotate(78deg) } 100% { -ms-transform: rotate(40deg); transform: rotate(40deg) } } @-webkit-keyframes sway-6 { 0% { -webkit-transform: rotate(65deg) } 40% { -webkit-transform: rotate(92deg) } 100% { -webkit-transform: rotate(58deg) } } @keyframes sway-6 { 0% { -ms-transform: rotate(65deg); transform: rotate(65deg) } 40% { -ms-transform: rotate(92deg); transform: rotate(92deg) } 100% { -ms-transform: rotate(58deg); transform: rotate(58deg) } } @-webkit-keyframes sway-7 { 0% { -webkit-transform: rotate(72deg) } 40% { -webkit-transform: rotate(118deg) } 100% { -webkit-transform: rotate(68deg) } } @keyframes sway-7 { 0% { -ms-transform: rotate(72deg); transform: rotate(72deg) } 40% { -ms-transform: rotate(118deg); transform: rotate(118deg) } 100% { -ms-transform: rotate(68deg); transform: rotate(68deg) } } @-webkit-keyframes sway-8 { 0% { -webkit-transform: rotate(94deg) } 40% { -webkit-transform: rotate(136deg) } 100% { -webkit-transform: rotate(82deg) } } @keyframes sway-8 { 0% { -ms-transform: rotate(94deg); transform: rotate(94deg) } 40% { -ms-transform: rotate(136deg); transform: rotate(136deg) } 100% { -ms-transform: rotate(82deg); transform: rotate(82deg) } } .sakura { background: -webkit-linear-gradient(120deg, rgba(255, 183, 197, 0.9), rgba(255, 197, 208, 0.9)); background: linear-gradient(120deg, rgba(255, 183, 197, 0.9), rgba(255, 197, 208, 0.9)); pointer-events: none; position: absolute } </style> </head> <body> <script type="text/javascript"> // Plugin code (function ($) { /** Polyfills and prerequisites **/ // requestAnimationFrame Polyfill var lastTime = 0; var vendors = ['webkit', 'o', 'ms', 'moz', '']; var vendorCount = vendors.length; for (var x = 0; x < vendorCount && ! window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; } if ( ! window.requestAnimationFrame) { window.requestAnimationFrame = function(callback) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; } if ( ! window.cancelAnimationFrame) { window.cancelAnimationFrame = function(id) { clearTimeout(id); }; } // Prefixed event check $.fn.prefixedEvent = function(type, callback) { for (var x = 0; x < vendorCount; ++x) { if ( ! vendors[x]) { type = type.toLowerCase(); } el = (this instanceof jQuery ? this[0] : this); el.addEventListener(vendors[x] + type, callback, false); } return this; }; // Test if element is in viewport function elementInViewport(el) { if (el instanceof jQuery) { el = el[0]; } var rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } // Random array element function randomArrayElem(arr) { return arr[Math.floor(Math.random() * arr.length)]; } // Random integer function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } /** Actual plugin code **/ $.fn.sakura = function (event, options) { // Target element var target = this.selector == "" ? $('body') : this; // Defaults for the option object, which gets extended below var defaults = { blowAnimations: ['blow-soft-left', 'blow-medium-left', 'blow-soft-right', 'blow-medium-right'], className: 'sakura', fallSpeed: 1, maxSize: 14, minSize: 10, newOn: 300, swayAnimations: ['sway-0', 'sway-1', 'sway-2', 'sway-3', 'sway-4', 'sway-5', 'sway-6', 'sway-7', 'sway-8'] }; var options = $.extend({}, defaults, options); // Default or start event if (typeof event === 'undefined' || event === 'start') { // Set the overflow-x CSS property on the target element to prevent horizontal scrollbars target.css({ 'overflow-x': 'hidden' }); // Function that inserts new petals into the document var petalCreator = function () { if (target.data('sakura-anim-id')) { setTimeout(function () { requestAnimationFrame(petalCreator); }, options.newOn); } // Get one random animation of each type and randomize fall time of the petals var blowAnimation = randomArrayElem(options.blowAnimations); var swayAnimation = randomArrayElem(options.swayAnimations); var fallTime = ((document.documentElement.clientHeight * 0.007) + Math.round(Math.random() * 5)) * options.fallSpeed; // Build animation var animations = 'fall ' + fallTime + 's linear 0s 1' + ', ' + blowAnimation + ' ' + (((fallTime > 30 ? fallTime : 30) - 20) + randomInt(0, 20)) + 's linear 0s infinite' + ', ' + swayAnimation + ' ' + randomInt(2, 4) + 's linear 0s infinite'; // Create petal and randomize size var petal = $('<div class="' + options.className + '" />'); var height = randomInt(options.minSize, options.maxSize); var width = height - Math.floor(randomInt(0, options.minSize) / 3); // Apply Event Listener to remove petals that reach the bottom of the page petal.prefixedEvent('AnimationEnd', function () { if ( ! elementInViewport(this)) { $(this).remove(); } }) // Apply Event Listener to remove petals that finish their horizontal float animation .prefixedEvent('AnimationIteration', function (ev) { if ( ( $.inArray(ev.animationName, options.blowAnimations) != -1 || $.inArray(ev.animationName, options.swayAnimations) != -1 ) && ! elementInViewport(this) ) { $(this).remove(); } }) .css({ '-webkit-animation': animations, animation: animations, 'border-radius': randomInt(options.maxSize, (options.maxSize + Math.floor(Math.random() * 10))) + 'px ' + randomInt(1, Math.floor(width / 4)) + 'px', height: height + 'px', left: (Math.random() * document.documentElement.clientWidth - 100) + 'px', 'margin-top': (-(Math.floor(Math.random() * 20) + 15)) + 'px', width: width + 'px' }); target.append(petal); }; // Finally: Start adding petals target.data('sakura-anim-id', requestAnimationFrame(petalCreator)); } // Stop event, which stops the animation loop and removes all current blossoms else if (event === 'stop') { // Cancel animation var animId = target.data('sakura-anim-id'); if (animId) { cancelAnimationFrame(animId); target.data('sakura-anim-id', null); } // Remove all current blossoms setTimeout(function() { $('.' + options.className).remove(); }, (options.newOn + 50)); } }; }(jQuery)); $(document).ready(function() { $('body').sakura(); }); </script> </body> </html>