touch_action 0.0.2alpha → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -2
- data/README.md +9 -9
- data/lib/touch_action.rb +17 -48
- data/lib/touch_action/javascripts/tap.js.erb +1 -1
- data/lib/touch_action/version.rb +1 -1
- data/spec/features/doubletap_spec.rb +13 -0
- data/spec/features/flick_spec.rb +32 -0
- data/spec/features/move_spec.rb +15 -0
- data/spec/features/pinch_spec.rb +15 -0
- data/spec/features/press_spec.rb +13 -0
- data/spec/features/rotate_spec.rb +16 -0
- data/spec/features/tap_spec.rb +20 -0
- data/spec/spec_helper.rb +56 -0
- data/spec/support/static_website/public/css/style.css +77 -0
- data/spec/support/static_website/public/images/frog.jpg +0 -0
- data/spec/support/static_website/public/index.html +198 -0
- data/spec/support/static_website/public/js/fastclick.js +805 -0
- data/spec/support/static_website/public/js/hammer.js +2463 -0
- data/spec/support/static_website/public/js/jquery-1.7.2.min.js +4 -0
- data/spec/support/static_website/public/js/jquery-2.1.1.min.js +4 -0
- data/spec/support/static_website/public/js/pinchzoom.js +761 -0
- data/spec/support/static_website/public/js/touch_square.js +0 -0
- data/spec/support/static_website/public/pinch.html +45 -0
- data/spec/support/static_website/public/tap.html +80 -0
- data/spec/support/static_website/rack_app.rb +46 -0
- data/spec/unit/watir-webdriver/element_spec.rb +11 -0
- data/touch_action.gemspec +4 -0
- metadata +102 -28
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9d3e2af6c99f3deef3611b2c7110b26f780d8dea
|
4
|
+
data.tar.gz: 165fa9f2bf25346239a51b0f6fd663f1b0c61213
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0e3e0e96f9665c9b4ff044b4e0852a3328abc5c538f14872c32dbeeced283b904aecffba0f1251e221e59b296714a705b6f74c44180ded05221f7d3e25be7657
|
7
|
+
data.tar.gz: c52e192b96ac4af15786162ac6f7729cf10bc0bb2cd5b528ded46789c27cfa023aba196158bfe43dddbac5c788ae0b17ef2ae6d687c2cc382b3c60d19c7bd8e0
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# TouchAction
|
2
2
|
|
3
|
-
|
3
|
+
Touch Action is a Ruby Gem used to add touch gestures simulation to the Watir-webdriver (and Selenium in the near future) in order to perform automated tests on mobile websites that requires those type of actions. It encapsulates the touch action library of [YUI JS](http://yuilibrary.com/yui/docs/event/simulate.html#simulating-touch-gestures). Very useful for example when testing mobile websites using [Appium](http://appium.io).
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -15,30 +15,30 @@ And then execute:
|
|
15
15
|
$ bundle
|
16
16
|
|
17
17
|
And then add `require 'touch_action'` to your spec_helper.rb or wherever you want to use it.
|
18
|
-
## WARNING
|
19
|
-
It's currently being developed and there are no tests on it. For now, it's only supporting Watir-webdriver.
|
20
18
|
|
21
19
|
## Usage
|
22
20
|
|
23
21
|
```ruby
|
24
|
-
#on the element you want to perform the action, call touch_action(:
|
22
|
+
#on the element you want to perform the action, call touch_action(:name_of_action)
|
25
23
|
element = @driver.div(:id, 'hit')
|
26
24
|
element.touch_action(:swipe)
|
27
25
|
```
|
28
26
|
###Available Gestures
|
29
|
-
|
27
|
+
|
28
|
+
It's currently supporting the gestures bellow. The only required argument is the action symbol, the rest are optional (here it's showing the default options for each action).
|
29
|
+
|
30
30
|
```ruby
|
31
|
-
element.touch_action(:flick,
|
31
|
+
element.touch_action(:flick, axis: 'x', distance: 100, duration: 50) #flick and swipe are the same
|
32
32
|
|
33
|
-
element.touch_action(:pinch,
|
33
|
+
element.touch_action(:pinch, r1: 50, r2: 100)
|
34
34
|
|
35
35
|
element.touch_action(:tap)
|
36
36
|
|
37
37
|
element.touch_action(:doubletap)
|
38
38
|
|
39
|
-
element.touch_action(:press,
|
39
|
+
element.touch_action(:press, hold: 2000)
|
40
40
|
|
41
|
-
element.touch_action(:move,
|
41
|
+
element.touch_action(:move, xdist: 70, ydist: -50, duration: 500)
|
42
42
|
|
43
43
|
element.touch_action(:rotate, {rotation: -75})
|
44
44
|
|
data/lib/touch_action.rb
CHANGED
@@ -5,57 +5,26 @@ require 'watir-webdriver'
|
|
5
5
|
|
6
6
|
module TouchAction
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def pinch_script options = {}
|
20
|
-
default_options = {r1: 50, r2: 100}
|
21
|
-
default_options.merge! options
|
22
|
-
pinch = File.read(File.expand_path("../touch_action/javascripts/pinch.js.erb", __FILE__))
|
23
|
-
render_erb(pinch_file.read, default_options)
|
24
|
-
end
|
25
|
-
|
26
|
-
def tap_script options = {}
|
27
|
-
tap = File.read(File.expand_path("../touch_action/javascripts/tap.js.erb", __FILE__))
|
28
|
-
render_erb tap
|
29
|
-
end
|
8
|
+
ACTIONS_WITH_DEFAULT_OPTIONS = {
|
9
|
+
tap: {},
|
10
|
+
doubletap: {},
|
11
|
+
flick: {axis: 'x', distance: 100, duration: 50},
|
12
|
+
pinch: {r1: 50, r2: 100},
|
13
|
+
press: {hold: 2000},
|
14
|
+
move: {xdist: 70, ydist: -50, duration: 500},
|
15
|
+
rotate: {rotation: -75}
|
16
|
+
}
|
30
17
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
press = File.read(File.expand_path("../touch_action/javascripts/press.js.erb", __FILE__))
|
40
|
-
render_erb(press, default_options)
|
41
|
-
end
|
42
|
-
|
43
|
-
def move_script options = {}
|
44
|
-
default_options = {xdist: 70, ydist: -50, duration: 2000}
|
45
|
-
default_options.merge! options
|
46
|
-
move = File.read(File.expand_path("../touch_action/javascripts/move.js.erb", __FILE__))
|
47
|
-
render_erb(move, default_options)
|
48
|
-
end
|
49
|
-
|
50
|
-
def rotate_script options = {}
|
51
|
-
default_options = {rotation: -75}
|
52
|
-
default_options.merge! options
|
53
|
-
rotate = File.read(File.expand_path("../touch_action/javascripts/rotate.js.erb", __FILE__))
|
54
|
-
render_erb(rotate, default_options)
|
18
|
+
def touch_action action, options = {}
|
19
|
+
action = :flick if action == :swipe
|
20
|
+
raise ArgumentError, "The touch action #{action} doesn't exist" unless ACTIONS_WITH_DEFAULT_OPTIONS[action]
|
21
|
+
default_options = ACTIONS_WITH_DEFAULT_OPTIONS[action]
|
22
|
+
options = default_options.merge options
|
23
|
+
script = File.read(File.expand_path("../touch_action/javascripts/#{action.to_s}.js.erb", __FILE__))
|
24
|
+
final_script = render_erb(script, options)
|
25
|
+
browser.execute_script( final_script, self )
|
55
26
|
end
|
56
27
|
|
57
|
-
alias_method :swipe_script, :flick_script
|
58
|
-
|
59
28
|
private
|
60
29
|
|
61
30
|
def render_erb template, vars = {}
|
@@ -6,7 +6,7 @@ function loadYui(callback) {
|
|
6
6
|
var head = document.getElementsByTagName('head')[0];
|
7
7
|
var script = document.createElement('script');
|
8
8
|
script.type = 'text/javascript';
|
9
|
-
script.src = "
|
9
|
+
script.src = "//yui.yahooapis.com/3.18.0/build/yui/yui-min.js";
|
10
10
|
|
11
11
|
// Then bind the event to the callback function.
|
12
12
|
// There are several events for cross browser compatibility.
|
data/lib/touch_action/version.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Doubletap" do
|
5
|
+
it 'should doubletap the div bound by HammerJS' do
|
6
|
+
@browser.goto('http://localhost:9292/tap')
|
7
|
+
element = @browser.div(id: 'myElement')
|
8
|
+
element.touch_action :doubletap
|
9
|
+
sleep(5)
|
10
|
+
expect(@browser.text).to include('doubletap')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Flick" do
|
5
|
+
it 'should flick the div bound by hammerJs' do
|
6
|
+
@browser.goto('http://localhost:9292')
|
7
|
+
div = @browser.div(id: 'hit')
|
8
|
+
div.touch_action :flick
|
9
|
+
sleep(5)
|
10
|
+
expect(@browser.p(id: 'distance_x').text).to include('100')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should flick the div bound by hammerJs when passing swipe instead of flick' do
|
14
|
+
@browser.goto('http://localhost:9292')
|
15
|
+
div = @browser.div(id: 'hit')
|
16
|
+
div.touch_action :swipe
|
17
|
+
sleep(5)
|
18
|
+
expect(@browser.p(id: 'distance_x').text).to include('100')
|
19
|
+
end
|
20
|
+
|
21
|
+
context "Options" do
|
22
|
+
|
23
|
+
it 'should flick the div bound by hammerJs to the left when passing the a negative distance' do
|
24
|
+
@browser.goto('http://localhost:9292')
|
25
|
+
div = @browser.div(id: 'hit')
|
26
|
+
div.touch_action :flick, distance: -80
|
27
|
+
sleep(5)
|
28
|
+
expect(@browser.p(id: 'distance_x').text).to include('-80')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Move" do
|
5
|
+
it 'should move the div bound by hammerJs' do
|
6
|
+
@browser.goto('http://localhost:9292')
|
7
|
+
div = @browser.div(id: 'hit')
|
8
|
+
div.touch_action :move
|
9
|
+
sleep(5)
|
10
|
+
expect(@browser.p(id: 'distance_x').text).to include('70')
|
11
|
+
expect(@browser.p(id: 'distance_y').text).to include('-50')
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Pinch" do
|
5
|
+
it 'should pinch the photo bound by pinchzoom js' do
|
6
|
+
@browser.goto('http://localhost:9292/pinch')
|
7
|
+
pinch_zoom_div = @browser.div(class: 'pinch-zoom')
|
8
|
+
last_transform_value = pinch_zoom_div.style('-webkit-transform')
|
9
|
+
element = @browser.image
|
10
|
+
element.touch_action :pinch
|
11
|
+
sleep(5)
|
12
|
+
expect(last_transform_value).not_to be_equal(pinch_zoom_div.style('-webkit-transform'))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Press" do
|
5
|
+
it 'should press the div bound by HammerJS' do
|
6
|
+
@browser.goto('http://localhost:9292/tap')
|
7
|
+
element = @browser.div(id: 'myElement')
|
8
|
+
element.touch_action :press
|
9
|
+
sleep(5)
|
10
|
+
expect(element.text).to include('press')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Rotate" do
|
5
|
+
it 'should Rotate the photo bound by pinchzoom js' do
|
6
|
+
@browser.goto('http://localhost:9292')
|
7
|
+
div = @browser.div(id: 'hit')
|
8
|
+
div.touch_action :move # don't ask me why, on this example rotate only works after a move
|
9
|
+
sleep(5)
|
10
|
+
last_transform_value = div.style('-webkit-transform')
|
11
|
+
div.touch_action :rotate
|
12
|
+
sleep(3)
|
13
|
+
expect(last_transform_value).not_to be_equal(div.style('-webkit-transform'))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe TouchAction do
|
4
|
+
describe "Tap" do
|
5
|
+
it 'should tap the div bound by HammerJS' do
|
6
|
+
@browser.goto('http://localhost:9292/tap')
|
7
|
+
element = @browser.div(id: 'myElement')
|
8
|
+
element.touch_action :tap
|
9
|
+
sleep(5)
|
10
|
+
expect(element.text).to include('tap')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should tap link bound by FastClick' do
|
14
|
+
@browser.goto('http://localhost:9292/tap')
|
15
|
+
@browser.a(id: 'fastclick').touch_action :tap
|
16
|
+
sleep(5)
|
17
|
+
expect(@browser.p(id: 'fast-click-test').text).to include('1 times')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "rspec"
|
2
|
+
require "pry"
|
3
|
+
require 'rack'
|
4
|
+
require 'thin'
|
5
|
+
require 'touch_action'
|
6
|
+
require 'watir-webdriver'
|
7
|
+
|
8
|
+
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
|
9
|
+
|
10
|
+
@server_thread = Thread.new do
|
11
|
+
Rack::Handler::Thin.run @app, :Port => 9292
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
case ENV['platform']
|
16
|
+
when 'ios'
|
17
|
+
capabilities = {
|
18
|
+
:deviceName => 'iPhone 5s',
|
19
|
+
:browserName => 'Safari',
|
20
|
+
:platformVersion => '7.1',
|
21
|
+
:platformName => 'iOS',
|
22
|
+
:app => 'safari',
|
23
|
+
:newCommandTimeout => 9999
|
24
|
+
}
|
25
|
+
|
26
|
+
when 'android'
|
27
|
+
capabilities = {
|
28
|
+
|
29
|
+
:deviceName => 'android_simulator',
|
30
|
+
:version => '4.4.2',
|
31
|
+
:platformName => 'Android',
|
32
|
+
:newCommandTimeout => 9999,
|
33
|
+
:browserName => 'Browser',
|
34
|
+
:avd => 'android_simulator',
|
35
|
+
autoAcceptAlerts: true
|
36
|
+
}
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
ENV['appium_url'] ||= "http://127.0.0.1:4723/wd/hub"
|
42
|
+
ENV['browser'] ||= 'firefox'
|
43
|
+
|
44
|
+
RSpec.configure do |config|
|
45
|
+
|
46
|
+
config.before(:each) do
|
47
|
+
if ENV['platform']
|
48
|
+
@browser = Watir::Browser.new(Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => ENV['appium_url']))
|
49
|
+
else
|
50
|
+
@browser = Watir::Browser.new ENV['browser']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
config.after(:each) do
|
54
|
+
@browser.close if @browser
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
|
2
|
+
|
3
|
+
*, *:after, *:before {
|
4
|
+
box-sizing: border-box;
|
5
|
+
-moz-box-sizing: border-box;
|
6
|
+
}
|
7
|
+
|
8
|
+
html, body {
|
9
|
+
margin: 0;
|
10
|
+
padding: 0;
|
11
|
+
height: 100%;
|
12
|
+
min-height: 100%;
|
13
|
+
background: #eee;
|
14
|
+
font: 13px/1.5em 'Open Sans', Helvetica, Arial, sans-serif;
|
15
|
+
}
|
16
|
+
|
17
|
+
a {
|
18
|
+
color: #4986e7;
|
19
|
+
}
|
20
|
+
|
21
|
+
.bg1, .green { background: #42d692; }
|
22
|
+
.bg2, .blue { background: #4986e7; }
|
23
|
+
.bg3, .red { background: #d06b64; }
|
24
|
+
.bg4, .purple { background: #cd74e6; }
|
25
|
+
.bg5, .azure { background: #9fe1e7; }
|
26
|
+
|
27
|
+
body {
|
28
|
+
margin: 20px;
|
29
|
+
}
|
30
|
+
|
31
|
+
pre {
|
32
|
+
background: #fff;
|
33
|
+
padding: 20px;
|
34
|
+
margin-bottom: 20px;
|
35
|
+
}
|
36
|
+
|
37
|
+
.container {
|
38
|
+
max-width: 900px;
|
39
|
+
margin: 0 auto;
|
40
|
+
}
|
41
|
+
|
42
|
+
.clear { clear: both; }
|
43
|
+
|
44
|
+
|
45
|
+
html, body {
|
46
|
+
overflow: hidden;
|
47
|
+
margin: 0;
|
48
|
+
}
|
49
|
+
|
50
|
+
body {
|
51
|
+
-webkit-perspective: 500;
|
52
|
+
-moz-perspective: 500;
|
53
|
+
perspective: 500;
|
54
|
+
}
|
55
|
+
|
56
|
+
.animate {
|
57
|
+
-webkit-transition: all .3s;
|
58
|
+
-moz-transition: all .3s;
|
59
|
+
transition: all .3s;
|
60
|
+
}
|
61
|
+
|
62
|
+
#hit {
|
63
|
+
padding: 10px;
|
64
|
+
}
|
65
|
+
|
66
|
+
#log {
|
67
|
+
position: absolute;
|
68
|
+
padding: 10px;
|
69
|
+
}
|
70
|
+
|
71
|
+
#myElement {
|
72
|
+
background: silver;
|
73
|
+
height: 300px;
|
74
|
+
text-align: center;
|
75
|
+
font: 30px/300px Helvetica, Arial, sans-serif;
|
76
|
+
}
|
77
|
+
|
Binary file
|
@@ -0,0 +1,198 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Touch Page Test</title>
|
6
|
+
<script type="text/javascript" src="../js/jquery-1.7.2.min.js"></script>
|
7
|
+
|
8
|
+
<script type='application/javascript' src='js/hammer.js'></script>
|
9
|
+
<link rel="stylesheet" type="text/css" href="css/style.css" />
|
10
|
+
<style type="text/css">
|
11
|
+
#blue{
|
12
|
+
position:absolute;
|
13
|
+
top:100px;
|
14
|
+
left:500px;
|
15
|
+
width:100px;
|
16
|
+
height:100px;
|
17
|
+
background-color:blue;
|
18
|
+
cursor:pointer;
|
19
|
+
right:
|
20
|
+
}
|
21
|
+
</style>
|
22
|
+
</head>
|
23
|
+
<body>
|
24
|
+
|
25
|
+
<p>Move the square to get it moving (it's using Hammer JS to recognize the touch).</p>
|
26
|
+
|
27
|
+
<p id="distance_x">Distance moved horizontaly:</p>
|
28
|
+
<br>
|
29
|
+
<p id="distance_y">Distance moved verticaly:</p>
|
30
|
+
|
31
|
+
|
32
|
+
<div id="hit" style="background: #42d692; width: 150px; height: 150px;"></div>
|
33
|
+
|
34
|
+
|
35
|
+
<script>
|
36
|
+
|
37
|
+
var reqAnimationFrame = (function () {
|
38
|
+
return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) {
|
39
|
+
window.setTimeout(callback, 1000 / 60);
|
40
|
+
};
|
41
|
+
})();
|
42
|
+
|
43
|
+
var el = document.querySelector("#hit");
|
44
|
+
|
45
|
+
var START_X = Math.round((window.innerWidth - el.offsetWidth) / 2);
|
46
|
+
var START_Y = Math.round((window.innerHeight - el.offsetHeight) / 2);
|
47
|
+
|
48
|
+
var ticking = false;
|
49
|
+
var transform;
|
50
|
+
var timer;
|
51
|
+
|
52
|
+
var mc = new Hammer.Manager(el);
|
53
|
+
|
54
|
+
mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
|
55
|
+
|
56
|
+
mc.add(new Hammer.Swipe()).recognizeWith(mc.get('pan'));
|
57
|
+
mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(mc.get('pan'));
|
58
|
+
mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get('pan'), mc.get('rotate')]);
|
59
|
+
|
60
|
+
mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }));
|
61
|
+
mc.add(new Hammer.Tap());
|
62
|
+
|
63
|
+
mc.on("panstart panmove", onPan);
|
64
|
+
mc.on("rotatestart rotatemove", onRotate);
|
65
|
+
mc.on("pinchstart pinchmove", onPinch);
|
66
|
+
mc.on("swipe", onSwipe);
|
67
|
+
mc.on("tap", onTap);
|
68
|
+
mc.on("doubletap", onDoubleTap);
|
69
|
+
|
70
|
+
mc.on("hammer.input", function(ev) {
|
71
|
+
if(ev.isFinal) {
|
72
|
+
START_X = START_X + ev.deltaX;
|
73
|
+
START_Y = START_Y + ev.deltaY;
|
74
|
+
$('#distance_x').text("Distance moved horizontaly: " + ev.deltaX);
|
75
|
+
$('#distance_y').text("Distance moved verticaly: " + ev.deltaY);
|
76
|
+
|
77
|
+
}
|
78
|
+
});
|
79
|
+
|
80
|
+
|
81
|
+
function resetElement() {
|
82
|
+
el.className = 'animate';
|
83
|
+
transform = {
|
84
|
+
translate: { x: START_X, y: START_Y },
|
85
|
+
scale: 1,
|
86
|
+
angle: 0,
|
87
|
+
rx: 0,
|
88
|
+
ry: 0,
|
89
|
+
rz: 0
|
90
|
+
};
|
91
|
+
|
92
|
+
requestElementUpdate();
|
93
|
+
|
94
|
+
|
95
|
+
}
|
96
|
+
|
97
|
+
function updateElementTransform() {
|
98
|
+
var value = [
|
99
|
+
'translate3d(' + transform.translate.x + 'px, ' + transform.translate.y + 'px, 0)',
|
100
|
+
'scale(' + transform.scale + ', ' + transform.scale + ')',
|
101
|
+
'rotate3d('+ transform.rx +','+ transform.ry +','+ transform.rz +','+ transform.angle + 'deg)'
|
102
|
+
];
|
103
|
+
|
104
|
+
value = value.join(" ");
|
105
|
+
el.textContent = value;
|
106
|
+
el.style.webkitTransform = value;
|
107
|
+
el.style.mozTransform = value;
|
108
|
+
el.style.transform = value;
|
109
|
+
ticking = false;
|
110
|
+
}
|
111
|
+
|
112
|
+
function requestElementUpdate() {
|
113
|
+
if(!ticking) {
|
114
|
+
reqAnimationFrame(updateElementTransform);
|
115
|
+
ticking = true;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
function onPan(ev) {
|
120
|
+
el.className = '';
|
121
|
+
transform.translate = {
|
122
|
+
x: START_X + ev.deltaX,
|
123
|
+
y: START_Y + ev.deltaY
|
124
|
+
};
|
125
|
+
|
126
|
+
requestElementUpdate();
|
127
|
+
|
128
|
+
}
|
129
|
+
|
130
|
+
var initScale = 1;
|
131
|
+
function onPinch(ev) {
|
132
|
+
if(ev.type == 'pinchstart') {
|
133
|
+
initScale = transform.scale || 1;
|
134
|
+
}
|
135
|
+
|
136
|
+
el.className = '';
|
137
|
+
transform.scale = initScale * ev.scale;
|
138
|
+
|
139
|
+
requestElementUpdate();
|
140
|
+
|
141
|
+
}
|
142
|
+
|
143
|
+
var initAngle = 0;
|
144
|
+
function onRotate(ev) {
|
145
|
+
if(ev.type == 'rotatestart') {
|
146
|
+
initAngle = transform.angle || 0;
|
147
|
+
}
|
148
|
+
|
149
|
+
el.className = '';
|
150
|
+
transform.rz = 1;
|
151
|
+
transform.angle = initAngle + ev.rotation;
|
152
|
+
requestElementUpdate();
|
153
|
+
|
154
|
+
}
|
155
|
+
|
156
|
+
function onSwipe(ev) {
|
157
|
+
var angle = 50;
|
158
|
+
transform.ry = (ev.direction & Hammer.DIRECTION_HORIZONTAL) ? 1 : 0;
|
159
|
+
transform.rx = (ev.direction & Hammer.DIRECTION_VERTICAL) ? 1 : 0;
|
160
|
+
transform.angle = (ev.direction & (Hammer.DIRECTION_RIGHT | Hammer.DIRECTION_UP)) ? angle : -angle;
|
161
|
+
|
162
|
+
clearTimeout(timer);
|
163
|
+
timer = setTimeout(function () {
|
164
|
+
resetElement();
|
165
|
+
}, 300);
|
166
|
+
requestElementUpdate();
|
167
|
+
|
168
|
+
}
|
169
|
+
|
170
|
+
function onTap(ev) {
|
171
|
+
transform.rx = 1;
|
172
|
+
transform.angle = 25;
|
173
|
+
|
174
|
+
clearTimeout(timer);
|
175
|
+
timer = setTimeout(function () {
|
176
|
+
resetElement();
|
177
|
+
}, 200);
|
178
|
+
requestElementUpdate();
|
179
|
+
|
180
|
+
}
|
181
|
+
|
182
|
+
function onDoubleTap(ev) {
|
183
|
+
transform.rx = 1;
|
184
|
+
transform.angle = 80;
|
185
|
+
|
186
|
+
clearTimeout(timer);
|
187
|
+
timer = setTimeout(function () {
|
188
|
+
resetElement();
|
189
|
+
}, 500);
|
190
|
+
requestElementUpdate();
|
191
|
+
|
192
|
+
}
|
193
|
+
|
194
|
+
resetElement();
|
195
|
+
|
196
|
+
</script>
|
197
|
+
</body>
|
198
|
+
</html>
|