How do I integrate a game in my flutter app? - flutter

I want to use this game https://github.com/yum650350/tissuebox in my Flutter project. I tried calling different parts of the main page but it wasn't coming up properly even though the game itself is working.
I want to integrate it in my iOS app and want to call it with a
function which opens a separate page where the user can play the game.
Is there a way I can do it?
So this is what I tried:
I called the method of the game in a separate screen
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(new MaterialApp(
debugShowCheckedModeBanner: false,
home: FirstScreen(),
));
}
class FirstScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
color: Colors.red,
child: Text('Go to Second Screen'),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute<Null>(builder: (BuildContext context) {
**???**
}));
},
),
),
);
}
}
But I don't know what to call in ?? this part since the game isn't wrapped in any class. This is the code of the game I want to call.
import 'package:shared_preferences/shared_preferences.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/gestures.dart';
import 'package:flame/sprite.dart';
import 'package:flame/flame.dart';
import 'package:flame/util.dart';
import 'package:flame/game.dart';
import 'dart:math';
tissuemain() async {
var util = Util();
await util.fullScreen();
await util.setOrientation(DeviceOrientation.portraitUp);
//loadimages
//tissuebox : 0,1,2,3,4,5,6
//background : b
//crown : c
//tissue : t
await Flame.images.loadAll(['b', '0', '1', '2', '3', '4', '5', '6', 't', 'c']);
audioLoad(c) async => (await Flame.audio.load(c)).path;
setAudio(a, s, v) async {
await a.setUrl(await audioLoad(s), isLocal: true);
a.setVolume(v);
}
//audios
//single drag : s.mp3
//double drag : s.mp3
//triple drag : s.mp3
//tick tock : tk.mp3
//game over : a.mp3
GameTable.setAudioList(GameTable.audioList1, await audioLoad('s.mp3'));
GameTable.setAudioList(GameTable.audioList2, await audioLoad('d.mp3'));
GameTable.setAudioList(GameTable.audioList3, await audioLoad('t.mp3'));
await setAudio(GameTable.tickTock, 'tk.mp3', 1.0);
await setAudio(GameTable.gameOver, 'a.mp3', .5);
var game = GameTable((await SharedPreferences.getInstance()).getInt('hs') ?? 0);
var hDrag = HorizontalDragGestureRecognizer();
var vDrag = VerticalDragGestureRecognizer();
hDrag.onUpdate = game.onDragUpdate;
hDrag.onStart = game.onDragStart;
hDrag.onEnd = game.onDragEnd;
vDrag.onUpdate = game.onDragUpdate;
vDrag.onStart = game.onDragStart;
vDrag.onEnd = game.onDragEnd;
runApp(game.widget);
util.addGestureRecognizer(hDrag);
util.addGestureRecognizer(vDrag);
}
enum Drag { tissue, box, none }
class GameTable extends Game {
//Audio
//These are workarounds for the ios memory leak
static var
tickTock = AudioPlayer(),
gameOver = AudioPlayer(),
audioList1 = [AudioPlayer(), AudioPlayer(), AudioPlayer()],
audioList2 = [AudioPlayer(), AudioPlayer()],
audioList3 = [AudioPlayer(), AudioPlayer()],
audioIndex1 = 0,
audioIndex2 = 0,
audioIndex3 = 0;
static getPlayIndex(int audioPlayer) {
if (audioPlayer == 1)
audioIndex1 = audioIndex1 < audioList1.length - 1 ? audioIndex1 + 1 : 0;
else if (audioPlayer == 2)
audioIndex2 = audioIndex2 < audioList2.length - 1 ? audioIndex2 + 1 : 0;
else if (audioPlayer == 3) audioIndex3 = audioIndex3 < audioList3.length - 1 ? audioIndex3 + 1 : 0;
return audioPlayer == 1 ? audioIndex1 : audioPlayer == 2 ? audioIndex2 : audioIndex3;
}
static get tissue1 => audioList1[getPlayIndex(1)];
static get tissue2 => audioList2[getPlayIndex(2)];
static get tissue3 => audioList3[getPlayIndex(3)];
static setAudioList(List<AudioPlayer> al,String audioName) => al.forEach((x) {
x.setUrl(audioName, isLocal: true);
x.setVolume(.2);
});
//
var background = Sprite('b'),
crown = Sprite('c'),
initialPoint = Offset.zero,
destPoint = Offset.zero,
dragState = Drag.none,
gameing = false,
gameover = false,
timePass = .0,
heighScore = 0,
score = 0,
timePassTemp = 0;
double tileSize, point1;
double get k => screenSize.width / 5 / tileSize;
Size screenSize;
Rect rect;
TissueBox tissueBox;
saveHighScore() async => await (await SharedPreferences.getInstance()).setInt('hs', heighScore);
GameTable(this.heighScore) {
init();
}
init() async {
resize(await Flame.util.initialDimensions());
rect = Rect.fromLTWH(.0, screenSize.height - tileSize * 23, tileSize * 9, tileSize * 23);
tissueBox = TissueBox(this);
}
#override
render(Canvas c) {
paintText(txt, offset, center, fontSize) {
var painter = TextPainter(
text: TextSpan(
style: TextStyle(
color: Colors.white,
fontSize: fontSize,
fontFamily: 'NS'),
text: txt),
textScaleFactor: k,
textDirection: TextDirection.ltr);
painter.layout();
painter.paint(c, center ? Offset(offset.dx - painter.width / 2, offset.dy) : offset);
}
background.renderRect(c, rect);
tissueBox.render(c);
var horCenter = tissueBox.initialLeft + tissueBox.boxRect.width / 2;
if (gameing)
paintText(timePass.toStringAsFixed(timePass < 1 ? 1 : 0) + 's', Offset(horCenter + 8, k * 23), true, k * 10);
var heighScoreTxt = heighScore.toString();
paintText(heighScoreTxt, Offset(heighScoreTxt.length==1?44.0:heighScoreTxt.length>2?22.0:33.0, k * 30), false, k * 12);
crown.renderRect(c, Rect.fromLTWH(28.0, k * 10, 49.2, 39.0));
paintText(score.toString(), Offset(horCenter, k * 50), true, k * 25);
heighScore = score > heighScore ? score : heighScore;
}
#override
update(double t) {
tissueBox.update(t);
timePass -= gameing || gameover ? t : 0;
if (timePass < 0 && gameing) {
tissueBox.isAway = true;
gameing = false;
timePass = 2;
gameover = true;
saveHighScore();
tissueBox.newGame();
} else if (gameing && !gameover) {
var floor = timePass.floor();
if (floor < timePassTemp && floor < 6 && floor != 0)
TissueBox.delay(Duration(milliseconds: 300), () => GameTable.tickTock.resume());
timePassTemp = floor;
}
gameover = timePass <= 0 && gameover ? false : gameover;
}
resize(s) {
screenSize = s;
tileSize = screenSize.width / 9;
}
onDragStart(DragStartDetails detail) {
var point = detail.globalPosition;
dragState = tissueBox.tissue.rect.contains(point) ? Drag.tissue : tissueBox.boxRect.contains(point) ? Drag.box : Drag.none;
initialPoint = Offset(point.dx == 0 ? initialPoint.dx : point.dx, point.dy == 0 ? initialPoint.dy : point.dy);
point1 = (tissueBox.tissue.rect.left - point.dx).abs();
}
onDragUpdate(DragUpdateDetails detail) {
if (gameover || dragState == Drag.none) return;
var point = detail.globalPosition;
destPoint = Offset(point.dx == 0 ? destPoint.dx : point.dx, point.dy == 0 ? destPoint.dy : point.dy);
if (dragState == Drag.tissue) {
if (initialPoint.dy - destPoint.dy > 100) {
if (gameing != true && gameover != true) {
gameing = true;
timePass = 10;
score = 0;
}
var sub = (point1 - (tissueBox.tissue.rect.left - point.dx).abs()).abs();
var addPoint = sub < 3 ? 3 : sub < 6 ? 2 : 1;
dragState = Drag.none;
tissueBox.nextTissue(addPoint);
playTissueAudio(addPoint);
score += addPoint;
}
} else if (dragState == Drag.box) {
tissueBox.boxRect = Rect.fromLTWH(tissueBox.initialLeft + destPoint.dx - initialPoint.dx, tissueBox.boxRect.top, TissueBox.boxSize.dx, TissueBox.boxSize.dy);
tissueBox.ismoving = true;
}
}
playTissueAudio(i) => (i == 1 ? GameTable.tissue1 : i == 2 ? GameTable.tissue2 : GameTable.tissue3).resume();
onDragEnd(DragEndDetails detail) {
initialPoint = Offset.zero;
dragState = Drag.none;
tissueBox.tissue.isMoving = false;
tissueBox.ismoving = false;
destPoint = initialPoint;
}
}
class TissueBox {
Rect get initialRect => Rect.fromLTWH(boxRect.center.dx - Tissue.width / 2, boxRect.top - boxRect.height + 20.3, Tissue.width, Tissue.width);
Sprite get getBoxSprite =>Sprite( rnd.nextInt(7).toString());
var tissueAwayList = List<TissueAway>(), rnd = Random(), ismoving = false, isAway = false;
Offset get getTissueUpPosition => Offset(initialRect.left, initialRect.top - 150);
final GameTable game;
Sprite boxSprite;
Rect boxRect;
int tissueCount;
Tissue tissue;
double get initialLeft => game.screenSize.width / 2 - TissueBox.boxSize.dx / 2;
double get initialTop => game.screenSize.height - game.tileSize * 5.5;
static var boxSize = Offset(150.0, 100.0);
TissueBox(this.game) {
boxRect = Rect.fromLTWH(initialLeft, initialTop, boxSize.dx, boxSize.dy);
tissueCount = 10 - rnd.nextInt(5);
tissue = Tissue(game, this);
boxSprite = getBoxSprite;
}
render(Canvas c) {
boxSprite.renderRect(c, boxRect);
tissue.render(c);
tissueAwayList.forEach((x) => x.render(c));
}
update(double t) {
tissue.update(t);
tissueAwayList.removeWhere((x) => x.isAway);
tissueAwayList.forEach((x) => x.update(t));
var distense = boxRect.left - initialLeft;
if (ismoving && !game.gameover) {
if (distense.abs() > 50 && tissueCount == 0){
isAway = true;
}
} else if (isAway && !game.gameover) {
boxRect = boxRect.shift(Offset(distense > 0 ? boxRect.left + game.k * 11 : boxRect.left - game.k * 11, boxRect.top));
if (boxRect.right < -50 || boxRect.left > game.screenSize.width + 50) {
newBox();
}
} else if (isAway && game.gameover) {
var target = Offset(boxRect.left, game.screenSize.height + Tissue.width) - Offset(boxRect.left, boxRect.top);
boxRect = boxRect.shift(
game.k * 11 < target.distance ?
Offset.fromDirection(target.direction, game.k * 11)
: target);
} else {
var target = Offset(initialLeft, initialTop) - Offset(boxRect.left, boxRect.top);
boxRect = boxRect.shift(
game.k * 11 < target.distance ?
Offset.fromDirection(target.direction, game.k * 11)
: target);
}
}
nextTissue(int pointsAdd) {
var duration = Duration(milliseconds: 100);
tissueAwayList.add(TissueAway(game, this));
if (pointsAdd > 1)
delay(duration, () {
tissueAwayList.add(TissueAway(game, this));
if (pointsAdd > 2)
delay(duration, () {
tissueAwayList.add(TissueAway(game, this));
});
});
tissue = Tissue(game, this, --tissueCount == 0);
}
newBox() {
boxSprite = getBoxSprite;
boxRect = Rect.fromLTWH(boxRect.right < -0 ? game.screenSize.width + 50 - boxSize.dx : -50.0, initialTop, boxSize.dx, boxSize.dy);
tissueCount = 10 - rnd.nextInt(5);
tissue = Tissue(game, this);
isAway = false;
ismoving = false;
}
newGame() async {
isAway = true;
GameTable.gameOver.resume();
await delay(Duration(seconds: 2), () {});
newBox();
}
static delay(duration, func()) async => await Future.delayed(duration, func);
}
class Tissue {
var tissueSprite = Sprite('t'), isMoving = false;
static var width = 100.0;
final TissueBox tissueBox;
final GameTable game;
bool isAway;
Rect rect;
Tissue(this.game, this.tissueBox, [this.isAway = false]) {
rect = tissueBox.initialRect;
}
render(Canvas c) => tissueSprite.renderRect(c, rect);
update(double t) => rect = isAway ? rect.shift(Offset.infinite) : tissueBox.initialRect;
}
class TissueAway extends Tissue {
TissueAway(GameTable game, TissueBox tissueBox) : super(game, tissueBox);
render(Canvas c) => tissueSprite.renderRect(c, rect);
update(double t) {
var speed = 500 * t;
Offset target = tissueBox.getTissueUpPosition - Offset(rect.left, rect.top);
if (speed < target.distance)
rect = rect.shift(Offset.fromDirection(target.direction, speed));
else
isAway = true;
}
}

