Xamarin.Forms Page Animation - animation

I'm trying to make an animation for my page. I want that animation to get fired only when the page is first loaded.
My animation code is working, sample:
public async Task BackgroundFlyUp()
{
var destinationRect = new Rectangle(0, Application.Current.MainPage.Height * (1 - FoodViewsConstants.FLY_UP_END),
Application.Current.MainPage.Width, Application.Current.MainPage.Height * FoodViewsConstants.FLY_UP_END);
await FlyUp.LayoutTo(destinationRect, FoodViewsConstants.FLY_UP_SPEED, Easing.Linear);
await ContentGrid.FadeTo(1, FoodViewsConstants.CONTENT_FADE_SPEED);
}
Although I don't want my animation to get fired every time OnAppearing is fired, I've tried to add the animation code in my OnAppearing method but it doesn't work right. (the fade is working but the FlyUp not) and being an async method, it can't be placed in the constructor. Can you guys help me out?

Based on my test, I guess you do not get the correct from destinationRect. The Application.Current.MainPage.Width and Application.Current.MainPage.Height would get the width and height except on initial load when the MainPage hadn't been presented yet.
You could use the screen size instead.
public async Task BackgroundFlyUp()
{
// Get Metrics
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
// Width (in pixels)
var width = mainDisplayInfo.Width;
// Height (in pixels)
var height = mainDisplayInfo.Height;
var destinationRect = new Rectangle(0, height * (1 - FoodViewsConstants.FLY_UP_END),
width, height * FoodViewsConstants.FLY_UP_END);
await FlyUp.LayoutTo(destinationRect, 5000, Easing.Linear);
await ContentGrid.FadeTo(1, FoodViewsConstants.CONTENT_FADE_SPEED);
}

Related

UIScrollView's does not scroll AFTER rendering WKWebView content

Thank you for looking at my question. Currently, I have several input fields and a WKWebView embedded in a UIScrollView. Before any events fire, all the subviews fit inside the scroll view with no issue. I'm dynamically setting the WK's height based on document.body.scrollHeight which is captured in the DidFinishNavigation delegate located in WKNavigationDelegate. After the WK's height is set, the WK extends past the view-able content. Here's the code which I'm trying to force the scrollview to resize itself.
[Export("webView:didFinishNavigation:")] public async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
//get the webView's initial height
var initialHeight = webView.Frame.Height;
//get height of HTML's document.body.scrollHeight
var contentHeight = await GetContentHeight();
//create new frame for webview
CGRect newWebViewFrame = new CGRect(webView.Frame.X, webView.Frame.Y, webView.Frame.Width, contentHeight);
//set webview's frame
webView.Frame = newWebViewFrame;
//get the difference of webView's initial height and webView's current height
var differenceInHeight = contentHeight - initialHeight;
//create new cgrect and set the height to svMain's height + the difference in height of the HTML document
CGRect newScrollViewFrame = new CGRect(0, 0, svMainScroller.Frame.Width, svMainScroller.Frame.Height + differenceInHeight);
//set MainScroller's frame
svMainScroller.Frame = newScrollViewFrame;
//force scrolling
svMainScroller.ScrollEnabled = true;
//scrolling should be handled in the main scroller
webView.ScrollView.ScrollEnabled = false;
svMainScroller.SizeToFit();
}
The desired effect is to have the scroll view be able to scroll to the end of the newly defined height. Any tips on how would I go about doing that would be greatly appreciated.
Updating the frame of the scroll view was the problem. My guess is that if the frame is big enough to contain all of the contents, then there's no need to scroll. So, I updated the scroll view's ContentSize instead of updating its frame.
svMainScroller.ContentSize = new CGSize(View.Frame.Width, View.Frame.Height + differenceInHeight);
Also, as a side note, verify that wkwebview is added as a subview to the scroll view and not the main view.

Github Doesn't Recognize JQuery Image Height

