touch_action 0.0.2alpha → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>
|