{"id":334,"date":"2009-07-03T11:37:19","date_gmt":"2009-07-03T18:37:19","guid":{"rendered":"https:\/\/actionsnippet.com\/?p=1684"},"modified":"2009-07-03T11:37:19","modified_gmt":"2009-07-03T18:37:19","slug":"better-bitmapdata-brush","status":"publish","type":"post","link":"https:\/\/actionsnippet.com\/?p=334","title":{"rendered":"Better BitmapData Brush"},"content":{"rendered":"<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nvar canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xCCCCCC);\r\naddChild(new Bitmap(canvas));\r\nvar prevX:Number;\r\nvar prevY:Number;\r\nvar brush:Shape = new Shape();\r\n\r\nstage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);\r\nstage.addEventListener(MouseEvent.MOUSE_UP, onUp);\r\nfunction onDown(evt:MouseEvent):void{\r\n\tprevX = mouseX;\r\n\tprevY = mouseY;\r\n\taddEventListener(Event.ENTER_FRAME, onLoop);\r\n}\r\n\r\nfunction onUp(evt:MouseEvent):void{\r\n\tremoveEventListener(Event.ENTER_FRAME, onLoop);\r\n}\r\n\r\nfunction onLoop(evt:Event):void {\r\n      brush.x = mouseX;\r\n\t  brush.y = mouseY;\r\n\t  with (brush.graphics){\r\n\t\t  clear();\r\n\t\t  lineStyle(3, 0x000000);\r\n\t\t  lineTo(prevX-mouseX, prevY-mouseY);\r\n\t  }\r\n\t  canvas.draw(brush, brush.transform.matrix);\r\n\t  prevX = mouseX;\r\n\t  prevY = mouseY;\r\n}\r\n<\/pre>\n<p>If you write a drawing program with the Graphics class alone, you&#8217;ll notice that eventually the flash player will start to slow down. This could take quite some time, but it will eventually happen. Because the Graphics class is entirely vector based, the flash player needs to keep track of every single point that makes up any line in your drawing. If you draw something and then erase it by drawing white vector lines over it, flash still needs to know about that thing that you erased. <\/p>\n<p>The <a href=\"https:\/\/actionsnippet.com\/?p=1671\" target=\"blank\">snippet I wrote yesterday<\/a> reminded me of the technique used in the above snippet. In yesterdays post every line is drawn using the graphics class. As a result, eventually the flash player begins to choke. <\/p>\n<p>Today&#8217;s snippet draws a vector between the previous mouse location and the current mouse location &#8211; this vector is then drawn onto a BitmapData object and the vector is cleared. So rather than creating vector graphics that are continuously increasing in complexity, your just changing the color of pixels around on a BitmapData. <\/p>\n<p>To see a visual explanation take a look at the below swf. I slowed it down to 5fps, I tinted the vector red and scaled up the stage so you can differentiate between what&#8217;s vector and what&#8217;s bitmap:<\/p>\n<p><a data-asruffle-linked=\"true\" href=\"http:\/\/www.actionsnippet.com\/swfs\/bitmap_brush.html\"><br \/>\nClick to see the swf&#8230;<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/actionsnippet.com\/wp-content\/better_brush.jpg\" \/><\/a> <span class=\"asruffle-link\" data-swf=\"{&quot;url&quot;:&quot;https:\\\/\\\/actionsnippet.com\\\/swfs\\\/bitmap_brush.swf&quot;,&quot;title&quot;:&quot;bitmap brush&quot;,&quot;width&quot;:500,&quot;height&quot;:400,&quot;missing&quot;:false,&quot;allowScriptAccess&quot;:false,&quot;backgroundColor&quot;:&quot;#ffffff&quot;}\"><button type=\"button\" hidden aria-expanded=\"false\">Play demo<span class=\"screen-reader-text\">: bitmap brush<\/span><\/button><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xCCCCCC); addChild(new Bitmap(canvas)); var prevX:Number; var prevY:Number; var brush:Shape = new Shape(); stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown); stage.addEventListener(MouseEvent.MOUSE_UP, onUp); function onDown(evt:MouseEvent):void{ prevX = mouseX; prevY = mouseY; addEventListener(Event.ENTER_FRAME, onLoop); } function onUp(evt:MouseEvent):void{ removeEventListener(Event.ENTER_FRAME, onLoop); } function onLoop(evt:Event):void { brush.x = mouseX; brush.y = mouseY; with (brush.graphics){ clear(); lineStyle(3, 0x000000); lineTo(prevX-mouseX, prevY-mouseY); } canvas.draw(brush, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,33],"tags":[3,14,4],"class_list":["post-334","post","type-post","status-publish","format-standard","hentry","category-bitmapdata","category-graphics","tag-actionscript","tag-as3","tag-flash"],"_links":{"self":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=334"}],"version-history":[{"count":0,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/334\/revisions"}],"wp:attachment":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}