I'm working with a function that uses an image to set a div's margin-top.
It finds the image height and the window height and sets the divs margin-top to the lesser of the two values. It works perfectly fine for all local browsers (IE, Chrome, Firefox).
When I upload it to GitHub it fails to recognize the image height however. Now when I run the code below on GitHub the console.log of the image height is 0. When I run it locally the console.log of the image height is correct. The image is loaded on GitHub, so it's not an issue of the image not making into the web page.
It seems like the script runs before the image loads on GitHub, but not locally. Anyone have any ideas?
var portfolioMargin = function() {
var windowHeight = window.innerHeight;
var imageHeight = $('#imageWrap img').height();
//if windowheight is bigger than image height make portfolio div margin equal to image height, else do the opposite
console.log("window height " + windowHeight);
console.log("image height " + imageHeight);
if (windowHeight > imageHeight) {
$('#portfolio').css('margin-top', imageHeight);
} else {
$('#portfolio').css('margin-top', windowHeight);
}
};//end portfolioMargin function
So I figured it out I think. You have to wrap the function in a window.load function to make sure all images have been loaded. From what I understand this won't work for dynamically added images however. Here is the code that fixed it:
//make sure images have loaded before running image height
$(window).load(function() {
portfolioMargin();
});

The sprite animation in my simple easeljs script is not showing up

I am trying my hand at easeljs and animating a spritesheet. This is the first time I am working with sprites and as such am not knowledgeable about them.
My simple easeljs code to show this specific animation is;
var stage;
function init() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage(document.getElementById("demoCanvas"));
var data = {
images: ["http://i.imgur.com/g5WtL7v.png"],
frames: {width:256, height:256},
animations: {
run:[0,4]
}
};
var spriteSheet = new createjs.SpriteSheet(data);
var animation = new createjs.BitmapAnimation(spriteSheet);
animation.gotoAndPlay("run");
}
But the sprite doesn't shows up on the canvas at all. WHat am I doing wrong?
Additional question;
defining frames in easeljs can be done by
frames: [ // x, y, width, height, imageIndex, regX, regY
While I do understand width and height, what are x, y, imageIndex and regX, regY. The documentaion explains how I can use these parameters but for someone who is working with sprites for the 1st time in my life, I just dont know what these terms mean.
EDIT: I have also tried changing the code as such;
var stage;
function init() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage("demoCanvas");
var data = {
images: ["http://i.imgur.com/g5WtL7v.png"],
frames: {width:256, height:256, count:8},
animations: {
run:[0,4, true]
}
};
var ss = new createjs.SpriteSheet(data);
var animation = new createjs.BitmapAnimation(ss);
animation.x = 100;
animation.y = 100;
stage.addChild(animation);
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener("tick", stage);
}
But I am still seeing a blank canvas...
You are missing a frame-count in the frames-object:
frames: {width:...,height:...,count:4} // or whatever number of frames your sprite holds
And just in case: The width and height is the width and height of 1 frame, not the entire image.
See more information and examples here: http://www.createjs.com/Docs/EaselJS/classes/SpriteSheet.html
ok i got things to work by combining both the codes that I have listed above;
var stage;
function init() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage("demoCanvas");
var data = {
images: ["http://i.imgur.com/g5WtL7v.png"],
frames: {width:256, height:256, count:8},
animations: {
run:[0,4, true]
}
};
var ss = new createjs.SpriteSheet(data);
var animation = new createjs.BitmapAnimation(ss);
animation.x = 100;
animation.y = 100;
stage.addChild(animation);
animation.gotoAndPlay("run");
createjs.Ticker.setFPS(10);
createjs.Ticker.addEventListener("tick", stage);
}
Now I have some questions;
If I need animation.gotoAndPlay("run"); to animate the sprite how come the code at https://github.com/CreateJS/EaselJS/blob/master/examples/SpriteSheet_simple.html doesn't needs it?
whats the difference between new createjs.Sprite(ss, "run"); and new createjs.BitmapAnimation(spriteSheet); . I am unable to find any documentation of the former.

AS3 stagesized Bitmap and update regions

I have a project where i'm drawing to a stageSized bitmap by using BitmapData.draw
using the 'show update regions' feature of the debug player, i can see that the player always updates the whole stage although i changed only a small part of the bitmapdata.
Can I somehow make the player only update that part of the screen where there were changes made to the bitmap data?
Would it be possible to use copyPixels instead? It only allows copying from another BitmapData, but most of the time that should be fine (you could always cache animations to bitmapdata once, and then use the cached data instead of the Draw-method). Flash player should be able to redraw only the altered parts when you use copyPixels.
However, the real question; is this really an issue? Don't optimize these things unless you actually need to :)
If you're only redrawing part of the bitmap, then only that part should get updated by Flash Player.
You can see it in action here:
public class Test extends Sprite
{
public function Test()
{
stage.align = "topLeft";
stage.scaleMode = "noScale";
var bitmap:Bitmap = new Bitmap();
addChild(bitmap);
var bd:BitmapData = new BitmapData(400, 400);
bitmap.bitmapData = bd;
// One-second timer.
var timer:Timer = new Timer(1000);
timer.start();
timer.addEventListener("timer", timerHandler);
}
private function timerHandler(event:Event):void
{
var bitmap:Bitmap = Bitmap(getChildAt(0));
var bd:BitmapData = bitmap.bitmapData;
// Draw 100x100 square in random location, with random color.
var xPos:Number = Math.random() * 300;
var yPos:Number = Math.random() * 300;
var matrix:Matrix = new Matrix(1, 0, 0, 1, xPos, yPos);
var color:uint = Math.round(Math.random() * 0xFFFFFF) | 0xFF000000;
var colorTransform:ColorTransform = new ColorTransform();
colorTransform.color = color;
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
g.beginFill(0xFFFFFF);
g.drawRect(0, 0, 100, 100);
g.endFill();
bd.draw(shape, matrix, colorTransform);
}
}
Try this with "Show Redraw Regions" in the standalone Flash Player, and you'll see it updates only the newly drawn part on each tick.

Can we get the real image size through the canvas?

In image tag, if we don't supply width and height property, we will get nothing when retrieving the width and the height of the image. I am using the canvas element to load an image and scale it proportionally. In order to do this, I have to get the actual image size. Is it possible to do that in html 5?
The HTMLImageElement has two properties for this, naturalWidth and naturalHeight. Use those.
As in:
var img = new Image();
img.addEventListener('load', function() {
// once the image is loaded:
var width = img.naturalWidth; // this will be 300
var height = img.naturalHeight; // this will be 400
someContext.drawImage(img, 0, 0, width, height);
}, false);
img.src = 'http://placekitten.com/300/400'; // grab a 300x400 image from placekitten
It is wise to set source only after the event listener is defined, see Phrogz's exploration on that here: Should setting an image src to data URL be available immediately?
You cannot retrieve width/height before image has been loaded.
Try something like:
// create new Image or get it right from DOM,
// var img = document.getElementById("myImage");
var img = new Image();
img.onload = function() {
// this.width contains image width
// this.height contains image height
}
img.src = "image.png";
Anyhow onload will not fire if image has been loaded before script execution. Eventually you can embed script in html <img src="test.jpg" onload="something()">
if I understand you correctly, you can use the getComputedStyle method.
var object = document.getElementById(el);
var computedHeight = document.defaultView.getComputedStyle(object, "").getPropertyValue("width");
Not fully understood your question.
But you can use javascript to get the width and height of the image.
and then pass it into
/ Five arguments: the element, destination (x,y) coordinates, and destination
// width and height (if you want to resize the source image).
context.drawImage(img_elem, dx, dy, dw, dh);
while drawing image on canvas.
or check this if it helps
http://jsfiddle.net/jjUHs/

Resources