VulpesOS/assets/webapps/camera.gaiamobile.org/js/views/zoom-bar.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

170 lines
No EOL
6.2 KiB
JavaScript

define([
'require',
'exports',
'module',
'debug',
'view',
'lib/bind',
'lib/orientation'
], function (require, exports, module) {
'use strict';
var debug = require('debug')('view:zoom-bar');
var View = require('view');
var bind = require('lib/bind');
var orientation = require('lib/orientation');
var lastTouch = null;
var clamp = function (value, minimum, maximum) {
return Math.min(Math.max(value, minimum), maximum);
};
module.exports = View.extend({
name: 'zoom-bar',
initialize: function () {
this.render();
this._orientation = orientation.get();
this.zoomBarIndicatorInterval = 10;
this.zoomBarInactivityTimeout = 3000;
},
render: function () {
this.el.innerHTML = this.template();
this.els.maxIndicator = this.find('.zoom-bar-max-indicator');
this.els.minIndicator = this.find('.zoom-bar-min-indicator');
this.els.inner = this.find('.zoom-bar-inner');
this.els.track = this.find('.zoom-bar-track');
this.els.scrubber = this.find('.zoom-bar-scrubber');
delete this.template;
debug('rendered');
return this.bindEvents();
},
bindEvents: function () {
bind(this.els.scrubber, 'touchstart', this.onTouchStart);
bind(this.els.scrubber, 'touchmove', this.onTouchMove);
bind(this.els.scrubber, 'touchend', this.onTouchEnd);
bind(this.els.maxIndicator, 'click', this.onIncrement);
bind(this.els.minIndicator, 'click', this.onDecrement);
orientation.on('orientation', this.setOrientation);
return this;
},
template: function () {
return '<div class="zoom-bar-max-indicator"></div>' + '<div class="zoom-bar-inner">' + '<div class="zoom-bar-track"></div>' + '<div class="zoom-bar-scrubber"></div>' + '</div>' + '<div class="zoom-bar-min-indicator"></div>';
},
onTouchStart: function (evt) {
lastTouch = evt.touches[0];
this.resetInactivityTimeout();
this.setScrubberActive(true);
this._innerHeight = this.els.inner.offsetHeight;
evt.stopPropagation();
},
onTouchMove: function (evt) {
if (!lastTouch) {
return;
}
var touch = evt.touches[0];
var deltaX = lastTouch.pageX - touch.pageX;
var deltaY = lastTouch.pageY - touch.pageY;
var scale = 100 / this._innerHeight;
deltaX *= scale;
deltaY *= scale;
switch (this._orientation) {
case 0:
this.setValue(this._value + deltaY, true);
break;
case 90:
this.setValue(this._value + deltaX, true);
break;
case 180:
this.setValue(this._value - deltaY, true);
break;
case 270:
this.setValue(this._value - deltaX, true);
break;
}
lastTouch = touch;
},
onTouchEnd: function (evt) {
if (!lastTouch) {
return;
}
lastTouch = null;
this.resetInactivityTimeout();
this.setScrubberActive(false);
},
onIncrement: function (evt) {
this.setValue(this._value + this.zoomBarIndicatorInterval, true);
this.flashScrubberActive();
evt.stopPropagation();
},
onDecrement: function (evt) {
this.setValue(this._value - this.zoomBarIndicatorInterval, true);
this.flashScrubberActive();
evt.stopPropagation();
},
_orientation: 0,
setOrientation: function (orientation) {
var el = this.el;
el.classList.remove('zooming');
window.requestAnimationFrame(function () {
el.style.transitionDuration = '0ms';
window.requestAnimationFrame(function () {
el.style.transitionDuration = '';
});
});
this._orientation = orientation;
},
_value: 0,
setValue: function (value, emitChange) {
this.resetInactivityTimeout();
var lastValue = this._value;
this._value = clamp(value, 0, 100);
if (this._value === lastValue) {
return;
}
if (this._value === 0) {
this.els.minIndicator.classList.add('active');
} else {
this.els.minIndicator.classList.remove('active');
}
if (this._value === 100) {
this.els.maxIndicator.classList.add('active');
} else {
this.els.maxIndicator.classList.remove('active');
}
var self = this;
window.requestAnimationFrame(function () {
self.els.track.style.top = 100 - self._value + '%';
self.els.scrubber.style.bottom = self._value + '%';
});
if (emitChange) {
this.emit('change', this._value);
}
},
setScrubberActive: function (active) {
window.clearTimeout(this._scrubberTimeout);
if (active) {
this.els.scrubber.classList.add('active');
} else {
this.els.scrubber.classList.remove('active');
}
},
flashScrubberActive: function () {
this.setScrubberActive(true);
var self = this;
this._scrubberTimeout = window.setTimeout(function () {
self.setScrubberActive(false);
}, 150);
},
resetInactivityTimeout: function () {
window.clearTimeout(this._inactivityTimeout);
this.show();
var self = this;
this._inactivityTimeout = window.setTimeout(function () {
self.hide();
}, this.zoomBarInactivityTimeout);
},
show: function () {
this.el.classList.add('zooming');
},
hide: function () {
this.el.classList.remove('zooming');
}
});
});