animating two views in titanium - animation

I have two views displayed in a window as follows
var topView = Ti.UI.createView({
top: 0,
height: '65%',
orientation: 'vertical'
});
var botView = Ti.UI.createView({
bottom: 0,
height: '35%',
layout: 'vertical'
});
i want to animate as follows:
when a button is clicked, topView increases to hundred percent while botView decreases to 0 percent. and the reverse happens when the button is clicked.
But i haven't found a way to do it for two views.
I hope someone can help out.
Thanks -:)
EDIT:
This is what i have done so far:
var expandFlag = false;
/* create animations */
var expandAnim_map = Ti.UI.createAnimation({
height : '100%',
duration: 300
});
var expandAnim_con = Ti.UI.createAnimation({
height: '0%',
duration : 300,
bottom:0
});
var collapseAnim_map = Ti.UI.createAnimation({
height: '65%',
duration: 300,
});
var collapseAnim_con = Ti.UI.createAnimation({
height: '35%',
duration: 300,
bottom:0
});
/* create animations */
if (expandFlag) {
botView.animate(collapseAnim_con);
topView.animate(collapseAnim_map);
expandFlag = false;
} else {
topView.animate(expandAnim_map);
botView.animate(expandAnim_con);
expandFlag = true;
}
This is irregular and not beautiful, hence i'm looking for a cleaner and smoother way to do it. Thanks.

I suggest that you animate only one view in order to get a good looking animation.
You can set a higher zIndex for the top view, and then expand and reduce only that view.
var expandFlag = false;
var topView = Ti.UI.createView({
top: 0,
zIndex: 2,
height: '65%',
orientation: 'vertical'
});
var botView = Ti.UI.createView({
bottom: 0,
zIndex: 1,
height: '35%',
layout: 'vertical'
});
/* create animations */
var expandAnim_map = Ti.UI.createAnimation({
height : '100%',
duration: 300
});
var collapseAnim_map = Ti.UI.createAnimation({
height: '65%',
duration: 300,
});
/* create animations */
if (expandFlag) {+
topView.animate(collapseAnim_map);
expandFlag = false;
} else {
topView.animate(expandAnim_map);
expandFlag = true;
}

Related

How to add Text-transform on text in canvas using kinetic js?

I want to know how could i convert text into uppercase in canvas using kinetic js.
Here is my code for canvas with image and text:
top_text_val = "INSERT TOP TEXT"; //Default top text on meme
bottom_text_val = "INSERT BOTTOM TEXT"; //Default bottom text on meme
var stage = new Kinetic.Stage({
container: 'meme-img',
width: 735, //width of container
height: 540, //height of container
});
var layer = new Kinetic.Layer(); //new object of kinetic layer
var imageObj = new Image(); //new image object to load image
var top_text;
var bottom_text;
//image onload event code
imageObj.onload = function() {
var image_shape = new Kinetic.Image({ //set image display dimensions
image: imageObj,
width: 735,
height: 540
});
top_text = new Kinetic.Text({ // Code to display top default text on meme image
x: 100,
y: 35,
text: top_text_val,
fontSize: 80,
fontFamily: 'Impact',
fill: '#fff',
align: "center",
stroke: 'black',
strokeWidth: 4,
});
layer.add(image_shape); // add the shape to the layer
layer.add(top_text); // add top text to the layer
stage.add(layer); // add the layer to the stage
};
if(image_link.trim().length>0) imageObj.src = image_link;
Now i want to set text and want to set text in Uppercase on keyup event of some text box. Please refer below code for same:
$('#txtTop').on('keyup',function(){
var value = $(this).val();
top_text.setText(value);
if($('#chkAllCaps').is(':checked')){
//here i need code to set uppercase text-transform
}
layer.draw();
});
I have tried text-transform also but it is not working.
Please kindly help me out.
Thanks!!
string.toUpperCase() would work in this case. The toUpperCase() method converts a string to uppercase letters and it would be better to add mouse click event on #chkAllCaps element and make a function for render.
This is jsfiddle: http://jsfiddle.net/6t7ohbnh/1/
Javascript
$('#txtTop').on('keyup', function() {
render();
});
$('#chkAllCaps').on('click', function() {
render();
});
function render(){
var value = $('#txtTop').val();
if ($('#chkAllCaps').is(':checked')) {
top_text.setText(value.toUpperCase());
}else{
top_text.setText(value);
}
layer.draw();
}

Why kineticJS cannot move workings with touch or mouse?

I need to move this "box" group while touching or mousemoving inside the white-part of the screen.
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'fullscreenDiv',
width: 1180,
height: 664
});
var layer = new Kinetic.Layer();
var gamepart = new Kinetic.Rect({
x: 0,
y: 0,
width: 1180,
height: 500,
stroke: 'black',
strokeWidth: 4
});
var statuspart = new Kinetic.Rect({
x: 0,
y: 500,
width: 1180,
height: 164,
fill: 'blue',
stroke: 'black',
strokeWidth: 4
});
var group = new Kinetic.Group({
draggable: true,
dragBoundFunc: function(pos) {
return {
x: pos.x,
y: this.getAbsolutePosition().y
}
}
});
window.addEventListener('keydown', function(e) {
if (e.keyCode == 37) //Left Arrow Key
moveBoxes(-10);
if (e.keyCode == 39) //Right Arrow Key
moveBoxes(10);
stage.draw();
});
function moveBoxes(pixels)
{
group.x(group.x() + pixels);
stage.draw();
}
var oldPos = null;
var touchPos = null;
gamepart.on('touchmove mousemove', moving(stage.getPointerPosition()));
function moving(mousePos){
if(!oldPos)
oldPos = stage.getPointerPosition();
touchPos = mousePos;
var x = touchPos.x - oldPos.x;
moveBoxes(x);
}
</script>
The group is containing boxes I have added.
It is working fine to move by key-arrows and the page can be found at webpage
I think you want to use function for 'touchmove mousemove' events, neither a result of function.
gamepart.on('touchmove mousemove', function() {
moving(stage.getPointerPosition())
});

KineticJS mouse position wrong after layer rotated

My demo is here http://jsfiddle.net/akuma/7NmXw/1/
First, draw something in the blue box.
Then, click the rotate button once.
After the box has been rotated, draw something again.
Finally the draw poisitoin was wrong.
How can I fix that, thanks!
Code:
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer({
width: 400,
height: 400
});
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 400,
height: 300,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 5
});
layer.add(rect);
stage.add(layer);
$(document).on('click', '#rotateBtn', function () {
var w = layer.getWidth(),
h = layer.getHeight();
layer.setOffset(w / 2, h / 2);
layer.setPosition(w / 2, h / 2);
layer.rotateDeg(90);
layer.draw();
});
var points = [],
drawing = false;
stage.on('mousedown', function () {
drawing = true;
var pos = stage.getMousePosition();
points.push([pos.x, pos.y]);
var line = new Kinetic.Line({
id: 'line',
points: [
[pos.x, pos.y],
[pos.x + 1, pos.y + 1]
],
stroke: 'white',
strokeWidth: 5,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.drawScene();
});
stage.on('mousemove', function () {
if (!drawing) {
return;
}
// Remove previous line
layer.get('#line').remove();
var pos = stage.getMousePosition();
points.push([pos.x, pos.y]);
// Redraw line
var line = new Kinetic.Line({
id: 'line',
points: points,
stroke: 'white',
strokeWidth: 5,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.drawScene();
});
stage.on('mouseup', function () {
drawing = false;
points = [];
});
Even after rotating, Kinetic will still give you un-rotated mouse coordinates
That’s because you are asking for stage.getMousePosition and the stage is not rotated.
There is no method like layer.getMousePosition, so you’ll have to create one.
If you rotate your layer 90-degrees, you must also rotate stage's mouse coordinates by 90-degrees.
Here’s how you rotate the stage mouse position to match the layer rotation:
// get the unrotated mouse position from Kinetic
var pos=stage.getMousePosition();
// rotate that point to match the layer rotation
var x1 = rotationX
+ (pos.x-rotationX)*rotationCos
+ (pos.y-rotationY)*rotationSin;
var y1 = rotationY
+ (pos.y-rotationY)*rotationCos
- (pos.x-rotationX)*rotationSin;
Since you will be doing this math with each mousemove, you should pre-calculate the rotation values to maximize performance:
// reset the current rotation information
function setRotation(degrees){
var radians=layer.getRotation();
rotationX=layer.getOffsetX();
rotationY=layer.getOffsetY();
rotationCos=Math.cos(radians);
rotationSin=Math.sin(radians);
}
Also, a bit off-topic to your question, but...
Instead of removing / recreating a new line on every mousemove, you can “recycle” your existing line:
// set the points property of the line to your updated points array
line.setPoints(points);
Here’s code and a Fiddle: http://jsfiddle.net/m1erickson/cQATv/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:400px;
height:400px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer({width:400,height:400});
stage.add(layer);
// vars to save the current rotation information
var rotationX;
var rotationY;
var rotationCos;
var rotationSin;
setRotation(0);
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 400,
height: 300,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 5
});
layer.add(rect);
stage.add(layer);
$(document).on('click', '#rotateBtn', function () {
var w = layer.getWidth(),
h = layer.getHeight();
layer.setOffset(w / 2, h / 2);
layer.setPosition(w / 2, h / 2);
layer.rotateDeg(90);
layer.draw();
// set the info necessary to un-rotate the mouse position
setRotation(layer.getRotationDeg())
});
var points = [],
drawing = false;
stage.on('mousedown', function () {
drawing = true;
// get the rotated mouse position
pos=getPos();
points.push([pos.x, pos.y]);
var line = new Kinetic.Line({
id: 'line',
points: [
[pos.x, pos.y],
[pos.x + 1, pos.y + 1]
],
stroke: 'white',
strokeWidth: 5,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.drawScene();
});
stage.on('mousemove', function () {
if (!drawing) {
return;
}
// Remove previous line
layer.get('#line').remove();
// get the rotated mouse position
var pos = getPos();
points.push([pos.x, pos.y]);
// Redraw line
var line = new Kinetic.Line({
id: 'line',
points: points,
stroke: 'white',
strokeWidth: 5,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.drawScene();
});
stage.on('mouseup', function () {
drawing = false;
points = [];
});
// reset to the current rotation information
function setRotation(degrees){
var radians=layer.getRotation();
rotationX=layer.getOffsetX();
rotationY=layer.getOffsetY();
rotationCos=Math.cos(radians);
rotationSin=Math.sin(radians);
}
// rotate the stage mouse position
// to match the layer rotation
function getPos(x,y){
// normal space, no adjustment necessary
if(rotationCos==0){return;}
var pos=stage.getMousePosition();
var x1 = rotationX
+ (pos.x-rotationX)*rotationCos
+ (pos.y-rotationY)*rotationSin;
var y1 = rotationY
+ (pos.y-rotationY)*rotationCos
- (pos.x-rotationX)*rotationSin;
return({x:x1,y:y1});
}
}); // end $(function(){});
</script>
</head>
<body>
<button id="rotateBtn">rotate</button>
<div id="container"></div>
</body>
</html>

loading fading in background image after settimeout with Kineticjs

Is it possible to change the background with an image fading in after a set time?
I am using the following code, but the image is not fading in. All I am achieving now is fading out the image with the transitionTo method, however I want it to fade in.
This is the code I am playing with:
var stage = new Kinetic.Stage({
container: 'container',
width: 1770,
height: 900
});
var layer = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
var myBg = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width: 1770,
height: 900
});
// add the shape to the layer
layer.add(myBg);
// add the layer to the stage
stage.add(layer);
setTimeout(function() {
myBg.transitionTo({
opacity: 0,
duration: 4,
});
}, 3000);
};
imageObj.src = 'bg.png';
Can someone kindly shed some light?
It happens because you did not set initial opacity. What you were doing is setting opacity from 1 to 1, not from 0 to 1. please refer the following code.
var myBg = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
opacity: 0,
width: 1770,
height: 900
});
myBg.transitionTo({
opacity: 1,
duration: 4,
})

