Skip to content

Instantly share code, notes, and snippets.

@roipeker
Last active October 2, 2022 23:09
Show Gist options
  • Save roipeker/470cd28664b16fe46e8776f35d60dfbf to your computer and use it in GitHub Desktop.
Save roipeker/470cd28664b16fe46e8776f35d60dfbf to your computer and use it in GitHub Desktop.
responsive concept for graphx.
void main() {
runApp(
MaterialApp(
home: GameWrapper(),
debugShowCheckedModeBanner: false,
),
);
}
class GameWrapper extends StatefulWidget {
const GameWrapper({super.key});
@override
createState() => _GameWrapperState();
}
class _GameWrapperState extends State<GameWrapper> {
@override
Widget build(BuildContext context) {
var screenMetric = '''
SCREEN ${MediaQuery.of(context).size}
DESIGN $designSize
''';
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
fit: StackFit.expand,
children: [
SceneBuilderWidget(
builder: () => SceneController(back: ResponsiveScene()),
),
Opacity(
opacity: .5,
child: Text(screenMetric),
),
],
),
);
}
}
extension SpriteExt on GSprite {
double get sw => stage?.stageWidth ?? 0;
double get sh => stage?.stageHeight ?? 0;
}
class Topbar extends GSprite {
final h = 50.0;
late GText text = GText(
text: '... sample topbar',
textStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20),
);
@override
void addedToStage() {
addChild(text);
text.validate();
text.alignPivot();
stage!.onResized.add(onStageResize);
}
onStageResize() {
graphics.clear();
graphics
.beginFill(Colors.lightBlue.withOpacity(.7))
.drawRoundRect(10, 10, sw - 20, h - 20, 12)
.endFill();
text.x = sw / 2;
text.y = h / 2;
}
}
class WarningSizeScreen extends GSprite {
WarningSizeScreen(GDisplayObjectContainer doc) {
doc.addChild(this);
mouseChildren = false ;
}
var bg = GShape();
late var text = GText(
text: 'Please resize your screen to match the design size',
paragraphStyle: ParagraphStyle(
textAlign: TextAlign.center,
),
textStyle: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20,
),
);
@override
void addedToStage() {
bg.graphics
.beginFill(Colors.black.withOpacity(.7))
.drawRect(0, 0, 100, 100)
.endFill();
addChild(bg);
addChild(text);
text.validate();
text.alignPivot();
stage!.onResized.add(handleOnResize);
handleOnResize();
}
bool isShown = false;
void show(){
if(isShown) return;
isShown = true;
tween(duration: 1, alpha: 1);
}
void hide(){
if(!isShown) return;
isShown = false;
tween(duration: 0.5, alpha: 0);
}
void handleOnResize() {
bg.width = sw;
bg.height = sh;
text.width = sw - 20;
text.validate();
text.alignPivot();
text.setPosition(sw / 2, sh / 2);
}
}
class ResponsiveScene extends GSprite {
late GShape frame;
late Topbar top;
late WarningSizeScreen warningScreen;
void onStageResize() {
var ratioStage = stage!.stageWidth / stage!.stageHeight;
var ratioDesign = designSize.width / designSize.height;
var isCover = ratioStage < ratioDesign;
// var isCover = ratioStage > ratioDesign;
/// <== change this to see the difference.
if (isCover) {
frame.scale = stage!.stageHeight / designSize.height;
} else {
frame.scale = stage!.stageWidth / designSize.width;
}
// center the frame on stage
frame.x = (stage!.stageWidth - designSize.width * frame.scale) / 2;
frame.y = (stage!.stageHeight - designSize.height * frame.scale) / 2;
if( sw < 300 || sh < 300){
warningScreen.show();
} else {
warningScreen.hide();
}
}
@override
void addedToStage() {
stage!.onResized.add(onStageResize);
frame = GShape();
addChild(frame);
top = Topbar();
addChild(top);
warningScreen = WarningSizeScreen(stage!);
warningScreen.alpha = 0;
/// fixed size.
frame.graphics
.beginFill(Colors.red)
.lineStyle(4, Colors.blue)
.drawRect(0, 0, designSize.width, designSize.height)
.endFill();
/// add a dot.
frame.graphics
.beginFill(Colors.white)
.drawCircle(designSize.width / 2, designSize.height / 2, 10)
.endFill();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment