mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 15:07:13 +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;
|
this.resistance = opts.resistance;
|
||||||
|
|
||||||
// Listen for drag and release events
|
// Listen for drag and release events
|
||||||
window.ionic.onGesture('drag', function(e) {
|
ionic.onGesture('drag', function(e) {
|
||||||
_this._handleDrag(e);
|
_this._handleDrag(e);
|
||||||
}, this.el);
|
}, this.el);
|
||||||
window.ionic.onGesture('release', function(e) {
|
ionic.onGesture('release', function(e) {
|
||||||
_this._handleEndDrag(e);
|
_this._handleEndDrag(e);
|
||||||
}, this.el);
|
}, this.el);
|
||||||
|
ionic.on('webkitTransitionEnd', function(e) {
|
||||||
|
_this._endTransition();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ionic.views.Scroll.prototype = {
|
ionic.views.Scroll.prototype = {
|
||||||
DECEL_RATE_NORMAL: 0.998,
|
DECEL_RATE_NORMAL: 0.998,
|
||||||
DECEL_RATE_FAST: 0.99,
|
DECEL_RATE_FAST: 0.99,
|
||||||
|
DECEL_RATE_SLOW: 0.996,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll to the given X and Y point, taking
|
* Scroll to the given X and Y point, taking
|
||||||
@ -2531,15 +2535,22 @@ window.ionic = {
|
|||||||
el.style.webkitTransitionTimingFunction = easing;
|
el.style.webkitTransitionTimingFunction = easing;
|
||||||
el.style.webkitTransitionDuration = time;
|
el.style.webkitTransitionDuration = time;
|
||||||
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
||||||
|
console.log('TRANSITION ADDED!');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_initDrag: function() {
|
_initDrag: function() {
|
||||||
|
this._endTransition();
|
||||||
|
this._isStopped = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_endTransition: function() {
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
this.el.classList.remove('scroll-scrolling');
|
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() {
|
window.requestAnimationFrame(function() {
|
||||||
var content;
|
var content;
|
||||||
|
|
||||||
|
if(_this._isStopped) {
|
||||||
|
_this._initDrag();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We really aren't dragging
|
// We really aren't dragging
|
||||||
if(!_this._drag) {
|
if(!_this._drag) {
|
||||||
_this._startDrag(e);
|
_this._startDrag(e);
|
||||||
@ -2600,18 +2616,18 @@ window.ionic = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleEndDrag: function(e) {
|
_handleEndDrag: function(e) {
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
// We didn't have a drag, so just init and leave
|
// We didn't have a drag, so just init and leave
|
||||||
if(!_this._drag) {
|
if(!this._drag) {
|
||||||
_this._initDrag();
|
this._initDrag();
|
||||||
return;
|
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
|
// Animate to the finishing point
|
||||||
_this._animateToStop(e);
|
this._animateToStop(e);
|
||||||
// Cleanup
|
|
||||||
_this._initDrag();
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -17,17 +17,21 @@
|
|||||||
this.resistance = opts.resistance;
|
this.resistance = opts.resistance;
|
||||||
|
|
||||||
// Listen for drag and release events
|
// Listen for drag and release events
|
||||||
window.ionic.onGesture('drag', function(e) {
|
ionic.onGesture('drag', function(e) {
|
||||||
_this._handleDrag(e);
|
_this._handleDrag(e);
|
||||||
}, this.el);
|
}, this.el);
|
||||||
window.ionic.onGesture('release', function(e) {
|
ionic.onGesture('release', function(e) {
|
||||||
_this._handleEndDrag(e);
|
_this._handleEndDrag(e);
|
||||||
}, this.el);
|
}, this.el);
|
||||||
|
ionic.on('webkitTransitionEnd', function(e) {
|
||||||
|
_this._endTransition();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ionic.views.Scroll.prototype = {
|
ionic.views.Scroll.prototype = {
|
||||||
DECEL_RATE_NORMAL: 0.998,
|
DECEL_RATE_NORMAL: 0.998,
|
||||||
DECEL_RATE_FAST: 0.99,
|
DECEL_RATE_FAST: 0.99,
|
||||||
|
DECEL_RATE_SLOW: 0.996,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll to the given X and Y point, taking
|
* Scroll to the given X and Y point, taking
|
||||||
@ -47,15 +51,22 @@
|
|||||||
el.style.webkitTransitionTimingFunction = easing;
|
el.style.webkitTransitionTimingFunction = easing;
|
||||||
el.style.webkitTransitionDuration = time;
|
el.style.webkitTransitionDuration = time;
|
||||||
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
el.style.webkitTransform = 'translate3d(0,' + y + 'px, 0)';
|
||||||
|
console.log('TRANSITION ADDED!');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_initDrag: function() {
|
_initDrag: function() {
|
||||||
|
this._endTransition();
|
||||||
|
this._isStopped = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_endTransition: function() {
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
this.el.classList.remove('scroll-scrolling');
|
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() {
|
window.requestAnimationFrame(function() {
|
||||||
var content;
|
var content;
|
||||||
|
|
||||||
|
if(_this._isStopped) {
|
||||||
|
_this._initDrag();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We really aren't dragging
|
// We really aren't dragging
|
||||||
if(!_this._drag) {
|
if(!_this._drag) {
|
||||||
_this._startDrag(e);
|
_this._startDrag(e);
|
||||||
@ -116,18 +132,18 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleEndDrag: function(e) {
|
_handleEndDrag: function(e) {
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
// We didn't have a drag, so just init and leave
|
// We didn't have a drag, so just init and leave
|
||||||
if(!_this._drag) {
|
if(!this._drag) {
|
||||||
_this._initDrag();
|
this._initDrag();
|
||||||
return;
|
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
|
// Animate to the finishing point
|
||||||
_this._animateToStop(e);
|
this._animateToStop(e);
|
||||||
// Cleanup
|
|
||||||
_this._initDrag();
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
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>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Weather</title>
|
<title>Weather</title>
|
||||||
@ -12,101 +12,39 @@
|
|||||||
<script src="/vendor/angular/angular-1.2.0rc2.min.js"></script>
|
<script src="/vendor/angular/angular-1.2.0rc2.min.js"></script>
|
||||||
<script src="/vendor/angular/angular-touch.js"></script>
|
<script src="/vendor/angular/angular-touch.js"></script>
|
||||||
<script src="/vendor/angular/angular-animate.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.js"></script>
|
||||||
<script src="/dist/js/ionic-angular.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>
|
</head>
|
||||||
<body ng-controller="WeatherCtrl">
|
<body ng-controller="WeatherCtrl">
|
||||||
<header id="header" class="bar bar-header bar-clear">
|
<header id="header" class="bar bar-header bar-clear">
|
||||||
<button class="button button-icon"><i class="icon-navicon-round"></i></button>
|
|
||||||
<h1 class="title">
|
<h1 class="title">
|
||||||
<span class="city">{{current.city.name}}</span><br>
|
<span class="city">{{current.display_location.city}}</span><br>
|
||||||
<current-time></current-time>
|
<current-time local-time="current.local_epoch" localtz="current.local_tz_short"></current-time>
|
||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<content id="main-content" has-header="true" padded="true">
|
<div id="scroller" class="scroll padding" style="margin-top:44px">
|
||||||
<small-weather>
|
<small-weather>
|
||||||
<h5>{{current.cover}}</h5>
|
<h5>{{current.weather}}</h5>
|
||||||
<h5>H: {{current.high}} L: {{current.low}}</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>
|
</small-weather>
|
||||||
<weather-box title="Forecast" style="height: 400px">
|
<weather-box title="Forecast" style="height: 400px">
|
||||||
</weather-box>
|
</weather-box>
|
||||||
<weather-box title="Details" style="height: 400px">
|
<weather-box title="Details" style="height: 400px">
|
||||||
</weather-box>
|
</weather-box>
|
||||||
</content>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
angular.module('ionic.example', ['ionic.ui.content'])
|
var s = document.getElementById('scroller');
|
||||||
|
var scroll = new ionic.views.Scroll({
|
||||||
.directive('currentTime', function($timeout, $filter) {
|
el: s,
|
||||||
return {
|
decelerationRate: 0.87
|
||||||
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
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</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 {
|
body {
|
||||||
background: url('madison2.jpg') no-repeat transparent;
|
background: url('madison3.jpg') no-repeat transparent;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
h1,h2,h3,h4,h5 {
|
h1,h2,h3,h4,h5 {
|
||||||
@ -11,6 +11,9 @@ h1,h2,h3,h4,h5 {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
#header .title .city {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
#main-content {
|
#main-content {
|
||||||
color: #fff;
|
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-top: 10px solid red;
|
||||||
border-bottom: 10px solid red;
|
border-bottom: 10px solid red;
|
||||||
}
|
}
|
||||||
|
.list-item {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user