mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 06:57:02 +08:00
Weather improvements and scroll fixes
This commit is contained in:
36
dist/js/ionic.js
vendored
36
dist/js/ionic.js
vendored
@ -2501,17 +2501,21 @@ window.ionic = {
|
||||
this.resistance = opts.resistance;
|
||||
|
||||
// Listen for drag and release events
|
||||
window.ionic.onGesture('drag', function(e) {
|
||||
ionic.onGesture('drag', function(e) {
|
||||
_this._handleDrag(e);
|
||||
}, this.el);
|
||||
window.ionic.onGesture('release', function(e) {
|
||||
ionic.onGesture('release', function(e) {
|
||||
_this._handleEndDrag(e);
|
||||
}, this.el);
|
||||
ionic.on('webkitTransitionEnd', function(e) {
|
||||
_this._endTransition();
|
||||
});
|
||||
};
|
||||
|
||||
ionic.views.Scroll.prototype = {
|
||||
DECEL_RATE_NORMAL: 0.998,
|
||||
DECEL_RATE_FAST: 0.99,
|
||||
DECEL_RATE_SLOW: 0.996,
|
||||
|
||||
/**
|
||||
* Scroll to the given X and Y point, taking
|
||||
@ -2531,15 +2535,22 @@ window.ionic = {
|
||||
el.style.webkitTransitionTimingFunction = easing;
|
||||
el.style.webkitTransitionDuration = time;
|
||||
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
||||
console.log('TRANSITION ADDED!');
|
||||
},
|
||||
|
||||
|
||||
_initDrag: function() {
|
||||
this._endTransition();
|
||||
this._isStopped = false;
|
||||
},
|
||||
|
||||
_endTransition: function() {
|
||||
this._isDragging = false;
|
||||
this._drag = null;
|
||||
this.el.classList.remove('scroll-scrolling');
|
||||
this.el.style.webkitTransitionDuration = '0';
|
||||
|
||||
console.log('REMOVING TRANSITION');
|
||||
this.el.style.webkitTransitionDuration = '0';
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2569,6 +2580,11 @@ window.ionic = {
|
||||
window.requestAnimationFrame(function() {
|
||||
var content;
|
||||
|
||||
if(_this._isStopped) {
|
||||
_this._initDrag();
|
||||
return;
|
||||
}
|
||||
|
||||
// We really aren't dragging
|
||||
if(!_this._drag) {
|
||||
_this._startDrag(e);
|
||||
@ -2600,18 +2616,18 @@ window.ionic = {
|
||||
},
|
||||
|
||||
_handleEndDrag: function(e) {
|
||||
var _this = this;
|
||||
|
||||
// We didn't have a drag, so just init and leave
|
||||
if(!_this._drag) {
|
||||
_this._initDrag();
|
||||
if(!this._drag) {
|
||||
this._initDrag();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a flag in case we don't cleanup completely after the
|
||||
// drag animation so we can cleanup the next time a drag starts
|
||||
this._isStopped = true;
|
||||
|
||||
// Animate to the finishing point
|
||||
_this._animateToStop(e);
|
||||
// Cleanup
|
||||
_this._initDrag();
|
||||
this._animateToStop(e);
|
||||
|
||||
},
|
||||
|
||||
|
||||
@ -17,17 +17,21 @@
|
||||
this.resistance = opts.resistance;
|
||||
|
||||
// Listen for drag and release events
|
||||
window.ionic.onGesture('drag', function(e) {
|
||||
ionic.onGesture('drag', function(e) {
|
||||
_this._handleDrag(e);
|
||||
}, this.el);
|
||||
window.ionic.onGesture('release', function(e) {
|
||||
ionic.onGesture('release', function(e) {
|
||||
_this._handleEndDrag(e);
|
||||
}, this.el);
|
||||
ionic.on('webkitTransitionEnd', function(e) {
|
||||
_this._endTransition();
|
||||
});
|
||||
};
|
||||
|
||||
ionic.views.Scroll.prototype = {
|
||||
DECEL_RATE_NORMAL: 0.998,
|
||||
DECEL_RATE_FAST: 0.99,
|
||||
DECEL_RATE_SLOW: 0.996,
|
||||
|
||||
/**
|
||||
* Scroll to the given X and Y point, taking
|
||||
@ -47,15 +51,22 @@
|
||||
el.style.webkitTransitionTimingFunction = easing;
|
||||
el.style.webkitTransitionDuration = time;
|
||||
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
||||
console.log('TRANSITION ADDED!');
|
||||
},
|
||||
|
||||
|
||||
_initDrag: function() {
|
||||
this._endTransition();
|
||||
this._isStopped = false;
|
||||
},
|
||||
|
||||
_endTransition: function() {
|
||||
this._isDragging = false;
|
||||
this._drag = null;
|
||||
this.el.classList.remove('scroll-scrolling');
|
||||
this.el.style.webkitTransitionDuration = '0';
|
||||
|
||||
console.log('REMOVING TRANSITION');
|
||||
this.el.style.webkitTransitionDuration = '0';
|
||||
},
|
||||
|
||||
/**
|
||||
@ -85,6 +96,11 @@
|
||||
window.requestAnimationFrame(function() {
|
||||
var content;
|
||||
|
||||
if(_this._isStopped) {
|
||||
_this._initDrag();
|
||||
return;
|
||||
}
|
||||
|
||||
// We really aren't dragging
|
||||
if(!_this._drag) {
|
||||
_this._startDrag(e);
|
||||
@ -116,18 +132,18 @@
|
||||
},
|
||||
|
||||
_handleEndDrag: function(e) {
|
||||
var _this = this;
|
||||
|
||||
// We didn't have a drag, so just init and leave
|
||||
if(!_this._drag) {
|
||||
_this._initDrag();
|
||||
if(!this._drag) {
|
||||
this._initDrag();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a flag in case we don't cleanup completely after the
|
||||
// drag animation so we can cleanup the next time a drag starts
|
||||
this._isStopped = true;
|
||||
|
||||
// Animate to the finishing point
|
||||
_this._animateToStop(e);
|
||||
// Cleanup
|
||||
_this._initDrag();
|
||||
this._animateToStop(e);
|
||||
|
||||
},
|
||||
|
||||
|
||||
16
starters/weather/app.js
Normal file
16
starters/weather/app.js
Normal file
@ -0,0 +1,16 @@
|
||||
angular.module('ionic.weather', ['ionic.weather.services', 'ionic.weather.directives'])
|
||||
|
||||
.constant('API_KEY', '1cc2d3de40fa5af0')
|
||||
|
||||
.filter('int', function() {
|
||||
return function(v) {
|
||||
return parseInt(v) || '';
|
||||
};
|
||||
})
|
||||
|
||||
.controller('WeatherCtrl', function($scope, Weather) {
|
||||
|
||||
Weather.getAtCurrentLocation(function(resp) {
|
||||
$scope.current = resp.current_observation;
|
||||
});
|
||||
});
|
||||
58
starters/weather/directives.js
Normal file
58
starters/weather/directives.js
Normal file
@ -0,0 +1,58 @@
|
||||
angular.module('ionic.weather.directives', [])
|
||||
|
||||
.directive('currentTime', function($timeout, $filter) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
template: '<span class="current-time">{{currentTime}}</span>',
|
||||
scope: {
|
||||
localtz: '=',
|
||||
localTime: '='
|
||||
},
|
||||
link: function($scope, $element, $attr) {
|
||||
$timeout(function checkTime() {
|
||||
if($scope.localTime && $scope.localtz) {
|
||||
$scope.currentTime = $filter('date')(parseInt($scope.localTime), 'h:mm') + $scope.localtz;
|
||||
}
|
||||
$timeout(checkTime, 500);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.directive('smallWeather', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: '<div id="small-weather" ng-transclude></div>',
|
||||
link: function($scope, $element, $attr) {
|
||||
|
||||
// Delay so we are in the DOM and can calculate sizes
|
||||
$timeout(function() {
|
||||
var windowHeight = window.innerHeight;
|
||||
var thisHeight = $element[0].offsetHeight;
|
||||
var headerHeight = document.querySelector('#header').offsetHeight;
|
||||
$element[0].style.marginTop = (windowHeight - thisHeight) + 'px';
|
||||
angular.element(document.querySelector('.content')).css('-webkit-overflow-scrolling', 'auto');
|
||||
$timeout(function() {
|
||||
angular.element(document.querySelector('.content')).css('-webkit-overflow-scrolling', 'touch');
|
||||
}, 50);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.directive('weatherBox', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
scope: {
|
||||
title: '@'
|
||||
},
|
||||
template: '<div class="weather-box"><h4 class="title">{{title}}</h4><div ng-transclude></div></div>',
|
||||
link: function($scope, $element, $attr) {
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1,4 +1,4 @@
|
||||
<html ng-app="ionic.example">
|
||||
<html ng-app="ionic.weather">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Weather</title>
|
||||
@ -12,101 +12,39 @@
|
||||
<script src="/vendor/angular/angular-1.2.0rc2.min.js"></script>
|
||||
<script src="/vendor/angular/angular-touch.js"></script>
|
||||
<script src="/vendor/angular/angular-animate.js"></script>
|
||||
<script src="/vendor/angular/angular-resource.js"></script>
|
||||
<script src="/dist/js/ionic.js"></script>
|
||||
<script src="/dist/js/ionic-angular.js"></script>
|
||||
|
||||
<script src="services.js"></script>
|
||||
<script src="directives.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</head>
|
||||
<body ng-controller="WeatherCtrl">
|
||||
<header id="header" class="bar bar-header bar-clear">
|
||||
<button class="button button-icon"><i class="icon-navicon-round"></i></button>
|
||||
<h1 class="title">
|
||||
<span class="city">{{current.city.name}}</span><br>
|
||||
<current-time></current-time>
|
||||
<span class="city">{{current.display_location.city}}</span><br>
|
||||
<current-time local-time="current.local_epoch" localtz="current.local_tz_short"></current-time>
|
||||
</h1>
|
||||
</header>
|
||||
<content id="main-content" has-header="true" padded="true">
|
||||
<div id="scroller" class="scroll padding" style="margin-top:44px">
|
||||
<small-weather>
|
||||
<h5>{{current.cover}}</h5>
|
||||
<h5>{{current.weather}}</h5>
|
||||
<h5>H: {{current.high}} L: {{current.low}}</h5>
|
||||
<h1 class="current-temp">{{current.temp}}°</h1>
|
||||
<h1 class="current-temp">{{current.temp_f | int}}°</h1>
|
||||
</small-weather>
|
||||
<weather-box title="Forecast" style="height: 400px">
|
||||
</weather-box>
|
||||
<weather-box title="Details" style="height: 400px">
|
||||
</weather-box>
|
||||
</content>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
angular.module('ionic.example', ['ionic.ui.content'])
|
||||
|
||||
.directive('currentTime', function($timeout, $filter) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
template: '<span class="current-time">{{currentTime}}</span>',
|
||||
link: function($scope, $element, $attr) {
|
||||
$timeout(function checkTime() {
|
||||
$scope.currentTime = $filter('date')(new Date, 'H:mm');
|
||||
$timeout(checkTime, 500);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.directive('smallWeather', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: '<div id="small-weather" ng-transclude></div>',
|
||||
link: function($scope, $element, $attr) {
|
||||
|
||||
// Delay so we are in the DOM and can calculate sizes
|
||||
$timeout(function() {
|
||||
var windowHeight = window.innerHeight;
|
||||
var thisHeight = $element[0].offsetHeight;
|
||||
var headerHeight = document.querySelector('#header').offsetHeight;
|
||||
$element[0].style.marginTop = (windowHeight - thisHeight) + 'px';
|
||||
angular.element(document.querySelector('.content')).css('-webkit-overflow-scrolling', 'auto');
|
||||
$timeout(function() {
|
||||
angular.element(document.querySelector('.content')).css('-webkit-overflow-scrolling', 'touch');
|
||||
}, 50);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.directive('weatherBox', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
scope: {
|
||||
title: '@'
|
||||
},
|
||||
template: '<div class="weather-box"><h4 class="title">{{title}}</h4><div ng-transclude></div></div>',
|
||||
link: function($scope, $element, $attr) {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
.filter('temp', function() {
|
||||
return function(v) {
|
||||
return v + '°';
|
||||
};
|
||||
})
|
||||
|
||||
.controller('WeatherCtrl', function($scope) {
|
||||
$scope.current = {
|
||||
city: {
|
||||
name: 'Madison'
|
||||
},
|
||||
temp: 36,
|
||||
cover: 'Partly cloudy',
|
||||
high: 43,
|
||||
low: 27
|
||||
}
|
||||
var s = document.getElementById('scroller');
|
||||
var scroll = new ionic.views.Scroll({
|
||||
el: s,
|
||||
decelerationRate: 0.87
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
||||
BIN
starters/weather/madison3.jpg
Normal file
BIN
starters/weather/madison3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
BIN
starters/weather/madison4.jpg
Normal file
BIN
starters/weather/madison4.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
30
starters/weather/services.js
Normal file
30
starters/weather/services.js
Normal file
@ -0,0 +1,30 @@
|
||||
angular.module('ionic.weather.services', ['ngResource'])
|
||||
|
||||
.factory('Weather', function($resource, API_KEY) {
|
||||
var baseUrl = 'http://api.wunderground.com/api/' + API_KEY;
|
||||
|
||||
var locationResource = $resource(baseUrl + '/geolookup/conditions/q/:coords.json', {
|
||||
callback: 'JSON_CALLBACK'
|
||||
}, {
|
||||
get: {
|
||||
method: 'JSONP'
|
||||
}
|
||||
});
|
||||
return {
|
||||
getAtCurrentLocation: function(cb) {
|
||||
var _this = this;
|
||||
|
||||
navigator.geolocation.getCurrentPosition(function(position) {
|
||||
_this.getAtLocation(position.coords.latitude, position.coords.longitude, cb);
|
||||
}, function(error) {
|
||||
alert('Unable to get current location: ' + error);
|
||||
});
|
||||
|
||||
},
|
||||
getAtLocation: function(lat,lng, cb) {
|
||||
locationResource.get({
|
||||
coords: lat + ',' + lng
|
||||
}, cb);
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1,5 +1,5 @@
|
||||
body {
|
||||
background: url('madison2.jpg') no-repeat transparent;
|
||||
background: url('madison3.jpg') no-repeat transparent;
|
||||
background-size: cover;
|
||||
}
|
||||
h1,h2,h3,h4,h5 {
|
||||
@ -11,6 +11,9 @@ h1,h2,h3,h4,h5 {
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
#header .title .city {
|
||||
font-size: 16px;
|
||||
}
|
||||
#main-content {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
BIN
starters/weather/wunderground.png
Normal file
BIN
starters/weather/wunderground.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@ -11,6 +11,9 @@
|
||||
border-top: 10px solid red;
|
||||
border-bottom: 10px solid red;
|
||||
}
|
||||
.list-item {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user