Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Codea gesture manager (pinch, move)
--[[
# Gesture manager class
This class is used to perform graphic transformations such as pinch and move.
Feel free to modify this class as you need or as you want.
# Usage
```
function setup() gestures = GestureManager() end
function touched(touch) gestures:touched(touch) end
function draw()
pushMatrix()
gestures:apply()
-- draw your map
popMatrix()
end
```
]]
GestureManager = class()
local function create_vec2_from_vec3(v3)
return vec2(v3.x, v3.y)
end
local function get_distance_vec3(touch1, touch2)
local touch1_2d = create_vec2_from_vec3(touch1)
local touch2_2d = create_vec2_from_vec3(touch2)
return touch1_2d:dist(touch2_2d)
end
function GestureManager:init()
self.touch1 = vec3(0, 0, 0)
self.touch2 = vec3(0, 0, 0)
self.scale = 1
self.translation = vec2(0, 0)
end
function GestureManager:get_translation()
return self.translation.x, self.translation.y
end
function GestureManager:get_scale()
return self.scale
end
function GestureManager:apply()
scale(self:get_scale())
translate(self:get_translation())
end
function GestureManager:touched(touch)
if touch.state == BEGAN then
local touch_pos = vec3(touch.x, touch.y, touch.id)
if self.touch1.z == 0 then
self.touch1 = touch_pos
elseif self.touch2.z == 0 then
self.touch2 = touch_pos
end
elseif touch.state == CHANGED then
local old_touch1 = self.touch1
local old_touch2 = self.touch2
local touch_pos = vec3(touch.x, touch.y, touch.id)
if self.touch1.z == touch.id then
self.touch1 = touch_pos
elseif self.touch2.z == touch.id then
self.touch2 = touch_pos
end
if self.touch1.z ~= 0 and self.touch2.z == 0 then
self.translation.x = self.translation.x + (self.touch1.x - old_touch1.x) / self.scale
self.translation.y = self.translation.y + (self.touch1.y - old_touch1.y) / self.scale
elseif self.touch1.z ~= 0 and self.touch2.z ~= 0 then
local old_center = vec2((old_touch1.x + old_touch2.x) / 2, (old_touch1.y + old_touch2.y) / 2)
local new_center = vec2((self.touch1.x + self.touch2.x) / 2, (self.touch1.y + self.touch2.y) / 2)
local old_distance = get_distance_vec3(old_touch1, old_touch2)
local distance = get_distance_vec3(self.touch1, self.touch2)
local scale_multiplier = distance / old_distance
local new_scale = self.scale * scale_multiplier
local old_width = WIDTH / self.scale
local new_width = WIDTH / new_scale
local width_diff = new_width - old_width
self.translation.x = self.translation.x + new_center.x / WIDTH * width_diff
local old_height = HEIGHT / self.scale
local new_height = HEIGHT / new_scale
local height_diff = new_height - old_height
self.translation.y = self.translation.y + new_center.y / HEIGHT * height_diff
self.scale = new_scale
self.translation = self.translation + (new_center - old_center) / self.scale
end
elseif touch.state == ENDED then
if self.touch1.z == touch.id then
self.touch1 = vec3(0, 0, 0)
elseif self.touch2.z == touch.id then
self.touch2 = vec3(0, 0, 0)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment