Did anyone try to create a magnifying glass and have Lua code to share?
Here's an example in ObjectiveC: http://www.craftymind.com/2009/02/10/creating-the-loupe-or-magnifying-glass-effect-on-the-iphone/
I've difficulties to see equivalences in CoronaLua, specially regarding the concept of "mask".
Any help welcomed, thanks.
Are masks mandatory to do a magnifying glass? Another way?
Yes, no
Uh, and you'd also need a "screen grab" function that stores the result in memory rather than "on disk". Otherwise you'd have to wait twice, once for saving and once for loading. With the current grabber it would probably not be a very "responsive" effect. :)
that's not true. you don't need to grab anything. you just display the same image again zoomed and with a mask added
1 2 3 4 5 6 7 8 | local myImage = display.newImage("book.png") local myMagnifiedImage = display.newImage("book.png") local myMaskImage = display.newImage("mask.png") myMagnifiedImage.xScale=2 myMagnifiedImage.yScale=2 myMagnifiedImage.mask = myMaskImage |
(note this code won't work... yet... until ansca add the feature!)
Why does people always look at *single* things ? - like you having a single bitmap. :)
How about having several display objects in hierarchy at different positions and scale on the same screen ? What would you magnify in that "most-of-the-times" case, if you don't "render-to-texture" the entire stage ? ;)
ok good point erpy. for that we need to be able to "draw" the contents of our display group to a flat bitmap. this feature is possibly on the roadmap
Exactly, which isn't that different from the current "take screenshot"... just, as said, needs to be faster - i.e. saved straight to memory.
This is commonly known as "render to texture" in 3D realtime... and since Corona is OpenGL-based sounds like an appropriate term. :)
Hi,
I've been thinking about this and the only way I can see of doing it currently is to have a stationary touch event cause a screen grab into the app's resource directory; then to open a web popup near the touch with a customised, local web page which accepts parameters to load the screen grab, position and scale it appropriately using the touch coordinates.
I don't know if the web popup could be moved relative to the touch or if touch events stop getting passed to the corona app when the touch moves onto the web popup, but I've done the photoshop/html/css work to produce a magnifier which loads the scaled image.
https://files.me.com/horacebury/cxj2us
I hope someone can finish the corona code, I'm going to bed and can't work on this for a while.
Matt.
ok here's a (very rough) magnifying glass using capture screen, but it's late and i can't work out the maths to scale the movement. I didnt understand the need for the web popup in your example though
a couple of things to note
* the screen capture is scaled, then masked
* scaling the capture seems to scale the mask (bug?)
* the screen capture would also actually need to move based on the scale, otherwise you end up with the lens showing the wrong thing underneath. i've not implemented this. basically since i've magnified from the centre, as you move towards the edge the magnified bit is further away.
* it doesn't scale correctly when viewing as iPhone4 etc... need to modify some of the calculations config etc i think
if someone could post any fixes that would be great
the end target would be to have it re-capture the display anytime the user clicks on the screen/magnifying glass etc. this would mean that the main original screen would need to be static (not updating) until you let go again. essentially you're just viewing a screen capture.
also you'd probably want to overlay the graphic of a magnifying glass at the same position as the mask. it probably gets more complicated if you try to start putting them in display groups together, as the mask isnt a separate image as such , it's a part of the scaled image here
regards
J
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | display.setStatusBar( display.HiddenStatusBar ) local halfW = display.contentCenterX local halfH = display.contentCenterY local W = display.contentWidth local H = display.contentHeight local canvas = display.newGroup() local rnd = math.random for i=1, 200, 1 do local line = display.newLine(rnd()*W, rnd()*H, rnd()*W, rnd()*H) line:setColor(rnd()*255,rnd()*255,rnd()*255) canvas:insert(line) local box = display.newRect(rnd()*W, rnd()*H, 2+rnd()*50, 2+rnd()*50) box:setFillColor(rnd()*255,rnd()*255,rnd()*255) canvas:insert(box) end local canvascopy = display.captureScreen() local SCALE_RATIO = 2 canvascopy.xScale=SCALE_RATIO canvascopy.yScale=SCALE_RATIO local mask = graphics.newMask( "circlemask.png" ) canvascopy:setMask(mask) canvascopy.maskScaleX=1/SCALE_RATIO canvascopy.maskScaleY=1/SCALE_RATIO function onTouch( event ) print("touch") local t = event.target local phase = event.phase if "began" == phase then display.getCurrentStage():setFocus( t ) -- Spurious events can be sent to the target, e.g. the user presses -- elsewhere on the screen and then moves the finger over the target. -- To prevent this, we add this flag. Only when it's true will "move" -- events be sent to the target. t.isFocus = true -- Store initial position t.x0 = (event.x - t.maskX*SCALE_RATIO) t.y0 = (event.y - t.maskY*SCALE_RATIO) elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.maskX = (event.x - t.x0)/SCALE_RATIO t.maskY = (event.y - t.y0)/SCALE_RATIO elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end return true end canvascopy:addEventListener( "touch", onTouch ) |
Good work!
The web popup in my code was because we didn't have masking back then.
M
can anyone help solve this please? the inverse ratios combined with the fact that the mask is scaled with the zoomed layer is throwing me!
i've put the cap in a group and overlaid a circle to show the group moving but the screencap not moving to where it needs to be. t.canvascap.maskX needs to be changed based on the zoom ratio etc and I can't work that out.
thanks
j
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | display.setStatusBar( display.HiddenStatusBar ) local halfW = display.contentCenterX local halfH = display.contentCenterY local W = display.contentWidth local H = display.contentHeight print(W,H) local lines={} local canvas = display.newGroup() local rect=display.newRect(0,0,display.contentWidth, display.contentHeight) rect:setFillColor(0,0,0) canvas:insert(rect) local rnd = math.random for i=1, 200, 1 do local line = display.newLine(rnd()*W, rnd()*H, rnd()*W, rnd()*H) line:setColor(rnd()*255,rnd()*255,rnd()*255) canvas:insert(line) local box = display.newRect(rnd()*W, rnd()*H, 2+rnd()*50, 2+rnd()*50) box:setFillColor(rnd()*255,rnd()*255,rnd()*255) canvas:insert(box) end local canvascap = display.captureScreen() canvascopy = display.newGroup() local SCALE_RATIO = 2 canvascap.xScale=SCALE_RATIO canvascap.yScale=SCALE_RATIO local mask = graphics.newMask( "circlemask.png" ) canvascap:setMask(mask) canvas.alpha=0.7 canvascopy.alpha=1 canvascap.maskScaleX=1/SCALE_RATIO canvascap.maskScaleY=1/SCALE_RATIO canvascopy.canvascap = canvascap canvascopy:insert(canvascap) canvascopy.isHitTestable=true local circ = display.newCircle(halfW, halfH, 100) circ.alpha=0.25 canvascopy:insert(circ) function onTouch( event ) --print("touch") local t = event.target local phase = event.phase if "began" == phase then display.getCurrentStage():setFocus( t ) t.isFocus = true -- Store initial position t.x0 = (event.x - t.x) t.y0 = (event.y - t.y) elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 -- t.canvascap.maskX = (event.x - t.x0) -- t.canvascap.maskY = (event.y - t.y0) elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end return true end canvascopy:addEventListener( "touch", onTouch ) |
Here is a modification that seems to work a bit better (at least for my purposes)
The trick & change from the original is you need to move the background canvas in the opposite direction so the circlemask is always 'magnifying' the correct visible portion -- a small change but provides a more convincing result (my project file includes a picture so you can visually see it's lining up better)
There are still a few problems (the magnifier flies off screen on second click) and it doesn't work right for scale factors > 2 but as I said it seems to do a more convincing magnification
Thanks to the orginal poster actually mentioned this so this is just a (very small) clean up of that
-John
you'd need a mask. we dont have masks yet