{"id":3406,"date":"2021-04-23T13:59:10","date_gmt":"2021-04-23T13:59:10","guid":{"rendered":"https:\/\/rengga.dev\/blog\/?p=3406"},"modified":"2023-02-28T04:54:18","modified_gmt":"2023-02-28T04:54:18","slug":"js-tutorial-obligatory-falling-snow","status":"publish","type":"post","link":"https:\/\/rengga.dev\/blog\/js-tutorial-obligatory-falling-snow\/","title":{"rendered":"JS Tutorial &#8211; Obligatory Falling Snow"},"content":{"rendered":"<p><span style=\"color: #ef3207;\"><a style=\"color: #ef3207;\" href=\"https:\/\/rengga.dev\/\" target=\"_blank\" rel=\"noopener\"><strong>Rengga Dev<\/strong><\/a> <\/span>&#8211; Try playing with the parameters on the gui to the right. The falling snow is just one effect of a countless number of possibilities.<\/p>\n<p><iframe style=\"width: 100%;\" title=\"Untitled\" src=\"https:\/\/codepen.io\/renggagumilar\/embed\/BaxaEBG?default-tab=result&amp;theme-id=dark\" height=\"600\" frameborder=\"no\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\"><br \/>\nSee the Pen <a href=\"https:\/\/codepen.io\/renggagumilar\/pen\/BaxaEBG\"><br \/>\nUntitled<\/a> by Rengga Gumilar (<a href=\"https:\/\/codepen.io\/renggagumilar\">@renggagumilar<\/a>)<br \/>\non <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<br \/>\n<\/iframe><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/\r\n\/\/ I'm hotlinking to some SVG images from flaticon.com\r\n\/\/ for use as the snowflakes. I hope that remains possible\r\n\/\/ especially with the below attribution;\r\n\/\/\r\n\/\/ \u2744 Icons made by Freepik from www.flaticon.com\r\n\/\/ \u2744 https:\/\/www.flaticon.com\/packs\/snowflakes\r\n\/\/\r\n\r\nlet colorType = {\r\n  type: \"multi\"\r\n};\r\n\r\nlet colors = {\r\n  color1: \"rgba(255,255,255,1)\",\r\n  color2: \"rgba(233,239,250,1)\",\r\n  color3: \"rgba(222,241,250,1)\",\r\n  color4: \"rgba(178,209,219,1)\",\r\n  color5: \"rgba(135,143,145,1)\"\r\n};\r\n\r\nlet options = {\r\n  alphaSpeed: 2,\r\n  alphaVariance: 1,\r\n  color: [colors.color1, colors.color2, colors.color3, colors.color4],\r\n  composition: \"source-over\",\r\n  count: 120,\r\n  direction: 160,\r\n  drift: 2,\r\n  glow: 50,\r\n  imageUrl: [\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake.png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(1).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(2).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(3).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(4).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(5).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(6).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(7).png\",\r\n    \"https:\/\/assets.codepen.io\/13471\/snowflake(8).png\",\r\n  ],\r\n  maxAlpha: 2,\r\n  maxSize: 24,\r\n  minAlpha: -0.2,\r\n  minSize: 3,\r\n  parallax: 6,\r\n  rotation: 0.5,\r\n  shape: [\"image\"],\r\n  speed: 2.5,\r\n  style: \"fill\",\r\n  twinkle: false,\r\n  xVariance: 20,\r\n  yVariance: 20,\r\n};\r\n\r\nwindow.onload = function() {\r\n  initStats();\r\n  initSparticles();\r\n  initGui();\r\n}\r\n\r\nwindow.initSparticles = function() {\r\n  var $main = document.querySelector(\"main\");\r\n  window.mySparticles = new Sparticles($main,options);\r\n};\r\n\r\nwindow.initStats = function() {\r\n  var stats = new Stats();\r\n  stats.domElement.classList.add(\"stats\");\r\n  document.body.appendChild(stats.domElement);\r\n  function statsDisplay() {\r\n    stats.begin();\r\n    stats.end();\r\n    requestAnimationFrame(statsDisplay);\r\n  }\r\n  requestAnimationFrame(statsDisplay);\r\n};\r\n\r\nwindow.initGui = function() {\r\n  const s = window.mySparticles;\r\n  const shapes = [\"circle\", \"square\", \"triangle\", \"diamond\", \"line\", \"image\"];\r\n  const styles = [\"fill\", \"stroke\", \"both\"];\r\n  const colorOptions = [\"single\", \"multi\", \"rainbow\"];\r\n  const composites = [\r\n    \"source-over\",\r\n    \"source-in\",\r\n    \"source-out\",\r\n    \"source-atop\",\r\n    \"destination-over\",\r\n    \"destination-in\",\r\n    \"destination-out\",\r\n    \"destination-atop\",\r\n    \"lighter\",\r\n    \"copy\",\r\n    \"xor\",\r\n    \"multiply\",\r\n    \"screen\",\r\n    \"overlay\",\r\n    \"darken\",\r\n    \"color-dodge\",\r\n    \"color-burn\",\r\n    \"hard-light\",\r\n    \"soft-light\",\r\n    \"difference\",\r\n    \"exclusion\",\r\n    \"hue\",\r\n    \"saturation\",\r\n    \"color\",\r\n    \"luminosity\"\r\n  ];\r\n  const rerender = () =&gt; {\r\n    window.mySparticles.destroy();\r\n    window.initSparticles();\r\n  };\r\n  var rerenderColors = function(v) {\r\n    if (colorType.type === \"rainbow\") {\r\n      options.color = \"rainbow\";\r\n    } else if (colorType.type === \"single\") {\r\n      options.color = colors.color1;\r\n    } else {\r\n      options.color = Object.keys(colors).map(i =&gt; {\r\n        return colors[i];\r\n      });\r\n    }\r\n    rerender();\r\n  };\r\n\r\n  const gui = new dat.GUI({ load: options });\r\n  const part = gui.addFolder(\"Particles\");\r\n  part.open();\r\n  part.add( options, \"count\", 1, 1500, 1).onFinishChange(rerender);\r\n  part.add( options, \"shape\", shapes).onFinishChange(rerender);\r\n  part.add( options, \"style\", styles).onFinishChange(rerender);\r\n  const image = part.addFolder(\"Image\");\r\n  \/\/ image.add( options, \"imageUrl\").onFinishChange(rerender);\r\n  part.add( options, \"minSize\", 1, 50, 1).onFinishChange(rerender);\r\n  part.add( options, \"maxSize\", 1, 50, 1).onFinishChange(rerender);\r\n  const anim = gui.addFolder(\"Animation\");\r\n  anim.add( options, \"direction\", 0, 360, 1).onFinishChange(rerender);\r\n  anim.add( options, \"speed\", 0, 100, 0.1).onFinishChange(rerender);\r\n  anim.add( options, \"rotation\", 0, 100, 0.1).onFinishChange(rerender);\r\n  const move = anim.addFolder(\"Movement\");\r\n  move.add( options, \"parallax\", 0, 10, 0.1).onFinishChange(rerender);\r\n  move.add( options, \"drift\", 0, 10, 0.1).onFinishChange(rerender);\r\n  move.add( options, \"xVariance\", 0, 50, 0.1).onFinishChange(rerender);\r\n  move.add( options, \"yVariance\", 0, 50, 0.1).onFinishChange(rerender);\r\n  const vis = gui.addFolder(\"Visual\");\r\n  vis.add( options, \"glow\", 0,50).onFinishChange(rerender);\r\n  vis.add( options, \"composition\", composites).onFinishChange(rerender);\r\n  const alpha = vis.addFolder(\"Alpha\");\r\n  alpha.add( options, \"twinkle\").onFinishChange(rerender);\r\n  alpha.add( options, \"minAlpha\", -2, 2, 0.1).onFinishChange(rerender);\r\n  alpha.add( options, \"maxAlpha\", -2, 2, 0.1).onFinishChange(rerender);\r\n  alpha.add( options, \"alphaSpeed\", 0, 50, 1).onFinishChange(rerender);\r\n  alpha.add( options, \"alphaVariance\", 0, 20, 1).onFinishChange(rerender);\r\n  const color = vis.addFolder(\"Color\");\r\n  color.open();\r\n  color.add(colorType, \"type\", colorOptions).onFinishChange(rerenderColors);\r\n  color.addColor(colors, \"color1\").onFinishChange(rerenderColors);\r\n  color.addColor(colors, \"color2\").onFinishChange(rerenderColors);\r\n  color.addColor(colors, \"color3\").onFinishChange(rerenderColors);\r\n  color.addColor(colors, \"color4\").onFinishChange(rerenderColors);\r\n  color.addColor(colors, \"color5\").onFinishChange(rerenderColors);\r\n};\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Rengga Dev &#8211; Try playing with the parameters on the gui to <a class=\"read-more\" href=\"https:\/\/rengga.dev\/blog\/js-tutorial-obligatory-falling-snow\/\" title=\"JS Tutorial &#8211; Obligatory Falling Snow\" itemprop=\"url\"><\/a><\/p>\n","protected":false},"author":1,"featured_media":3822,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[325,264,263,331,103,227],"newstopic":[],"class_list":{"0":"post-3406","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-javascript","8":"tag-background-effects","9":"tag-javascript-tutorial","10":"tag-js-tutorial","11":"tag-obligatory-falling-snow","12":"tag-web-design","13":"tag-web-designer"},"_links":{"self":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3406","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/comments?post=3406"}],"version-history":[{"count":1,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3406\/revisions"}],"predecessor-version":[{"id":3408,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3406\/revisions\/3408"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media\/3822"}],"wp:attachment":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media?parent=3406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/categories?post=3406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/tags?post=3406"},{"taxonomy":"newstopic","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/newstopic?post=3406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}