{"id":3391,"date":"2021-06-15T11:46:04","date_gmt":"2021-06-15T11:46:04","guid":{"rendered":"https:\/\/rengga.dev\/blog\/?p=3391"},"modified":"2023-02-28T03:53:45","modified_gmt":"2023-02-28T03:53:45","slug":"js-tutorial-background-effects-grayscale-ambient-background","status":"publish","type":"post","link":"https:\/\/rengga.dev\/blog\/js-tutorial-background-effects-grayscale-ambient-background\/","title":{"rendered":"JS Tutorial &#8211; Background Effects Grayscale Ambient Background"},"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; Collection of hand-picked free\u00a0<strong>vanilla JavaScript background effect<\/strong>\u00a0code examples:\u00a0<em>change background color or image, animated, with canvas<\/em>\u00a0and etc.<\/p>\n<p><iframe style=\"width: 100%;\" title=\"Untitled\" src=\"https:\/\/codepen.io\/renggagumilar\/embed\/gOzOqzM?default-tab=result&amp;theme-id=dark\" height=\"500\" frameborder=\"no\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\"><br \/>\nSee the Pen <a href=\"https:\/\/codepen.io\/renggagumilar\/pen\/gOzOqzM\"><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\">\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ PARTICLE ENGINE \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\nvar ParticleEngine = (function() {\r\n    'use strict';\r\n\r\n    function ParticleEngine(canvas_id) {\r\n        \/\/ enforces new\r\n        if (!(this instanceof ParticleEngine)) {\r\n            return new ParticleEngine(args);\r\n        }\r\n        \r\n        var _ParticleEngine = this;\r\n\r\n        this.canvas_id = canvas_id;\r\n        this.stage = new createjs.Stage(canvas_id);\r\n        this.totalWidth = this.canvasWidth = document.getElementById(canvas_id).width = document.getElementById(canvas_id).offsetWidth;\r\n        this.totalHeight = this.canvasHeight = document.getElementById(canvas_id).height = document.getElementById(canvas_id).offsetHeight;\r\n        this.compositeStyle = \"lighter\";\r\n\r\n        this.particleSettings = [{id:\"small\", num:300, fromX:0, toX:this.totalWidth, ballwidth:3, alphamax:0.4, areaHeight:.5, color:\"#F0F0F0\", fill:false}, \r\n                                {id:\"medium\", num:100, fromX:0, toX:this.totalWidth,  ballwidth:8, alphamax:0.3, areaHeight:1, color:\"#C0C0C0\", fill:true}, \r\n                                {id:\"large\", num:10, fromX:0, toX:this.totalWidth, ballwidth:30,  alphamax:0.2, areaHeight:1, color:\"#A0A0A0\", fill:true}];\r\n        this.particleArray = [];\r\n        this.lights = [{ellipseWidth:400, ellipseHeight:100, alpha:0.6, offsetX:0, offsetY:0, color:\"#D0D0D0\"}, \r\n                        {ellipseWidth:350, ellipseHeight:250, alpha:0.3, offsetX:-50, offsetY:0, color:\"#B8B8B8\"}, \r\n                        {ellipseWidth:100, ellipseHeight:80, alpha:0.2, offsetX:80, offsetY:-50, color:\"#F8F8F8\"}];\r\n\r\n        this.stage.compositeOperation = _ParticleEngine.compositeStyle;\r\n\r\n\r\n        function drawBgLight()\r\n        {\r\n            var light;\r\n            var bounds;\r\n            var blurFilter;\r\n            for (var i = 0, len = _ParticleEngine.lights.length; i &lt; len; i++) {\t\t\t\t\r\n                light = new createjs.Shape();\r\n                light.graphics.beginFill(_ParticleEngine.lights[i].color).drawEllipse(0, 0, _ParticleEngine.lights[i].ellipseWidth, _ParticleEngine.lights[i].ellipseHeight);\r\n                light.regX = _ParticleEngine.lights[i].ellipseWidth\/2;\r\n                light.regY = _ParticleEngine.lights[i].ellipseHeight\/2; \r\n                light.y = light.initY = _ParticleEngine.totalHeight\/2 + _ParticleEngine.lights[i].offsetY;\r\n                light.x = light.initX =_ParticleEngine.totalWidth\/2 + _ParticleEngine.lights[i].offsetX;\r\n\r\n                blurFilter = new createjs.BlurFilter(_ParticleEngine.lights[i].ellipseWidth, _ParticleEngine.lights[i].ellipseHeight, 1);\r\n                bounds = blurFilter.getBounds();\r\n                light.filters = [blurFilter];\r\n                light.cache(bounds.x-_ParticleEngine.lights[i].ellipseWidth\/2, bounds.y-_ParticleEngine.lights[i].ellipseHeight\/2, bounds.width*2, bounds.height*2);\r\n                light.alpha = _ParticleEngine.lights[i].alpha;\r\n\r\n                light.compositeOperation = \"screen\";\r\n                _ParticleEngine.stage.addChildAt(light, 0);\r\n\r\n                _ParticleEngine.lights[i].elem = light;\r\n            }\r\n\r\n            TweenMax.fromTo(_ParticleEngine.lights[0].elem, 10, {scaleX:1.5, x:_ParticleEngine.lights[0].elem.initX, y:_ParticleEngine.lights[0].elem.initY},{yoyo:true, repeat:-1, ease:Power1.easeInOut, scaleX:2, scaleY:0.7});\r\n            TweenMax.fromTo(_ParticleEngine.lights[1].elem, 12, { x:_ParticleEngine.lights[1].elem.initX, y:_ParticleEngine.lights[1].elem.initY},{delay:5, yoyo:true, repeat:-1, ease:Power1.easeInOut, scaleY:2, scaleX:2, y:_ParticleEngine.totalHeight\/2-50, x:_ParticleEngine.totalWidth\/2+100});\r\n            TweenMax.fromTo(_ParticleEngine.lights[2].elem, 8, { x:_ParticleEngine.lights[2].elem.initX, y:_ParticleEngine.lights[2].elem.initY},{delay:2, yoyo:true, repeat:-1, ease:Power1.easeInOut, scaleY:1.5, scaleX:1.5, y:_ParticleEngine.totalHeight\/2, x:_ParticleEngine.totalWidth\/2-200});\r\n        }\r\n        \r\n        var blurFilter;\r\n        function drawParticles(){\r\n\r\n            for (var i = 0, len = _ParticleEngine.particleSettings.length; i &lt; len; i++) {\r\n                var ball = _ParticleEngine.particleSettings[i];\r\n\r\n                var circle;\r\n                for (var s = 0; s &lt; ball.num; s++ )\r\n                {\r\n                    circle = new createjs.Shape();\r\n                    if(ball.fill){\r\n                        circle.graphics.beginFill(ball.color).drawCircle(0, 0, ball.ballwidth);\r\n                        blurFilter = new createjs.BlurFilter(ball.ballwidth\/2, ball.ballwidth\/2, 1);\r\n                        circle.filters = [blurFilter];\r\n                        var bounds = blurFilter.getBounds();\r\n                        circle.cache(-50+bounds.x, -50+bounds.y, 100+bounds.width, 100+bounds.height);\r\n                    }else{\r\n                        circle.graphics.beginStroke(ball.color).setStrokeStyle(1).drawCircle(0, 0, ball.ballwidth);\r\n                    }\r\n                    \r\n                    circle.alpha = range(0, 0.1);\r\n                    circle.alphaMax = ball.alphamax;\r\n                    circle.distance = ball.ballwidth * 2;\r\n                    circle.ballwidth = ball.ballwidth;\r\n                    circle.flag = ball.id;\r\n                    _ParticleEngine.applySettings(circle, ball.fromX, ball.toX, ball.areaHeight);\r\n                    circle.speed = range(2, 10);\r\n                    circle.y = circle.initY;\r\n                    circle.x = circle.initX;\r\n                    circle.scaleX = circle.scaleY = range(0.3, 1);\r\n\r\n                    _ParticleEngine.stage.addChild(circle);\r\n                    \r\n\r\n                    animateBall(circle);\r\n\r\n                    _ParticleEngine.particleArray.push(circle);\r\n                }\r\n            }\t\r\n        }\r\n\r\n        this.applySettings = function(circle, positionX, totalWidth, areaHeight)\r\n        {\r\n            circle.speed = range(1, 3);\r\n            circle.initY = weightedRange(0, _ParticleEngine.totalHeight , 1, [_ParticleEngine.totalHeight * (2-areaHeight\/2)\/4, _ParticleEngine.totalHeight*(2+areaHeight\/2)\/4], 0.8 );\r\n            circle.initX = weightedRange(positionX, totalWidth, 1, [positionX+ ((totalWidth-positionX))\/4, positionX+ ((totalWidth-positionX)) * 3\/4], 0.6);\r\n        }\r\n\r\n        function animateBall(ball)\r\n        {\r\n            var scale = range(0.3, 1);\r\n            var xpos = range(ball.initX - ball.distance, ball.initX + ball.distance);\r\n            var ypos = range(ball.initY - ball.distance, ball.initY + ball.distance);\r\n            var speed = ball.speed;\r\n            TweenMax.to(ball, speed, {scaleX:scale, scaleY:scale, x:xpos, y:ypos, onComplete:animateBall, onCompleteParams:[ball], ease:Cubic.easeInOut});\t\r\n            TweenMax.to(ball, speed\/2, {alpha:range(0.1, ball.alphaMax), onComplete:fadeout, onCompleteParams:[ball, speed]});\t\r\n        }\t\r\n\r\n        function fadeout(ball, speed)\r\n        {\r\n            ball.speed = range(2, 10);\r\n            TweenMax.to(ball, speed\/2, {alpha:0 });\r\n        }\r\n\r\n        drawBgLight();\r\n        drawParticles();\r\n    }\r\n\r\n    ParticleEngine.prototype.render = function()\r\n    {\r\n        this.stage.update();\r\n    }\r\n\r\n    ParticleEngine.prototype.resize = function()\r\n    {\r\n        this.totalWidth = this.canvasWidth = document.getElementById(this.canvas_id).width = document.getElementById(this.canvas_id).offsetWidth;\r\n        this.totalHeight = this.canvasHeight = document.getElementById(this.canvas_id).height = document.getElementById(this.canvas_id).offsetHeight;\r\n        this.render();\r\n\r\n        for (var i= 0, length = this.particleArray.length; i &lt; length; i++)\r\n        {\r\n            this.applySettings(this.particleArray[i], 0, this.totalWidth, this.particleArray[i].areaHeight);\r\n        }\r\n\r\n        for (var j = 0, len = this.lights.length; j &lt; len; j++) {\r\n            this.lights[j].elem.initY = this.totalHeight\/2 + this.lights[j].offsetY;\r\n            this.lights[j].elem.initX =this.totalWidth\/2 + this.lights[j].offsetX;\r\n            TweenMax.to(this.lights[j].elem, .5, {x:this.lights[j].elem.initX, y:this.lights[j].elem.initY});\t\t\t\r\n        }\r\n    }\r\n\r\n    return ParticleEngine;\r\n\r\n}());\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/UTILS\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nfunction range(min, max)\r\n{\r\n    return min + (max - min) * Math.random();\r\n}\r\n        \r\nfunction round(num, precision)\r\n{\r\n   var decimal = Math.pow(10, precision);\r\n   return Math.round(decimal* num) \/ decimal;\r\n}\r\n\r\nfunction weightedRange(to, from, decimalPlaces, weightedRange, weightStrength)\r\n{\r\n    if (typeof from === \"undefined\" || from === null) { \r\n        from = 0; \r\n    }\r\n    if (typeof decimalPlaces === \"undefined\" || decimalPlaces === null) { \r\n        decimalPlaces = 0; \r\n    }\r\n    if (typeof weightedRange === \"undefined\" || weightedRange === null) { \r\n        weightedRange = 0; \r\n    }\r\n    if (typeof weightStrength === \"undefined\" || weightStrength === null) { \r\n        weightStrength = 0; \r\n    }\r\n\r\n   var ret\r\n   if(to == from){return(to);}\r\n \r\n   if(weightedRange &amp;&amp; Math.random()&lt;=weightStrength){\r\n      ret = round( Math.random()*(weightedRange[1]-weightedRange[0]) + weightedRange[0], decimalPlaces )\r\n   }else{\r\n      ret = round( Math.random()*(to-from)+from, decimalPlaces )\r\n   }\r\n   return(ret);\r\n}\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ RUN CODE \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nvar particles\r\n(function(){\r\n    particles = new ParticleEngine('projector');\r\n    createjs.Ticker.addEventListener(\"tick\", updateCanvas);\r\n    window.addEventListener('resize', resizeCanvas, false);\r\n\r\n    function updateCanvas(){\r\n        particles.render();\r\n    }\r\n\r\n    function resizeCanvas(){\r\n        particles.resize();\r\n    }\r\n}());<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Rengga Dev &#8211; Collection of hand-picked free\u00a0vanilla JavaScript background effect\u00a0code examples:\u00a0change background <a class=\"read-more\" href=\"https:\/\/rengga.dev\/blog\/js-tutorial-background-effects-grayscale-ambient-background\/\" title=\"JS Tutorial &#8211; Background Effects Grayscale Ambient Background\" itemprop=\"url\"><\/a><\/p>\n","protected":false},"author":1,"featured_media":3809,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[325,326,264,263,103,227],"newstopic":[],"class_list":{"0":"post-3391","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-javascript","8":"tag-background-effects","9":"tag-grayscale-ambient-background","10":"tag-javascript-tutorial","11":"tag-js-tutorial","12":"tag-web-design","13":"tag-web-designer"},"_links":{"self":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3391","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=3391"}],"version-history":[{"count":2,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3391\/revisions"}],"predecessor-version":[{"id":3398,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/3391\/revisions\/3398"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media\/3809"}],"wp:attachment":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media?parent=3391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/categories?post=3391"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/tags?post=3391"},{"taxonomy":"newstopic","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/newstopic?post=3391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}