The code in the main method will have a line that says runApp(...). The value of the ... is a widget that will be treated as the root widget of the app. In theory, you could just take that widget and pass it to your Navigator.push method and it should treat that widget as any other widget.
That being said, real life probably won't be as clean as this. There might be some initialization code in that app's main method or root widget that won't work properly if the app has long since already been initialized. Since virtually every Flutter app's root widget creates a WidgetsApp (or one of its derived classes MaterialApp or CupertinoApp), there might be some conflict that arrives from having one of those widgets being inserted as a descendent of another one of those widgets.
The game in question may work simply, or it might take some tweaking to work properly. That's something that will depend entirely on what app you are trying to embed into your own, so the only solution is to try it out and see for yourself.

Related

Flutter: How to do this emoji firework animation?

I want to do this emoji fireworks animation in a flutter widget:
https://codepen.io/z3vin/pen/QEqqdY
The code is in TypeScript:
class Firework {
constructor(app) {
this.app = app;
this.rnd = app.rnd;
this.bursts = [];
this.reset();
}
reset() {
this.color = `hsl(${this.rnd.int(360)},90%,50%)`;
this.alive = true;
this.bursting = false;
this.pos = new Vec( this.rnd.int(0,this.app.w), this.app.h+40 );
this.vel = new Vec(0,-this.rnd.real(16.0,this.app.h/40));
this.acc = new Vec(0,0);
this.size = this.rnd.real(0.25,5.0);
this.emoji = this.rnd.pick(this.app.emojis);
}
applyForce(f){
this.vel.add(f);
}
update() {
this.applyForce(this.app.forces.gravity);
this.vel.add(this.acc);
this.pos.add(this.vel);
if(this.vel.y > 1) {
this.bursting = true;
const maxBursts = Math.floor(this.app.w / 4);
const numBursts = this.rnd.chance(5) ? this.rnd.int(100,maxBursts) : this.rnd.int(20,80);
for(let i = 1; i < numBursts; i++){
this.bursts.push(new Burst(this.pos, this));
}
}
}
draw() {
const ctx = this.app.ctx;
if(!this.bursting) {
this.update();
ctx.save();
ctx.fillStyle = this.color;
ctx.font = `${this.size}em sans-serif`;
ctx.fillText(this.emoji,this.pos.x,this.pos.y);
//ctx.fillRect(this.pos.x, this.pos.y, this.size, this.size);
ctx.restore();
} else {
this.bursts.forEach(burst=>{
if(!burst.alive){
without(this.bursts,burst);
if(this.bursts.length ===0){
this.alive = false;
}
}
burst.draw();
});
}
}
}
class Burst {
constructor(origin,firework){
this.firework = firework;
this.app = firework.app;
this.pos = origin.clone();
this.rnd = firework.rnd;
this.lifespan = this.rnd.int(5,50);
this.vel = new Vec(this.rnd.real(-8.0,8.0),this.rnd.real(-8.0,8.0));
this.acc = new Vec(0,0);
this.color = this.firework.color;
this.size = this.rnd.real(0.5,15.0);
const sparkle = this.rnd.chance(20) ? 2 : 1;
this.sizeStep = this.size/(this.lifespan/sparkle);
this.alive = true;
this.rotate = this.rnd.real(0,Math.PI*2);
}
applyForce(f){
this.vel.add(f);
}
update() {
this.applyForce(this.app.forces.gravity);
this.vel.add(this.acc);
this.pos.add(this.vel);
//this.size -= this.sizeStep;
//this.rotate += 0.1;
}
draw() {
const ctx = this.app.ctx;
this.update();
ctx.save();
ctx.translate(this.pos.x,this.pos.y)
ctx.rotate(this.rotate);
ctx.font = `${this.firework.size/2}em sans-serif`;
ctx.fillText(this.firework.emoji,0,0);
ctx.restore();
this.lifespan--;
if(this.lifespan<=0){
this.alive = false;
}
}
}
class App {
constructor(){
this.ctx = document.getElementById('cnv').getContext('2d');
this.sizeCanvas();
this.initEvents();
this.rnd = new Random();
this.fireworks = [];
this.forces = {
gravity: new Vec(0,0.25)
};
this.emojis = ['😊','🍕','💩','☘','👀','🐟','💥','⚡️','🍉','🍟','⚽️'];
window.requestAnimationFrame((t)=>{this.draw(t)});
log(this);
}
sizeCanvas(){
this.w = this.ctx.canvas.width = window.innerWidth;
this.h = this.ctx.canvas.height = window.innerHeight;
}
clearIt() {
//this.ctx.clearRect(0,0,this.w,this.h);
this.ctx.save();
this.ctx.fillStyle = 'hsla(220,60%,10%,0.12)';
this.ctx.fillRect(0,0,this.w,this.h)
this.ctx.restore();
}
draw(t){
this.clearIt();
window.requestAnimationFrame((t)=>{this.draw(t)});
if(this.rnd.chance(this.w/80)){
this.fireworks.push(new Firework(this));
}
this.fireworks.forEach(f=>{
if(!f.alive){
without(this.fireworks,f);
}
//log(this.fireworks.length)
f.draw();
});
}
initEvents(){
window.onresize = (e)=>{this.sizeCanvas(e)};
}
}
const foo = 'dsdsa';
const log = console.log.bind(console);
const Vec = TinyVector;
document.addEventListener('DOMContentLoaded', function () {
const app = new App();
});
function without (arr, el) {
arr.splice(arr.indexOf(el),1);
}
Can someone guide me to do this kind of UI making in flutter?
I'm desesperate to find the solution but i don't understand how animation works and i found nothing on stack or other website to do this.
Thanks a lot to people who know how to do that.
I already tried the confetti package but it's not my final goal.

