Advertisement
ukamori

falling sakura leaves

Apr 18th, 2022
5,997
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 10.08 KB | None | 0 0
  1. <-- a tidied up version of this code from http://jsfiddle.net/aKr8D/21/ embed must be hidden head --!>
  2.  
  3.  
  4. <head>
  5. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  6. </head>
  7.  
  8. <style>
  9. @-webkit-keyframes fall {
  10. 0% {
  11. opacity: 0.9;
  12. top: 0
  13. }
  14.  
  15. 100% {
  16. opacity: 0.2;
  17. top: 100%
  18. }
  19. }
  20.  
  21. @keyframes fall {
  22. 0% {
  23. opacity: 0.9;
  24. top: 0
  25. }
  26.  
  27. 100% {
  28. opacity: 0.2;
  29. top: 100%
  30. }
  31. }
  32.  
  33. @-webkit-keyframes blow-soft-left {
  34. 0% {
  35. margin-left: 0
  36. }
  37.  
  38. 100% {
  39. margin-left: -50%
  40. }
  41. }
  42.  
  43. @keyframes blow-soft-left {
  44. 0% {
  45. margin-left: 0
  46. }
  47.  
  48. 100% {
  49. margin-left: -50%
  50. }
  51. }
  52.  
  53. @-webkit-keyframes blow-medium-left {
  54. 0% {
  55. margin-left: 0
  56. }
  57.  
  58. 100% {
  59. margin-left: -100%
  60. }
  61. }
  62.  
  63. @keyframes blow-medium-left {
  64. 0% {
  65. margin-left: 0
  66. }
  67.  
  68. 100% {
  69. margin-left: -100%
  70. }
  71. }
  72.  
  73. @-webkit-keyframes blow-soft-right {
  74. 0% {
  75. margin-left: 0
  76. }
  77.  
  78. 100% {
  79. margin-left: 50%
  80. }
  81. }
  82.  
  83. @keyframes blow-soft-right {
  84. 0% {
  85. margin-left: 0
  86. }
  87.  
  88. 100% {
  89. margin-left: 50%
  90. }
  91. }
  92.  
  93. @-webkit-keyframes blow-medium-right {
  94. 0% {
  95. margin-left: 0
  96. }
  97.  
  98. 100% {
  99. margin-left: 100%
  100. }
  101. }
  102.  
  103. @keyframes blow-medium-right {
  104. 0% {
  105. margin-left: 0
  106. }
  107.  
  108. 100% {
  109. margin-left: 100%
  110. }
  111. }
  112.  
  113. @-webkit-keyframes sway-0 {
  114. 0% {
  115. -webkit-transform: rotate(-5deg)
  116. }
  117.  
  118. 40% {
  119. -webkit-transform: rotate(28deg)
  120. }
  121.  
  122. 100% {
  123. -webkit-transform: rotate(3deg)
  124. }
  125. }
  126.  
  127. @keyframes sway-0 {
  128. 0% {
  129. -ms-transform: rotate(-5deg);
  130. transform: rotate(-5deg)
  131. }
  132.  
  133. 40% {
  134. -ms-transform: rotate(28deg);
  135. transform: rotate(28deg)
  136. }
  137.  
  138. 100% {
  139. -ms-transform: rotate(3deg);
  140. transform: rotate(3deg)
  141. }
  142. }
  143.  
  144. @-webkit-keyframes sway-1 {
  145. 0% {
  146. -webkit-transform: rotate(10deg)
  147. }
  148.  
  149. 40% {
  150. -webkit-transform: rotate(43deg)
  151. }
  152.  
  153. 100% {
  154. -webkit-transform: rotate(15deg)
  155. }
  156. }
  157.  
  158. @keyframes sway-1 {
  159. 0% {
  160. -ms-transform: rotate(10deg);
  161. transform: rotate(10deg)
  162. }
  163.  
  164. 40% {
  165. -ms-transform: rotate(43deg);
  166. transform: rotate(43deg)
  167. }
  168.  
  169. 100% {
  170. -ms-transform: rotate(15deg);
  171. transform: rotate(15deg)
  172. }
  173. }
  174.  
  175. @-webkit-keyframes sway-2 {
  176. 0% {
  177. -webkit-transform: rotate(15deg)
  178. }
  179.  
  180. 40% {
  181. -webkit-transform: rotate(56deg)
  182. }
  183.  
  184. 100% {
  185. -webkit-transform: rotate(22deg)
  186. }
  187. }
  188.  
  189. @keyframes sway-2 {
  190. 0% {
  191. -ms-transform: rotate(15deg);
  192. transform: rotate(15deg)
  193. }
  194.  
  195. 40% {
  196. -ms-transform: rotate(56deg);
  197. transform: rotate(56deg)
  198. }
  199.  
  200. 100% {
  201. -ms-transform: rotate(22deg);
  202. transform: rotate(22deg)
  203. }
  204. }
  205.  
  206. @-webkit-keyframes sway-3 {
  207. 0% {
  208. -webkit-transform: rotate(25deg)
  209. }
  210.  
  211. 40% {
  212. -webkit-transform: rotate(74deg)
  213. }
  214.  
  215. 100% {
  216. -webkit-transform: rotate(37deg)
  217. }
  218. }
  219.  
  220. @keyframes sway-3 {
  221. 0% {
  222. -ms-transform: rotate(25deg);
  223. transform: rotate(25deg)
  224. }
  225.  
  226. 40% {
  227. -ms-transform: rotate(74deg);
  228. transform: rotate(74deg)
  229. }
  230.  
  231. 100% {
  232. -ms-transform: rotate(37deg);
  233. transform: rotate(37deg)
  234. }
  235. }
  236.  
  237. @-webkit-keyframes sway-4 {
  238. 0% {
  239. -webkit-transform: rotate(40deg)
  240. }
  241.  
  242. 40% {
  243. -webkit-transform: rotate(68deg)
  244. }
  245.  
  246. 100% {
  247. -webkit-transform: rotate(25deg)
  248. }
  249. }
  250.  
  251. @keyframes sway-4 {
  252. 0% {
  253. -ms-transform: rotate(40deg);
  254. transform: rotate(40deg)
  255. }
  256.  
  257. 40% {
  258. -ms-transform: rotate(68deg);
  259. transform: rotate(68deg)
  260. }
  261.  
  262. 100% {
  263. -ms-transform: rotate(25deg);
  264. transform: rotate(25deg)
  265. }
  266. }
  267.  
  268. @-webkit-keyframes sway-5 {
  269. 0% {
  270. -webkit-transform: rotate(50deg)
  271. }
  272.  
  273. 40% {
  274. -webkit-transform: rotate(78deg)
  275. }
  276.  
  277. 100% {
  278. -webkit-transform: rotate(40deg)
  279. }
  280. }
  281.  
  282. @keyframes sway-5 {
  283. 0% {
  284. -ms-transform: rotate(50deg);
  285. transform: rotate(50deg)
  286. }
  287.  
  288. 40% {
  289. -ms-transform: rotate(78deg);
  290. transform: rotate(78deg)
  291. }
  292.  
  293. 100% {
  294. -ms-transform: rotate(40deg);
  295. transform: rotate(40deg)
  296. }
  297. }
  298.  
  299. @-webkit-keyframes sway-6 {
  300. 0% {
  301. -webkit-transform: rotate(65deg)
  302. }
  303.  
  304. 40% {
  305. -webkit-transform: rotate(92deg)
  306. }
  307.  
  308. 100% {
  309. -webkit-transform: rotate(58deg)
  310. }
  311. }
  312.  
  313. @keyframes sway-6 {
  314. 0% {
  315. -ms-transform: rotate(65deg);
  316. transform: rotate(65deg)
  317. }
  318.  
  319. 40% {
  320. -ms-transform: rotate(92deg);
  321. transform: rotate(92deg)
  322. }
  323.  
  324. 100% {
  325. -ms-transform: rotate(58deg);
  326. transform: rotate(58deg)
  327. }
  328. }
  329.  
  330. @-webkit-keyframes sway-7 {
  331. 0% {
  332. -webkit-transform: rotate(72deg)
  333. }
  334.  
  335. 40% {
  336. -webkit-transform: rotate(118deg)
  337. }
  338.  
  339. 100% {
  340. -webkit-transform: rotate(68deg)
  341. }
  342. }
  343.  
  344. @keyframes sway-7 {
  345. 0% {
  346. -ms-transform: rotate(72deg);
  347. transform: rotate(72deg)
  348. }
  349.  
  350. 40% {
  351. -ms-transform: rotate(118deg);
  352. transform: rotate(118deg)
  353. }
  354.  
  355. 100% {
  356. -ms-transform: rotate(68deg);
  357. transform: rotate(68deg)
  358. }
  359. }
  360.  
  361. @-webkit-keyframes sway-8 {
  362. 0% {
  363. -webkit-transform: rotate(94deg)
  364. }
  365.  
  366. 40% {
  367. -webkit-transform: rotate(136deg)
  368. }
  369.  
  370. 100% {
  371. -webkit-transform: rotate(82deg)
  372. }
  373. }
  374.  
  375. @keyframes sway-8 {
  376. 0% {
  377. -ms-transform: rotate(94deg);
  378. transform: rotate(94deg)
  379. }
  380.  
  381. 40% {
  382. -ms-transform: rotate(136deg);
  383. transform: rotate(136deg)
  384. }
  385.  
  386. 100% {
  387. -ms-transform: rotate(82deg);
  388. transform: rotate(82deg)
  389. }
  390. }
  391.  
  392. .sakura {
  393. background: -webkit-linear-gradient(120deg, rgba(255, 183, 197, 0.9), rgba(255, 197, 208, 0.9));
  394. background: linear-gradient(120deg, rgba(255, 183, 197, 0.9), rgba(255, 197, 208, 0.9));
  395. pointer-events: none;
  396. position: absolute
  397. }
  398.  
  399. </style>
  400.  
  401. <script type="text/javascript">
  402. // Plugin code
  403. (function($) {
  404. /** Polyfills and prerequisites **/
  405.  
  406. // requestAnimationFrame Polyfill
  407. var lastTime = 0;
  408. var vendors = ['webkit', 'o', 'ms', 'moz', ''];
  409. var vendorCount = vendors.length;
  410.  
  411. for (var x = 0; x < vendorCount && !window.requestAnimationFrame; ++x) {
  412. window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
  413. window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
  414. }
  415.  
  416. if (!window.requestAnimationFrame) {
  417. window.requestAnimationFrame = function(callback) {
  418. var currTime = new Date().getTime();
  419. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  420.  
  421. var id = window.setTimeout(function() {
  422. callback(currTime + timeToCall);
  423. }, timeToCall);
  424. lastTime = currTime + timeToCall;
  425.  
  426. return id;
  427. };
  428. }
  429.  
  430. if (!window.cancelAnimationFrame) {
  431. window.cancelAnimationFrame = function(id) {
  432. clearTimeout(id);
  433. };
  434. }
  435.  
  436. // Prefixed event check
  437. $.fn.prefixedEvent = function(type, callback) {
  438. for (var x = 0; x < vendorCount; ++x) {
  439. if (!vendors[x]) {
  440. type = type.toLowerCase();
  441. }
  442.  
  443. el = (this instanceof jQuery ? this[0] : this);
  444. el.addEventListener(vendors[x] + type, callback, false);
  445. }
  446.  
  447. return this;
  448. };
  449.  
  450. // Test if element is in viewport
  451. function elementInViewport(el) {
  452.  
  453. if (el instanceof jQuery) {
  454. el = el[0];
  455. }
  456.  
  457. var rect = el.getBoundingClientRect();
  458.  
  459. return (
  460. rect.top >= 0 &&
  461. rect.left >= 0 &&
  462. rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
  463. rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  464. );
  465. }
  466.  
  467. // Random array element
  468. function randomArrayElem(arr) {
  469. return arr[Math.floor(Math.random() * arr.length)];
  470. }
  471.  
  472. // Random integer
  473. function randomInt(min, max) {
  474. return Math.floor(Math.random() * (max - min + 1)) + min;
  475. }
  476.  
  477. /** Actual plugin code **/
  478. $.fn.sakura = function(event, options) {
  479.  
  480. // Target element
  481. var target = this.selector == "" ? $('body') : this;
  482.  
  483. // Defaults for the option object, which gets extended below
  484. var defaults = {
  485. blowAnimations: ['blow-soft-left', 'blow-medium-left', 'blow-soft-right', 'blow-medium-right'],
  486. className: 'sakura',
  487. fallSpeed: 1,
  488. maxSize: 14,
  489. minSize: 10,
  490. newOn: 300,
  491. swayAnimations: ['sway-0', 'sway-1', 'sway-2', 'sway-3', 'sway-4', 'sway-5', 'sway-6', 'sway-7', 'sway-8']
  492. };
  493.  
  494. var options = $.extend({}, defaults, options);
  495.  
  496. // Default or start event
  497. if (typeof event === 'undefined' || event === 'start') {
  498.  
  499. // Set the overflow-x CSS property on the target element to prevent horizontal scrollbars
  500. target.css({
  501. 'overflow-x': 'hidden'
  502. });
  503.  
  504. // Function that inserts new petals into the document
  505. var petalCreator = function() {
  506. if (target.data('sakura-anim-id')) {
  507. setTimeout(function() {
  508. requestAnimationFrame(petalCreator);
  509. }, options.newOn);
  510. }
  511.  
  512. // Get one random animation of each type and randomize fall time of the petals
  513. var blowAnimation = randomArrayElem(options.blowAnimations);
  514. var swayAnimation = randomArrayElem(options.swayAnimations);
  515. var fallTime = ((document.documentElement.clientHeight * 0.007) + Math.round(Math.random() * 5)) * options.fallSpeed;
  516.  
  517. // Build animation
  518. var animations =
  519. 'fall ' + fallTime + 's linear 0s 1' + ', ' +
  520. blowAnimation + ' ' + (((fallTime > 30 ? fallTime : 30) - 20) + randomInt(0, 20)) + 's linear 0s infinite' + ', ' +
  521. swayAnimation + ' ' + randomInt(2, 4) + 's linear 0s infinite';
  522.  
  523. // Create petal and randomize size
  524. var petal = $('<div class="' + options.className + '" />');
  525. var height = randomInt(options.minSize, options.maxSize);
  526. var width = height - Math.floor(randomInt(0, options.minSize) / 3);
  527.  
  528. // Apply Event Listener to remove petals that reach the bottom of the page
  529. petal.prefixedEvent('AnimationEnd', function() {
  530. if (!elementInViewport(this)) {
  531. $(this).remove();
  532. }
  533. })
  534. // Apply Event Listener to remove petals that finish their horizontal float animation
  535. .prefixedEvent('AnimationIteration', function(ev) {
  536. if (
  537. (
  538. $.inArray(ev.animationName, options.blowAnimations) != -1 ||
  539. $.inArray(ev.animationName, options.swayAnimations) != -1
  540. ) &&
  541. !elementInViewport(this)
  542. ) {
  543. $(this).remove();
  544. }
  545. })
  546. .css({
  547. '-webkit-animation': animations,
  548. animation: animations,
  549. 'border-radius': randomInt(options.maxSize, (options.maxSize + Math.floor(Math.random() * 10))) + 'px ' + randomInt(1, Math.floor(width / 4)) + 'px',
  550. height: height + 'px',
  551. left: (Math.random() * document.documentElement.clientWidth - 100) + 'px',
  552. 'margin-top': (-(Math.floor(Math.random() * 20) + 15)) + 'px',
  553. width: width + 'px'
  554. });
  555.  
  556. target.append(petal);
  557. };
  558.  
  559. // Finally: Start adding petals
  560. target.data('sakura-anim-id', requestAnimationFrame(petalCreator));
  561.  
  562. }
  563. // Stop event, which stops the animation loop and removes all current blossoms
  564. else if (event === 'stop') {
  565.  
  566. // Cancel animation
  567. var animId = target.data('sakura-anim-id');
  568.  
  569. if (animId) {
  570. cancelAnimationFrame(animId);
  571. target.data('sakura-anim-id', null);
  572. }
  573.  
  574. // Remove all current blossoms
  575. setTimeout(function() {
  576. $('.' + options.className).remove();
  577. }, (options.newOn + 50));
  578.  
  579. }
  580. };
  581. }(jQuery));
  582.  
  583. $(document).ready(function() {
  584. $('body').sakura();
  585. });
  586.  
  587. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement