I wanted to have a start screen where the user could pick the language they want the app to run in and display some example exercises.
As the screen dimensions could be anything, I wrote some code to layout images to fit the entire screen using the absolute layout.
On top of this, I added the title banner and then I added a timer to randomly swap the location of two images every 200 milliseconds.
An example can be seen below.

If you wanted to, you could make the images move positions, rather than just swap positions using the new animation framework coming in version 1.3. See another example here.
XML
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
<GridLayout columns="*" rows="*,auto" cssClass="page">
<AbsoluteLayout row="0" column="0" id="absoluteLayout"/>
<Image src="{{image}}" row="0" column="0" verticalAlignment="center"/>
<GridLayout cssClass="footer" row="1" column="0" rows="auto" columns="50,*,50">
<Image src="{{flag}}" cssClass="flagimage" col="0" row="0"/>
<Label text="{{lang}}" tap="{{goDefault}}" col="1" row="0" textAlignment="left"/>
<Image src="~/res/icons/white/ellipsis_white.png" cssClass="iconwhitesmall" tap="{{goOther}}" row="0" col="2"/>
</GridLayout>
</GridLayout>
</Page>
Page code
import observable = require("data/observable");
import pages = require("ui/page");
import model = require("./intro-view-model");
import absoluteLayout = require("ui/layouts/absolute-layout");
export function pageLoaded(args: observable.EventData) {
var page = <pages.Page>args.object;
page.bindingContext = model.viewModel;
model.viewModel.placeImages(<absoluteLayout.AbsoluteLayout>page.getViewById("absoluteLayout"));
}
Model code
/* tslint:disable:use-strict triple-equals max-line-length one-line */
import observableHelper = require("../../helpers/observablehelper");
import applicationSettingsHelper = require("../../helpers/applicationsettingshelper");
import languageOption = require("../../res/data/languageoption");
import frames = require("ui/frame");
import recordDevice = require("../../helpers/recorddevice");
import absoluteLayout = require("ui/layouts/absolute-layout");
import platform = require("platform");
import image = require("ui/image");
var languageOptions: Array<languageOption.LanguageOption> = languageOption.data();
enum fields { image, lang, flag };
interface IPosition {
left: number;
top: number;
}
export class Model extends observableHelper.BaseModel<fields> {
constructor() {
super(fields);
this.setValue(fields.image, "~/res/banner/banner.png");
var languageChosen = applicationSettingsHelper.getLanguage();
this.setValue(fields.lang, languageChosen);
var flag = "";
for (var i = 0, imax = languageOptions.length; i < imax; i++) {
if (languageOptions[i].Lang == languageChosen) {
flag = "~/res/flags/" + languageOptions[i].Flag.toLowerCase() + ".png";
break;
}
}
this.setValue(fields.flag, flag);
recordDevice.recordDevice();
}
// scaling for images
scale = 1;
// image store
imagesArray: Array<image.Image> = [];
// determine screen dimensions and place images in absolute layout to fill the entire screen
// then set the images source and then randomly swap two image locations every 200 milliseconds
placeImages(layout: absoluteLayout.AbsoluteLayout) {
var deviceWidth = platform.screen.mainScreen.widthPixels / platform.screen.mainScreen.scale,
deviceHeight = platform.screen.mainScreen.heightPixels / platform.screen.mainScreen.scale,
doExit = false,
leftPos = 0,
topPos = 0,
imageHeight = 49 * this.scale,
imageWidth = 40 * this.scale;
// add images until the screen is completely full
while (!doExit) {
var imageAdd = new image.Image();
imageAdd.width = imageWidth;
imageAdd.height = imageHeight;
absoluteLayout.AbsoluteLayout.setLeft(imageAdd, leftPos);
absoluteLayout.AbsoluteLayout.setTop(imageAdd, topPos);
layout.addChild(imageAdd);
leftPos = leftPos + imageWidth + 2;
if (leftPos > deviceWidth) {
topPos = topPos + imageHeight + 2;
leftPos = 0;
}
if (topPos > deviceHeight) {
doExit = true;
}
this.imagesArray.push(imageAdd);
}
// set images
this.setImages();
// swap images on timer
setTimeout(() => {
this.setPositions();
}, 200);
}
// Randomly pick two images and swap their locations
setPositions() {
// Pick two images randomly
var oldPosition = Math.round(Math.random() * (this.imagesArray.length - 1));
var newPosition = Math.round(Math.random() * (this.imagesArray.length - 1));
// swap Locations
var imageAdd = this.imagesArray[oldPosition];
var imageAddPos = { left: absoluteLayout.AbsoluteLayout.getLeft(imageAdd), top: absoluteLayout.AbsoluteLayout.getTop(imageAdd) };
var imageAdd2 = this.imagesArray[newPosition];
var imageAdd2Pos = { left: absoluteLayout.AbsoluteLayout.getLeft(imageAdd2), top: absoluteLayout.AbsoluteLayout.getTop(imageAdd2) };
absoluteLayout.AbsoluteLayout.setLeft(imageAdd, imageAdd2Pos.left);
absoluteLayout.AbsoluteLayout.setTop(imageAdd, imageAdd2Pos.top);
absoluteLayout.AbsoluteLayout.setLeft(imageAdd2, imageAddPos.left);
absoluteLayout.AbsoluteLayout.setTop(imageAdd2, imageAddPos.top);
setTimeout(() => {
this.setPositions();
}, 200);
}
// loop through images and set the image source, 90 "interesting" images to pick from
setImages() {
var imageCounter = 0;
for (var i = 0, imax = this.imagesArray.length; i < imax; i++) {
if (imageCounter == 90) {
imageCounter = 1;
}
else {
imageCounter = imageCounter + 1;
}
this.imagesArray[i].src = "~/res/banner/" + imageCounter + ".jpg";
}
}
goDefault() {
frames.topmost().navigate({
moduleName: "./views/main/main-page"
});
}
goOther() {
frames.topmost().navigate({
moduleName: "./views/language/language-page"
});
}
}
export var viewModel = new Model();
No comments:
Post a Comment