I want to show some animation when user tap on the screen. The animation need to be controllable too as it needs to be reset after each tap.
What I have tried:
1. Show a Gif image in Overlay.
RenderBox renderBox = context.findRenderObject();
var size = renderBox.size;
var offset = renderBox.localToGlobal(Offset.zero);
_myGif = Image.asset('images/mygif.gif', width: 100, height: 100,);
return OverlayEntry(
builder: (context) => Positioned(
left: offset.dx - 50.0 + size.width/2,
top: offset.dy - 50.0 + size.height/2,
child: Container(
child: _myGif
),
)
);
Problem: The Gif animation is not controllable. The animation also appears to be played from random frames and end at random frames each time.
Use third party widget (gif_ani)
_animationCtrl = GifController(vsync: this, duration: new Duration(milliseconds: 1000), frameCount: 38);
_mygifAnimation = GifAnimation(
width: 100.0,
height: 100.0,
image: AssetImage('images/mygif.gif'),
controller: _animationCtrl,
);
Problem: It only works when it's not on an Overlay. When the GifAnimation is added as a child in Overlay it doesn't display at all.
Use Flame to run sprite sheet
Problem: AnimationAsWidget doesn't fit my requirement as I need to control the animation. Other ways would make my code too complex as I'm not building a game.
Is there any solution on this? Thank you in advance.
Related
when give a Container a background while i'm using platformViewRegistry.registerViewFactory & ImageElement
the background appear above the image.
ui.platformViewRegistry.registerViewFactory(
link,
(int viewId) => ImageElement()
..src = link
);
return SizedBox(
width: 50,
height: 50,
child:HtmlElementView(viewType: link)
);
image appear like that :
https://user-images.githubusercontent.com/59504151/197509825-7a0e972a-0519-4a4d-83aa-db941a04b892.png
and if i drag the image it shown under the background like this:
this image when i drag the image by mouse
https://user-images.githubusercontent.com/59504151/197509715-0c81e41e-6b52-4848-b017-412a3b099864.png
I am trying to create a view that consist of a background image with widgets positioned dynamically in certain places on this image, each widget will have an x and y that needs to be calculated for different screens and for different image sizes.
what i did so far was showing the image in a stack and made a list of widgets where each widget type is being checked then create a flutter widget that corresponds with it adding it to this list and displaying it over the image in the stack, but i am looking for a cleaner way to create this behavior, also when rotating the screen the widgets are not being placed in a correct position,
Thank you for your time.
You can do something like:
Stack(
children: [
Image.asset('YOUR IMAGE HERE', fit: BoxFit.cover), // this is your bg image,
..List.generate(imagesCollection.length, (index) {
// you could encapsulate all this logic in a separate widget
var img = imagesCollection[index];
var r = Random();
// make sure to stay within the bounds of your screen
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
var randomX = r.nextInt(screenWidth);
var randomY = r.nextInt(screenHeight);
// before you position the image, check that is within the bounds
// check if the randomX - IMAGE_WITH is less than the screen width, same for the height
return Positioned(
top: randomY,
left: randomX,
child: Image.asset(img, width: IMAGE_WIDTH, height: IMAGE_HEIGHT)
);
}
]
)
Something around those lines.
Is there a way to achieve popup menu on header which expands on hover and closes on mouse exit
You can use the MouseRegion widget to determine the hover changes. Popup in the sense, could you explain what exactly you want to achieve? Some would be possible some wouldn't be. I hope you just need to expand the menu button on hover, which you can use an AnimatedContainer for the menu, warp it with MouseRegion widget, declare a variable that says the width, and height of AnimatedContainer widget. MouseRegion has onEnter and onExit functions, onEnter is when the container has hovered and onExit is when the user stops hovering the container. During onEnter you can increase the width and height and during onExit, you can set it to default.
double _animatedContainerHeight = 30; //Default height
double _animatedContainerWidth = 30; //Default width
MouseRegion(
onEnter: (value) {
setState(() {
_animatedContainerHeight = 50; //OnHover height
_animatedContainerWidth = 50; //OnHover width
});
},
onExit: (value) { setState(() {
_animatedContainerHeight = 30; //Return back to normal height
_animatedContainerWidth = 30; //Return back to normal width
});
},
cursor: SystemMouseCursors.click, //Cursor type on hover
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
height: _animatedContainerHeight, //Animation height control
width: _animatedContainerWidth, //Animation width control
),
)
Using NSAnimationContext.runAnimationGroup(_:_:) as demonstrated in the NSAnimationContext documentation to animate both the frame origin and size works as expected for some view types (including NSImageView). However, it does not work as expected for an NSButton unless I add an explicit frame size change after the animation
Animating frame size for NSImageView
The following works as expected for an NSImageView. It is moved to the origin, and resized to 200x200:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 2.0
// Get the animator for an NSImageView
let a = self.theImage.animator()
// Move and resize the NSImageView
a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
print("Animation done")
}
Animating frame size for NSButton
When performing the same with an NSButton, the button will move but not resize:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 2.0
// Get the animator for an NSButton
let a = self.button.animator()
// Move and resize the NSImageView
a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
print("Animation done")
}
However, if I add the following line of code to the end, after all of the animation code, it works as expected!
self.button.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
The final, working listing for NSButton is:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 2.0
// Get the animator for an NSButton
let a = self.button.animator()
// Move and resize the NSImageView
a.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
}) {
print("Animation done")
}
self.button.frame = NSRect(x: 0, y: 0, width: 200, height: 200)
I'm not looking a gift horse in the mouth here, but I don't understand why this is required for NSButton, or even what makes it work. Can anyone explain why explicitly setting the frame of the NSButton after the animation code makes the animation work?
I suspect this has something to do with implicit autolayout constraints being generated at runtime. After modifying the frame, the autolayout simply reverts it back to the original size.
I abandoned the original approach in favor of the following:
Create width and/or height constraints in Interface Builder. I use the default priority of 1000 (constraint is mandatory).
Create an outlet for the width and/or height NSLayoutConstraint. This was tricky in IB: I had to double-click the constraint in the measurements tab of the inspector which then opened the constraint object in the inspector. Then you can select the connections tab and connect the outlet.
In my NSViewController subclass I use anchors to define the new height or width: theWidthConstraint.constant = 200 followed by self.view.needsUpdateConstraints = true
This approach is much cleaner and more compatible with the autolayout system. In addition, it makes it easy to animate the entire layout change that results from the new autolayout:
NSAnimationContext.runAnimationGroup({(let context) -> Void in
context.duration = 1.0
self.theWidthConstraint.animator().constant = 200
// Other constraint modifications can go here
}) {
print("Animation done")
}
I'm trying to add some imageViews and a tableView into scrollView in Titanium. I want the scrollView to be scrollable but not the tableView inside, so I set tableView.scrollable to false. However, even if the height of the scrollView exceeds the height of the screen, it is not scrollable. Since it's not encouraged to put a tableView inside a scrollView, I'm wondering if there is a better way to create a table with fixed length inside a scrollView in Titanium?
The following is my code:
var view = Ti.UI.createScrollView({
contentWidth:'auto',
contentHeight:'auto',
top:0,
showVerticalScrollIndicator:true,
showHorizontalScrollIndicator:true,
});
var imageview1 = Ti.UI.createImageView({
image: "../images/headers/gscs_logo.png",
height: 80,
left: 10,
right: 10,
top: 10,
});
var imageview2 = Ti.UI.createImageView({
image: "../images/headers/wellness_logo.png",
height: 80,
left: 10,
right: 10,
top: 90,
});
view.add(imageview1);
view.add(imageview2);
var tableview = Ti.UI.createTableView({
data: [{title:'a'}, {title:'b'}, {title:'c'}, {title:'d'}, {title:'e'}, {title:'f'}, {title:'g'}],
top: 180,
scrollable: false,
});
view.add(tableview);
Ti.UI.currentWindow.add(view);
This is the window I got (StackOverflow does not allow new users to post images, sorry).
This is the window I want. The table has fixed number of rows and its parent view can be scrolled.
I have also tried to set currentWindow.layout to "vertical", but that failed since neither the scrollView nor the tableView would show up.
Thank you for your patience and help!
After looking at Kitchen Sink, Titanium's demo app, I figured out how to do this: just set tableview.style to Titanium.UI.iPhone.TableViewStyle.GROUPED, and and set the imageView as tableview.headerView.
var imageview = Ti.UI.createImageView({
image: "../images/headers/bakerinstitute_logo.png",
height: 100,
left: 40,
right: 40,
top: 10,
});
var tableview = Ti.UI.createTableView({
data: [{title:'a', header:'first one'}, {title:'b'}, {title:'c'}, {title:'d'}, {title:'e'}, {title:'f'}, {title:'g'}, {title:'h'}, {title:'i'}, {title:'j'}, {title:'k', header:'last one'}],
style:Titanium.UI.iPhone.TableViewStyle.GROUPED,
backgroundColor:'transparent',
rowBackgroundColor:'white',
headerView: imageview
});
Ti.UI.currentWindow.add(tableview);
You should check out the UICatalog sample code provided by apple. There are many views, and some of them look like the one you provided a link for. Hope that Helps!