complex clipping boundary in kinetic.js with draggable image

Check out my html5 based clipping constraint on
http://shedlimited.debrucellc.com/test3/canvaskinclip.html
(messing with jsfiddle on http://jsfiddle.net/aqaP7/4/)
So, in html5 I can easily draw a shaped boundary like the following:
context.beginPath();
context.moveTo(5, 5);
context.lineTo(34, 202);
context.lineTo(2, 405);
context.lineTo(212, 385);
context.lineTo(425, 405);
context.lineTo(400, 202);
context.lineTo(415, 10);
context.lineTo(212, 25);
context.clip();
In kinetic.js though, all I see for clipping options is: height, width, and x, y,
I came across the following : Mask/Clip an Image using a Polygon in KineticJS, but the inner/fill image can't be set to draggable
any help please!
In the new kineticJS versions, a lot of the work is done in the background for you.
Take a look at this tutorial:
This fiddle gets you pretty close, here's the code:
<body>
<div id="container"></div>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.0-beta2.js"></script>
<script>
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function draw(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 600,
height: 700
});
var layer = new Kinetic.Layer();
var patternPentagon = new Kinetic.RegularPolygon({
x: 220,
y: stage.getHeight() / 4,
sides: 5,
radius: 70,
fillPatternImage: images.yoda,
fillPatternOffset: [-220, 70],
stroke: 'black',
strokeWidth: 4,
draggable: true
});
patternPentagon.on('dragmove', function() {
//this.setFillPatternImage(images.yoda);
//this.setFillPatternOffset(-100, 70);
var userPos = stage.getUserPosition();
this.setFillPatternOffset(-userPos.x,-userPos.y);
layer.draw();
this.setX(220);
this.setY(stage.getHeight() / 4);
});
layer.add(patternPentagon);
stage.add(layer);
}
var sources = {
darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg',
yoda: 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg'
};
loadImages(sources, function(images) {
draw(images);
});
</script>
</body>
There is a more complex/accurate way of doing this without making it a background pattern, like with grouping objects together

Resources