Skip to content

Commit 697798f

Browse files
committed
new demo:
- page indicator.
1 parent 194d5a8 commit 697798f

File tree

9 files changed

+318
-4
lines changed

9 files changed

+318
-4
lines changed

example/lib/demos/demos.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export 'mouse_repulsion/mouse_repulsion.dart';
2929
export 'murat_coffee/murat_coffee.dart';
3030
export 'nico_loading_indicator/nico_loading_indicator.dart';
3131
export 'nokia_snake/nokia_snake.dart';
32+
export 'page_indicator/page_indicator.dart';
3233
export 'path_chart_stress/path_chart_stress.dart';
3334
export 'pie_chart/pie_chart.dart';
3435
export 'pizza_box/pizza_box.dart';
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import 'dart:ui';
2+
3+
import 'package:graphx/graphx.dart';
4+
5+
class PageDot extends GShape {
6+
7+
int id;
8+
9+
double _baseSize;
10+
11+
Color _color;
12+
13+
Color get color => _color;
14+
15+
set color(Color value) {
16+
if (value == _color) return;
17+
_color = value;
18+
_invalidateDraw();
19+
}
20+
21+
double _size;
22+
double targetSize;
23+
24+
double get size => _size;
25+
26+
set size(double value) {
27+
if (value < _baseSize) value = _baseSize;
28+
if (value == _size) return;
29+
_size = value;
30+
_invalidateDraw();
31+
// _draw();
32+
}
33+
34+
PageDot(this.id, double baseSize, Color color) {
35+
// w = h = size;
36+
_color = color;
37+
targetSize = _size = _baseSize = baseSize;
38+
_invalidateDraw();
39+
// _draw();
40+
}
41+
42+
void _draw() {
43+
graphics
44+
.clear()
45+
.beginFill(_color)
46+
.drawRoundRect(0, 0, _size, _baseSize, _baseSize / 2)
47+
.endFill();
48+
}
49+
50+
bool _isInvalid = true;
51+
52+
void validate() {
53+
_isInvalid = false;
54+
_draw();
55+
}
56+
57+
void _invalidateDraw() {
58+
if (_isInvalid) return;
59+
_isInvalid = true;
60+
}
61+
62+
@override
63+
void update(double delta) {
64+
super.update(delta);
65+
// _size += (_targetSize-_size)/10;
66+
// _isInvalid=true;
67+
if (_isInvalid) {
68+
_isInvalid = false;
69+
validate();
70+
}
71+
72+
}
73+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/// roipeker 2020
2+
///
3+
import 'package:flutter/material.dart';
4+
import 'package:graphx/graphx.dart';
5+
6+
import 'scene.dart';
7+
8+
class PageIndicatorMain extends StatelessWidget {
9+
@override
10+
Widget build(BuildContext context) {
11+
return Scaffold(
12+
appBar: AppBar(
13+
centerTitle: false,
14+
title: Text('page indicator'),
15+
elevation: 0,
16+
backgroundColor: Colors.black26,
17+
),
18+
body: Center(
19+
child: Container(
20+
// width: 300,
21+
child: SceneBuilderWidget(
22+
builder: () => SceneController(
23+
front: PageIndicatorPaged(),
24+
config: SceneConfig.games,
25+
),
26+
),
27+
),
28+
),
29+
);
30+
}
31+
}
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:graphx/graphx.dart';
3+
4+
import '../../utils/base_scene.dart';
5+
import 'dot.dart';
6+
7+
/// Sample fot Ismail, need to integrate a controller to get the PageView
8+
/// events.
9+
///
10+
class PageIndicatorPaged extends BaseScene {
11+
PageIndicatorPaged();
12+
13+
List<PageDot> _dots;
14+
static const double dotSize = 27 / 2;
15+
static const double dotPreW = 37 / 2;
16+
static const double dotSelectedW = 69 / 2;
17+
static const dotUnselectedColor = Color(0xffC4C4C4);
18+
static const dotSelectedColor = Colors.red;
19+
static const dotPreColor = Colors.blue;
20+
21+
GSprite container;
22+
GSprite scrollContainer;
23+
24+
int _currentIndex = 0;
25+
final int _visibleItems = 5;
26+
final int _numItems = 10;
27+
int _scroll = 0;
28+
double dotSep = 3;
29+
30+
double allDotsWidth = 0;
31+
32+
@override
33+
void addedToStage() {
34+
super.addedToStage();
35+
stage.color = Color(0xffD1D1D);
36+
37+
container = GSprite();
38+
scrollContainer = GSprite();
39+
addChild(container);
40+
container.addChild(scrollContainer);
41+
42+
_dots = List.generate(_numItems, (index) {
43+
var dot = PageDot(index, dotSize, dotUnselectedColor);
44+
dot.x = index * (dotSize * 2);
45+
scrollContainer.addChild(dot);
46+
return dot;
47+
});
48+
49+
var itemWS = dotSize + dotSep;
50+
allDotsWidth =
51+
itemWS * (_visibleItems - 2) + (dotPreW + dotSep) * 2 + dotSelectedW;
52+
53+
/// debug size.
54+
// container.graphics
55+
// // .lineStyle(1, Colors.black)
56+
// .beginFill(Colors.black.withAlpha(120))
57+
// .drawRect(-10, -10, allDotsWidth+20, dotSize+20)
58+
// .endFill();
59+
60+
/// -- masking.
61+
62+
// var maskOff = 3.0;
63+
// container.maskRect = GRect(
64+
// -maskOff,
65+
// -maskOff,
66+
// allDotsWidth + maskOff * 2,
67+
// dotSize + maskOff * 2,
68+
// );
69+
// container.maskRect.corners.allTo(dotSize);
70+
/// -- end masking.
71+
72+
/// only for testing.
73+
stage.keyboard.focusNode.requestFocus();
74+
stage.keyboard.onDown.add((event) {
75+
if (event.arrowLeft) {
76+
moveDir(-1);
77+
} else if (event.arrowRight) {
78+
moveDir(1);
79+
}
80+
});
81+
82+
stage.onResized.add(() {
83+
var ratioScale = sw / allDotsWidth;
84+
scale = ratioScale;
85+
86+
/// center it (not using alignPivot())
87+
y = (sh - (dotSize * ratioScale)) / 2;
88+
});
89+
90+
// force first rebuild.
91+
_currentIndex = -1;
92+
currentIndex = 0;
93+
}
94+
95+
void moveDir(int dir) {
96+
currentIndex += dir;
97+
}
98+
99+
int get currentIndex => _currentIndex;
100+
101+
double _targetScroll = 0.0;
102+
103+
@override
104+
void update(double delta) {
105+
super.update(delta);
106+
_updateScroll();
107+
_resizeItems();
108+
_positionItems();
109+
}
110+
111+
set currentIndex(int value) {
112+
if (value == _currentIndex) return;
113+
// reset all sizes.
114+
_currentIndex = value.clamp(0, _numItems - 1);
115+
116+
/// offset scroll.
117+
if (_currentIndex > _visibleItems - 1) {
118+
var offset = _visibleItems - 1 - _currentIndex;
119+
_scroll = offset;
120+
if (_currentIndex == _numItems - 1) {
121+
_scroll += 1;
122+
}
123+
_targetScroll = _scroll * (dotSize + dotSep);
124+
} else {
125+
_scroll = 0;
126+
_targetScroll = 0;
127+
}
128+
var firstIndex = -_scroll;
129+
_dots.forEach((dot) {
130+
double targetAlpha = 1.0;
131+
if (dot.id < firstIndex || dot.id > firstIndex + _visibleItems) {
132+
targetAlpha = 0.3;
133+
}
134+
dot.tween(
135+
duration: .3,
136+
colorize: dotUnselectedColor,
137+
alpha: targetAlpha,
138+
);
139+
dot.targetSize = dotSize;
140+
});
141+
142+
prevDot?.targetSize = dotPreW;
143+
nextDot?.targetSize = dotPreW;
144+
145+
nextDot?.tween(duration: .3, colorize: dotPreColor, overwrite: 0);
146+
prevDot?.tween(duration: .3, colorize: dotPreColor, overwrite: 0);
147+
// nextDot?.color = dotPreColor;
148+
// prevDot?.color = dotPreColor;
149+
150+
currDot?.targetSize = dotSelectedW;
151+
currDot?.tween(duration: .3, colorize: dotSelectedColor, overwrite: 0);
152+
// _positionItems();
153+
}
154+
155+
void _positionItems() {
156+
var lastX = 0.0;
157+
for (var i = 0; i < _dots.length; ++i) {
158+
var dot = _dots[i];
159+
// dot.x = lastX;
160+
dot.x += (lastX - dot.x) / 4;
161+
lastX += dot.size + dotSep;
162+
}
163+
}
164+
165+
void _resizeItems() {
166+
for (var i = 0; i < _dots.length; ++i) {
167+
var dot = _dots[i];
168+
dot.size += (dot.targetSize - dot.size) / 10;
169+
}
170+
}
171+
172+
PageDot get currDot {
173+
return _dots[_currentIndex];
174+
}
175+
176+
PageDot get prevDot {
177+
if (_currentIndex == 0) return null;
178+
return _dots[_currentIndex - 1];
179+
}
180+
181+
PageDot get nextDot {
182+
if (_currentIndex >= _numItems - 1) return null;
183+
return _dots[_currentIndex + 1];
184+
}
185+
186+
void _updateScroll() {
187+
var distance = _targetScroll - scrollContainer.x;
188+
if (distance.abs() < .5) {
189+
scrollContainer.x = _targetScroll;
190+
return;
191+
}
192+
scrollContainer.x += distance / 12;
193+
}
194+
}

example/lib/main.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ void main() {
5454
// home: Globe3dMain(),
5555
// home: LungsAnimationMain(),
5656
// home: PathChartStressTestMain(),
57-
home: ExpanderFabMenu(),
57+
// home: ExpanderFabMenu(),
58+
home: PageIndicatorMain(),
5859
),
5960
);
6061
}

