UNPKG

6.87 kBJavaScriptView Raw
1/*
2Copyright 2013-2015 ASIAL CORPORATION
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15
16*/
17
18import MicroEvent from './microevent';
19
20var create = function create() {
21
22 /**
23 * @object ons.orientation
24 * @category util
25 * @description
26 * [en]Utility methods for orientation detection.[/en]
27 * [ja]画面のオリエンテーション検知のためのユーティリティメソッドを収めているオブジェクトです。[/ja]
28 */
29 var obj = {
30 /**
31 * @event change
32 * @description
33 * [en]Fired when the device orientation changes.[/en]
34 * [ja]デバイスのオリエンテーションが変化した際に発火します。[/ja]
35 * @param {Object} event
36 * [en]Event object.[/en]
37 * [ja]イベントオブジェクトです。[/ja]
38 * @param {Boolean} event.isPortrait
39 * [en]Will be true if the current orientation is portrait mode.[/en]
40 * [ja]現在のオリエンテーションがportraitの場合にtrueを返します。[/ja]
41 */
42
43 /**
44 * @method on
45 * @signature on(eventName, listener)
46 * @description
47 * [en]Add an event listener.[/en]
48 * [ja]イベントリスナーを追加します。[/ja]
49 * @param {String} eventName
50 * [en]Name of the event.[/en]
51 * [ja]イベント名を指定します。[/ja]
52 * @param {Function} listener
53 * [en]Function to execute when the event is triggered.[/en]
54 * [ja]このイベントが発火された際に呼び出される関数オブジェクトを指定します。[/ja]
55 */
56
57 /**
58 * @method once
59 * @signature once(eventName, listener)
60 * @description
61 * [en]Add an event listener that's only triggered once.[/en]
62 * [ja]一度だけ呼び出されるイベントリスナーを追加します。[/ja]
63 * @param {String} eventName
64 * [en]Name of the event.[/en]
65 * [ja]イベント名を指定します。[/ja]
66 * @param {Function} listener
67 * [en]Function to execute when the event is triggered.[/en]
68 * [ja]イベントが発火した際に呼び出される関数オブジェクトを指定します。[/ja]
69 */
70
71 /**
72 * @method off
73 * @signature off(eventName, [listener])
74 * @description
75 * [en]Remove an event listener. If the listener is not specified all listeners for the event type will be removed.[/en]
76 * [ja]イベントリスナーを削除します。もしイベントリスナーを指定しなかった場合には、そのイベントに紐づく全てのイベントリスナーが削除されます。[/ja]
77 * @param {String} eventName
78 * [en]Name of the event.[/en]
79 * [ja]イベント名を指定します。[/ja]
80 * @param {Function} listener
81 * [en]Function to execute when the event is triggered.[/en]
82 * [ja]削除するイベントリスナーを指定します。[/ja]
83 */
84
85 // actual implementation to detect if whether current screen is portrait or not
86 _isPortrait: false,
87
88 /**
89 * @method isPortrait
90 * @signature isPortrait()
91 * @return {Boolean}
92 * [en]Will be true if the current orientation is portrait mode.[/en]
93 * [ja]オリエンテーションがportraitモードの場合にtrueになります。[/ja]
94 * @description
95 * [en]Returns whether the current screen orientation is portrait or not.[/en]
96 * [ja]オリエンテーションがportraitモードかどうかを返します。[/ja]
97 */
98 isPortrait: function isPortrait() {
99 return this._isPortrait();
100 },
101
102 /**
103 * @method isLandscape
104 * @signature isLandscape()
105 * @return {Boolean}
106 * [en]Will be true if the current orientation is landscape mode.[/en]
107 * [ja]オリエンテーションがlandscapeモードの場合にtrueになります。[/ja]
108 * @description
109 * [en]Returns whether the current screen orientation is landscape or not.[/en]
110 * [ja]オリエンテーションがlandscapeモードかどうかを返します。[/ja]
111 */
112 isLandscape: function isLandscape() {
113 return !this.isPortrait();
114 },
115
116 _init: function _init() {
117 document.addEventListener('DOMContentLoaded', this._onDOMContentLoaded.bind(this), false);
118
119 if ('orientation' in window) {
120 window.addEventListener('orientationchange', this._onOrientationChange.bind(this), false);
121 } else {
122 window.addEventListener('resize', this._onResize.bind(this), false);
123 }
124
125 this._isPortrait = function () {
126 return window.innerHeight > window.innerWidth;
127 };
128
129 return this;
130 },
131
132 _onDOMContentLoaded: function _onDOMContentLoaded() {
133 this._installIsPortraitImplementation();
134 this.emit('change', { isPortrait: this.isPortrait() });
135 },
136
137 _installIsPortraitImplementation: function _installIsPortraitImplementation() {
138 var isPortrait = window.innerWidth < window.innerHeight;
139
140 if (!('orientation' in window)) {
141 this._isPortrait = function () {
142 return window.innerHeight > window.innerWidth;
143 };
144 } else if (window.orientation % 180 === 0) {
145 this._isPortrait = function () {
146 return Math.abs(window.orientation % 180) === 0 ? isPortrait : !isPortrait;
147 };
148 } else {
149 this._isPortrait = function () {
150 return Math.abs(window.orientation % 180) === 90 ? isPortrait : !isPortrait;
151 };
152 }
153 },
154
155 _onOrientationChange: function _onOrientationChange() {
156 var _this = this;
157
158 var isPortrait = this._isPortrait();
159
160 // Wait for the dimensions to change because
161 // of Android inconsistency.
162 var nIter = 0;
163 var interval = setInterval(function () {
164 nIter++;
165
166 var w = window.innerWidth;
167 var h = window.innerHeight;
168
169 if (isPortrait && w <= h || !isPortrait && w >= h) {
170 _this.emit('change', { isPortrait: isPortrait });
171 clearInterval(interval);
172 } else if (nIter === 50) {
173 _this.emit('change', { isPortrait: isPortrait });
174 clearInterval(interval);
175 }
176 }, 20);
177 },
178
179 // Run on not mobile browser.
180 _onResize: function _onResize() {
181 this.emit('change', { isPortrait: this.isPortrait() });
182 }
183 };
184
185 MicroEvent.mixin(obj);
186
187 return obj;
188};
189
190export default create()._init();
\No newline at end of file