Unhandled Exception: setState() during building of sub class

Im trying to pass data from a child widget to a parent widget using callback
so IM having this error
setState() or markNeedsBuild() called during build.
and I know its because of calling "callback" set msg before returning the stack(during building of child , superclass call setState :( )
widget.setmsg(msg);
return Stack(children: widget.model == posenet ? _renderKeypoints() : null);
SO how can I return renderKeypoints() widget and return msg to super? or is there a way to print msg immediately in the screen (I get the value of msg after having calculation in renderkeypoint ?
Subclass code :
typedef void IntCallback(String id);
// ignore: must_be_immutable
class BndBox extends StatefulWidget {
final List<dynamic> results;
final int previewH;
final int previewW;
final double screenH;
final double screenW;
final String model;
final IntCallback setmsg;
BndBox(this.results, this.previewH, this.previewW, this.screenH, this.screenW,
this.model, this.setmsg);
#override
_BndBoxState createState() => _BndBoxState();
}
class _BndBoxState extends State<BndBox> {
#override
Widget build(BuildContext context) {
String msg = "";
List<Widget> _renderKeypoints() {
var lists = <Widget>[];
var kx = [10.9];
kx.removeAt(0);
widget.results.forEach((re) {
var list = re["keypoints"].values.map<Widget>((k) {
var _x = k["x"];
var _y = k["y"];
var scaleW, scaleH, x, y;
kx.add(k["x"]);
if (widget.screenH / widget.screenW >
widget.previewH / widget.previewW) {
scaleW = widget.screenH / widget.previewH * widget.previewW;
scaleH = widget.screenH;
print("scaleW");
print(scaleW);
print("scaleH");
print(scaleH);
var difW = (scaleW - widget.screenW) / scaleW;
x = (_x - difW / 2) * scaleW;
y = _y * scaleH;
} else {
scaleH = widget.screenW / widget.previewW * widget.previewH;
scaleW = widget.screenW;
var difH = (scaleH - widget.screenH) / scaleH;
x = _x * scaleW;
y = (_y - difH / 2) * scaleH;
}
return Stack(children: [
Positioned(
left: x - 6,
top: y - 6,
width: 100,
height: 12,
child: Container(
child: Text(
"● ${k["part"]}",
style: TextStyle(
color: Color.fromRGBO(37, 213, 253, 1.0),
fontSize: 12.0,
),
),
),
),
]);
}).toList();
lists..addAll(list);
});
try {
if (((kx[3] - kx[5]).abs() <= 0.05) &&
((kx[3] - kx[11]).abs() <= 0.1)) {
msg = "RIGHT POSE";
} else if (((kx[3] - kx[5]) > 0.05 && (kx[3] - kx[5]) < 0.1) &&
(((kx[3] - kx[11]) > 0.1) && (kx[3] - kx[11]) < 0.2)) {
msg = "WRONG POSE";
} else {
msg = "UNDEFINED";
}
} catch (Exception) {
msg = "EXCEPTION";
}
return lists;
}
// widget.setmsg(msg); //error here
return Stack(
children: widget.model == posenet ? _renderKeypoints() : SizedBox(),
}
}
return Stack(children: widget.model == posenet ? _renderKeypoints() : SizedBox());
the solution does not need call back ,,
what I wanted has been solved
return Stack(children: <Widget>[
Stack(
children: widget.model == posenet ? _renderKeypoints() : null,
),
Text(msg)
]);

Flutter : Timer.periodic running multiple times in each iteration

I am trying to make snake 2 in flutter. And I have used Timer.periodic() for game loop. And I tried specifying duration as 1 seconds. But the code inside the Timer.periodic() runs multiple times in a second. I also tried debugging (though I am terrible at that) and found that the code inside the Timer.periodic() ran multiple times without stepping out of it. Though while debugging this couild happen as the code pauses for input. But I'm not sure about anything .Here is my code -
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
class SnakePage extends StatefulWidget {
#override
_SnakePageState createState() => _SnakePageState();
}
class _SnakePageState extends State<SnakePage> {
int score = 0;
String swipe = '';
bool running = false;
int iterates = 0;
List snake = [
[
[4, 3],
1,
true
],
[
[4, 2],
1,
false
],
[
[4, 1],
1,
false
],
];
// Convert radians to degree
double radians(double degree) {
return ((degree * 180) / pi);
}
void turn(moveEvent) {
double angle = radians(moveEvent.delta.direction);
if (angle >= -45 && angle <= 45) {
this.swipe = 'Swipe Right';
} else if (angle >= 45 && angle <= 135) {
this.swipe = 'Swipe Down';
} else if (angle <= -45 && angle >= -135) {
this.swipe = 'Swipe Up';
} else {
this.swipe = 'Swipe Left';
}
}
int toIndex(coOrdinates) {
return ((coOrdinates[0] + 1) * 10) + coOrdinates[1];
}
void run() {
this.running = true;
Timer.periodic(
Duration(
milliseconds: 500,
), (timer) {
this.setState(() {
this.iterates += 1;
this.swipe = this.iterates.toString();
for (var i = 0; i < this.snake.length; i++) {
this.snake[i][0][1] += 1;
if (this.snake[i][0][1] == 10) {
this.snake[i][0][1] = 0;
}
}
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WC'),
),
body: Listener(
onPointerMove: this.running
? (moveEvent) => this.turn(moveEvent)
: (moveEvent) => this.run(),// Where the function is being called
child: Container();
);
}
}
And please pardon me for code being a mess and not well commented.
Any Help would be appreciated!
The problem is that, every time you execute the run() method, a new timer is created and you listen for it, again. The old timer is not stopped, so it keeps firing.
The solution is, before you create a timer, cancel the previous one. Something like this:
class _SnakePageState extends State<SnakePage> {
Timer? _myTimer;
void run() {
this.running = true;
_myTimer?.cancel(); //in case we have a timer, we'll cancel it.
_myTimer = Timer.periodic(. // assing new timer to our variable.
Duration(
milliseconds: 500,
), (timer) {
this.setState(() {
this.iterates += 1;
this.swipe = this.iterates.toString();
for (var i = 0; i < this.snake.length; i++) {
this.snake[i][0][1] += 1;
if (this.snake[i][0][1] == 10) {
this.snake[i][0][1] = 0;
}
}
});
});
}
}

Click event don't fire on first slide ion-slide

Created a slider with ion-slides. But sometimes first and the last slide of slider don't fire the click event. Like we are displaying five slides: 2,3,4 slides fire event with no error and in 1,4 it doesn't fire click event neither shows any error.
Please me the solution. Thanks in advance
.html file
<ion-grid>
<ion-row>
<ion-col size="12" class="p-0">
<ion-slides pager="false" #slideWithNav
(ionSlideDidChange)="SlideDidChange(sliderOne,slideWithNav)" class="pb-10">
<ion-slide tappable *ngFor="let s of sliderOne.slidesItems" (click)="openModal(s)">
<div>
<h6 class="m-5 cardTtl">{{s.name}}</h6>
</div>
</ion-slide>
</ion-slides>
</ion-col>
</ion-row>
.js file
let slides = document.querySelector('ion-slides');
const slideOpts = {
grabCursor: true,
centeredSlides: true,
slidesPerView: 2.45,
initialSlide: 1,
pager: true,
loop: true,
autoplay:false,
coverflowEffect: {
rotate: 5,
stretch: 0,
depth: 100,
modifier: 1,
slideShadows: true,
},
pagination: {
el: '.swiper-pagination',
},
on: {
beforeInit() {
const swiper = this;
swiper.classNames.push(`${swiper.params.containerModifierClass}coverflow`);
swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
swiper.params.watchSlidesProgress = true;
swiper.originalParams.watchSlidesProgress = true;
},
setTranslate() {
const swiper = this;
const {
width: swiperWidth, height: swiperHeight, slides, $wrapperEl, slidesSizesGrid, $
} = swiper;
const params = swiper.params.coverflowEffect;
const isHorizontal = swiper.isHorizontal();
const transform$$1 = swiper.translate;
const center = isHorizontal ? -transform$$1 + (swiperWidth / 2) : -transform$$1 + (swiperHeight / 2);
const rotate = isHorizontal ? params.rotate : -params.rotate;
const translate = params.depth;
// Each slide offset from center
for (let i = 0, length = slides.length; i < length; i += 1) {
const $slideEl = slides.eq(i);
const slideSize = slidesSizesGrid[i];
const slideOffset = $slideEl[0].swiperSlideOffset;
const offsetMultiplier = ((center - slideOffset - (slideSize / 2)) / slideSize) * params.modifier;
let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
// var rotateZ = 0
let translateZ = -translate * Math.abs(offsetMultiplier * 6.2);
let translateY = isHorizontal ? 0 : params.stretch * (offsetMultiplier);
let translateX = isHorizontal ? params.stretch * (offsetMultiplier) : 0;
// Fix for ultra small values
if (Math.abs(translateX) < 0.001) translateX = 0;
if (Math.abs(translateY) < 0.001) translateY = 0;
if (Math.abs(translateZ) < 0.001) translateZ = 0;
if (Math.abs(rotateY) < 0.001) rotateY = 0;
if (Math.abs(rotateX) < 0.001) rotateX = 0;
const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
$slideEl.transform(slideTransform);
$slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
if (params.slideShadows) {
// Set shadows
let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
if ($shadowBeforeEl.length === 0) {
$shadowBeforeEl = swiper.$(`<div class="swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}"></div>`);
$slideEl.append($shadowBeforeEl);
}
if ($shadowAfterEl.length === 0) {
$shadowAfterEl = swiper.$(`<div class="swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}"></div>`);
$slideEl.append($shadowAfterEl);
}
if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
}
}
// Set correct perspective for IE10
if (swiper.support.pointerEvents || swiper.support.prefixedPointerEvents) {
const ws = $wrapperEl[0].style;
ws.perspectiveOrigin = `${center}px 50%`;
}
},
setTransition(duration) {
const swiper = this;
swiper.slides
.transition(duration)
.find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left')
.transition(duration);
}
}
}
slides.options = slideOpts;
.ts file
constructor(public modalController: ModalController) {
$.getScript('assets/js/slider.js');
this.sliderOne =
{
isBeginningSlide: true,
isEndSlide: false,
slidesItems: [
{ id: 0, name: 'text1' },
{ id: 1, name: 'text2' },
{ id: 2, name: 'text3' },
{ id: 3, name: 'text4' }
],
};
}
async openModal(s) {
const modal = await this.modalController.create({
component: SliderPage,
componentProps: {
titleName: s.name
}
});
return await modal.present();
}

Flutter TextFormField decoration

How to display the number "123456789" as "123 456 789" in TextFormfield?
TextFormField(
controller: _numberId,
keyboardType: TextInputType.number,
),
I write below extention on String :
extension StringSeprate on String {
String stringSeparate(
{int count = 3, String separator = ",", bool fromRightToLeft = true}) {
if (this.isEmpty) {
return "";
}
if (count < 1) {
return this;
}
if (count >= this.length) {
return this;
}
var str = this.replaceAll(separator, "");
if (fromRightToLeft) {
str = String.fromCharCodes(str.runes.toList().reversed);
}
var chars = str.runes.toList();
var namOfSeparation =
(chars.length.toDouble() / count.toDouble()).ceil() - 1;
var separatedChars = List(chars.length + namOfSeparation.round());
var j = 0;
for (var i = 0; i < chars.length; i++) {
separatedChars[j] = String.fromCharCode(chars[i]);
if (i > 0 && (i + 1) < chars.length && (i + 1) % count == 0) {
j += 1;
separatedChars[j] = separator;
}
j += 1;
}
return fromRightToLeft
? String.fromCharCodes(separatedChars.join().runes.toList().reversed)
: separatedChars.join();
}
}
final code (copy below code in your file and call it from main for test):
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class TestWidget extends StatelessWidget {
TextEditingController _textEditingController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: _textEditingController,
inputFormatters: [
TextInputFormatter.withFunction((oldValue, newValue) =>
TextEditingValue(
text: newValue.text.stringSeparate(
separator: ' ', fromRightToLeft: false)))
],
onChanged: (String value) {
if (value == null) return;
_textEditingController.selection = TextSelection.fromPosition(
TextPosition(
offset: value.length, affinity: TextAffinity.upstream));
},
),
],
),
),
);
}
}
extension StringSeprate on String {
String stringSeparate(
{int count = 3, String separator = ",", bool fromRightToLeft = true}) {
if (this.isEmpty) {
return "";
}
if (count < 1) {
return this;
}
if (count >= this.length) {
return this;
}
var str = this.replaceAll(separator, "");
var chars = str.runes.toList();
var namOfSeparation =
(chars.length.toDouble() / count.toDouble()).ceil() - 1;
var separatedChars = List(chars.length + namOfSeparation.round());
var j = 0;
for (var i = 0; i < chars.length; i++) {
separatedChars[j] = String.fromCharCode(chars[i]);
if (i > 0 && (i + 1) < chars.length && (i + 1) % count == 0) {
j += 1;
separatedChars[j] = separator;
}
j += 1;
}
return fromRightToLeft
? String.fromCharCodes(separatedChars.join().runes.toList().reversed)
: separatedChars.join();
}
}
result is like :