example/lib/utils/base_scene.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import 'package:graphx/graphx.dart';
2+
3+
class BaseScene extends GSprite {
4+
double get sw => stage?.stageWidth ?? 0;
5+
double get sh => stage?.stageHeight ?? 0;
6+
7+
BaseScene([GSprite doc]) {
8+
doc?.addChild(this);
9+
}
10+
}

example/lib/utils/utils.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export 'package:flutter/material.dart';
22
export 'package:graphx/graphx.dart' show SceneBuilderWidget;
33

4-
export 'demo_scene_widget.dart';
4+
export 'base_scene.dart';
5+
export 'demo_scene_widget.dart';

lib/src/core/scene_controller.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class SceneController {
161161
if (_config.rebuildOnHotReload) {
162162
GTween.hotReload();
163163
dispose();
164+
164165
/// TODO: check if we need to delay the reinitialization.
165166
$init();
166167
}

lib/src/display/stage.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:ui' as ui;
2+
23
import '../../graphx.dart';
34
import '../events/mixins.dart';
45

@@ -127,8 +128,9 @@ class Stage extends GDisplayObjectContainer
127128
/// Only available when [SceneConfig.useKeyboard] is true.
128129
KeyboardManager get keyboard {
129130
if (scene?.core?.keyboard == null) {
130-
throw 'You need to enable keyboard capture, define useKeyboard=true '
131-
'in your SceneController';
131+
throw Exception(
132+
'You need to enable keyboard capture, define useKeyboard=true '
133+
'in your SceneController');
132134
}
133135
return scene?.core?.keyboard;
134136
}

0 commit comments

Comments
 (0)