Your SlideShare is downloading. ×
Pointer Events in Canvas
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Pointer Events in Canvas

827
views

Published on


0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
827
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Pointer v. Canvas
    • 2. Who Are We? Dean Hudson, @deaneroMason Browne, @metapandava Developers, Massively Fun
    • 3. We make games withopen web technology.http://massivelyfun.com @massivelyfun
    • 4. Basic Game Loop and Entities
    • 5. Game Loop Outline• Call requestAnimationFrame• Handle queued UI events• Call update on your game entities• Render!
    • 6. // game loopgameLoop = { run: function () { this.id = requestAnimationFrame(this.run); update(); // Call update on each entity draw(); // Call draw on each entity }, stop: function () { cancelAnimationFrame(this.id); }};gameLoop.run();
    • 7. RAF Shim• Lots of examples on the internet• Set RAF to whichever your browser has• Fallback to set timeout at ~16ms
    • 8. buildRAFPolyfill = function () { window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (cb, elt) { window.setTimeout(function() { cb(+new Date()); }, 1000 / 60); };}
    • 9. Simple Game Entity• Respond to update call• Manage position, height, width• Attach pointer events here
    • 10. class GameEntity # @params: {rect} The entitys drawing primitive constructor: (options = {}) -> {x, y, rotation} = options @position = new Position(x, y, rotation) @id = options.id ? UUID.generate() # You wa this moveTo: (pt) -> @position.setXY(pt) rotateTo: (rot) -> @position.setRotation(rot) # Coeff is a multiplier from the timer which we can use to adjust # motion to match how far we are off our target frame rate update: (tick, coeff) -> # do something interesting here. contains: (otherX, otherY) -> @rect.contains(x, y) if @rect? and @linkedRectmodule.exports = GameEntity
    • 11. Simple Draw Primitive• Respond to draw call• Manage position, height, width• Determine containment here (image hit detection, for instance)
    • 12. ### Rect: Drawing primitiveclass Rect constructor: (options = {}) -> @visible = options?.visible ? true @width = options?.width ? 1 @height = options?.height ? 1 {x, y, rotation} = options @position = new Position(x, y, rotation) draw: (ctx) -> throw new RenderError("Implement Me") # Basic, rectangular containment. contains: (otherX, otherY) -> {x, y} = @position.get() (otherX >= x && otherX <= x + @width) and (otherY >= y && otherY <= y + @height)module.exports = Rect
    • 13. Handling Mouse/ Touch Events
    • 14. Strategy• Attach onFoo to your canvas element where Foo is your DOM pointer event• Build a normalized event from the DOM event• Normalize your page X/Y to canvas X/Y.• Check for containment in game entities• Call handler if the entity contains the point and the handler exists
    • 15. Your Friend, ImageData
    • 16. WTF is ImageData?• ImageData is what you get back from a getImageData() call• A single byte Array with ALL your pixel data• Pixel data is stored as R, G, B, A tuples
    • 17. Single pixel Array offsets 0 1 2 3 R G B A 8 bits 8 bits 8 bits 8 bits 4 bytes
    • 18. Since ImageData acts like a byte array....• We can iterate through the pixels and do arithmetic or bitwise manipulation on the data.• Use XOR, NOT, etc. Get weird!
    • 19. var filter = function (x, y, w, h) { if (!this._cache) return; var ctx = this._cache.getContext(2d), idata = ctx.getImageData(x, y, w, h), i; for (i = 0; i < idata.data.length; i++) { idata.data[i] = (idata.data[i]++) % 255; }};
    • 20. var filter = function (x, y, w, h) { if (!this._cache) return; var ctx = this._cache.getContext(2d), idata = ctx.getImageData(x, y, w, h), i; for (i = 0; i < idata.data.length; i++) { if (! i % 4 === 3) continue; idata.data[i] = (idata.data[i]++) % 255; }
    • 21. Hit Detection
    • 22. What we want
    • 23. Strategy• If (x, y) is in the bounding box for the image, check pixels.• getImageData() to get a pixel data array for your sprite at pixel x, y.• Check byte values for pixel.
    • 24. var isPixelPainted = function (x, y) { ctx = this.imageCache; // this must be a canvas! thresh = this.transparencyThreshold || 100; // Grab a single pixel at x, y: if the alpha channel is greater // than the threshold, were in business. idata acts like a byte // array with each pixel occupying 4 slots (R, G, B , A). idata = ctx.getImageData(x, y, 1, 1); return idata.data[3] > thresh;}
    • 25. DON’T FORGET: each idata.datavalue is between 0-255!
    • 26. Dragging Example
    • 27. Questions?
    • 28. Thanks! dean@massivelyfun.com, @deaneromason@massivelyfun.com, @metapandava http://massivelyfun.com