Composition animation on a visual sub channel - win-universal-app

I use the new Composition Animation API in UWP (Windows 10 1607) to animate a custom control. I want changes of the vertical offset of its children to be animated, but not changes to the horizontal offset.
I can animate the whole offset (X and Y) like this:
var offsetAnimation = compositor.CreateVector3KeyFrameAnimation();
offsetAnimation.Target = "Offset";
offsetAnimation.Duration = TimeSpan.FromSeconds(0.5);
offsetAnimation.InsertExpressionKeyFrame(1.0f, "This.FinalValue");
animationCollection["Offset"] = offsetAnimation;
var visual = ElementCompositionPreview.GetElementVisual(child);
visual.ImplicitAnimations = animationCollection;
I expected this code to only animate the Y offset of the child, but it doesn't display any animation at all:
var offsetAnimation = compositor.CreateScalarKeyFrameAnimation();
offsetAnimation.Target = "Offset.Y";
offsetAnimation.Duration = TimeSpan.FromSeconds(0.5);
offsetAnimation.InsertExpressionKeyFrame(1.0f, "This.FinalValue");
animationCollection["Offset"] = offsetAnimation;
var visual = ElementCompositionPreview.GetElementVisual(child);
visual.ImplicitAnimations = animationCollection;
Setting Target to "Offset.y" or the trigger to "Offset.Y" doesn't help.
I haven't found an example using visual sub channels in the documentation, so I would appreciate any help on how to only animate the y channel of the offset.

According to your code snippet, you set a Offset trigger for the animation. That means once the offset of child is changed, this animation will started. And you set 'This.FinalValue' for the ExpressionKeyFrame, so it will bind the value you set to the new offset and it will animate to that new value.
So we if we just set the new offset to only have y value changed (let x and z be same as the old one), the animation will only animate the y channel.
Code like follows:
<TextBlock x:Name="txtanimation" Text="animation test" Height="30" Width="100" Foreground="Red" ></TextBlock>
<Button x:Name="btnanimate" Click="btnanimate_Click" Content="Animate y" Margin="60"></Button>
Code behind:
Visual visual;
public MainPage()
{
this.InitializeComponent();
visual = ElementCompositionPreview.GetElementVisual(txtanimation);
Compositor compositor = ElementCompositionPreview.GetElementVisual(txtanimation).Compositor;
ImplicitAnimationCollection animationCollection = compositor.CreateImplicitAnimationCollection();
Vector3KeyFrameAnimation offsetAnimation = compositor.CreateVector3KeyFrameAnimation();
offsetAnimation.Target = "Offset";
offsetAnimation.Duration = TimeSpan.FromSeconds(2.5);
offsetAnimation.InsertExpressionKeyFrame(1.0f, "This.FinalValue");
animationCollection["Offset"] = offsetAnimation;
visual.ImplicitAnimations = animationCollection;
}
private void btnanimate_Click(object sender, RoutedEventArgs e)
{
visual.Offset=visual.Offset+ new System.Numerics.Vector3(0f, 400f, 0f);
}
And the result:
More samples please reference WindowsUIDevLabs. And more details you can reference videos like Implicit Animations.

Related

Drag & Drop (swap) 3 texture buttons in a Margin Container->VBox

Following along a great tutorial, code is replicated yet does not function as shown. No new texture appears to be created when I try to drag the texture button. Only difference is the tutorial uses a TextureRect, while I'm using a TextureButton.
extends TextureButton
func get_drag_data(position: Vector2):
var vControl = Control.new()
var vData = {}
var vTexture = TextureRect.new()
vTexture.expand = true
vTexture.texture = texture_disabled
vTexture.rect_size = Vector2(320, 400)
vControl.add_child(vTexture)
vTexture.rect_position = -0.5 * vTexture.rect_size
set_drag_preview(vTexture)
return vData
Code above is attached to Party_1. texture_disabled does have a texture set.
It would work if you had the code in get_drag_data looking like this:
func get_drag_data(_position: Vector2):
var vTexture = TextureRect.new()
vTexture.expand = true
vTexture.texture = texture_disabled
vTexture.rect_size = Vector2(320, 400)
set_drag_preview(vTexture)
return {}
However, that would place the TextureRect top-left corner at the cursor position.
You want to offset the position of the TextureRect so it is centered at the cursor position. To do that, you create another Control, add the TextureRect as a child to it… And pass the TextureRect anyway? No, that does not work, you need to pass the new Control:
func get_drag_data(_position: Vector2):
var vTexture = TextureRect.new()
vTexture.expand = true
vTexture.texture = texture_disabled
vTexture.rect_size = Vector2(320, 400)
var vControl = Control.new()
vControl.add_child(vTexture)
vTexture.rect_position = -0.5 * vTexture.rect_size
set_drag_preview(vControl)
return {}
Please notice I'm giving vControl to set_drag_preview, not vTexture.
You cannot give to set_drag_preview a Control that has a parent. In fact, if you tried you would get an error in the Output console saying:
_gui_set_drag_preview: Condition "p_control->get_parent() != nullptr" is true.
Or
_gui_set_drag_preview: Condition "p_control->is_inside_tree()" is true.

How do I change font sizes in Heaps?

I'm currently coding in Haxe with Heaps and was checking on how to display text. One thing I want to do is give different font sizes to different texts. Naturally, I declared two Font instances and resized one of them. However, both texts are resized and I cannot manage to have them resize independently. How should I resize font sizes in Heaps?
class Main extends hxd.App{
override function init(){
var font : h2d.Font = hxd.res.DefaultFont.get();
var font2 : h2d.Font = hxd.res.DefaultFont.get();
font2.resizeTo(23);
var tf = new h2d.Text(font);
var tf2 = new h2d.Text(font2);
tf.text = "Hello World\nHeaps is great!";
tf.textColor = 0x00FF00;
tf.x = 100;
tf.y = 100;
tf.textAlign = Center;
tf2.text = "Hello World\nHeaps is great!";
tf2.textColor = 0x00FF00;
tf2.x = 300;
tf2.y = 300;
tf2.textAlign = Center;
s2d.addChild(tf);
s2d.addChild(tf2);
static function main(){
new Main();
}
}
The approach taken does not work because DefaultFont.get() caches the result.
You could either:
Copy the second font by doing var font2 : h2d.Font = font.clone() so that it gets its own properties.
Adjust scaleX and scaleY of Text.

UWP - How to create a TokenAutoComplete Control

I am developing UWP (Win10 - VS2015) App. I need a Token TextBox in Windows Platform. Any idea please, how to start and create this control, then when writing text inside the Textbox and put space or just tap that text, it should convert into selected Token. See the pic (its just for idea). I need such type of control.
You can also get idea from this Post TokenAutoComplete
The code which I'm posting is initial code you can start builting control with..
I used RichTextBlock and Textbox. If you put these two controls in WrapPanel inside the Gridview. You might get similar control which you wanted but I haven't tried it.
<RichTextBlock x:Name="tokenblock">
<Paragraph>
</Paragraph>
</RichTextBlock>
<TextBox TextChanged="TextBox_TextChanged"/>
Code behind is like this
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string text = (sender as TextBox).Text;
if (text.Contains(';'))
{
Paragraph para;
text = text.Substring(0, text.LastIndexOf(';'));
if (tokenblock.Blocks.Count > 0)
para = tokenblock.Blocks[0] as Paragraph;
else
para = new Paragraph();
InlineUIContainer inline = new InlineUIContainer();
Border br = new Border();
br.Background = new SolidColorBrush(Colors.Gray);
br.CornerRadius = new CornerRadius(10);
TextBlock tb = new TextBlock();
br.MinWidth = 70;
br.MaxWidth = 150;
tb.Text = text;
tb.TextWrapping = TextWrapping.Wrap;
tb.Margin =new Thickness(10, 10, 10, 10);
br.Child = tb;
inline.Child = br;
para.Inlines.Add(inline);
(sender as TextBox).Text = "";
}
//below codes I haven't tried
<GridView x:Name="myGridView" IsItemClickEnabled="True">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="5"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
//here you have to put RichTextBlock and textbox as two gridview items

How to access gradient editor in Unity3D?

I was searching through the Unity manual to see what they had for gradient effects and I found this:
Here is the link:
http://docs.unity3d.com/Manual/EditingValueProperties.html
However, I can't find this editor anywhere inside of Unity. I want to use this to apply a gradient to my background for a game. Does it exist!?
You do not have access to arbitrarily use color picker or gradient editor. For your purpose of making the background you have several options,
Change the Camera background color from the editor.
Use a Skybox, you can make your own skybox too.
If your game has a limited view, use a plane with a custom material.
Maybe this script shows how you can use Gradients. You need to add this script to one of your GameObject in your scene. And your Camera's tag is MainCamera .
This code based on this.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GradientHandler : MonoBehaviour {
public Camera camera;
public Gradient gradient;
// Use this for initialization
void Start () {
camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>() as Camera; //Gets Camera script from MainCamera object(Object's tag is MainCamera).
GradientColorKey[] colorKey = new GradientColorKey[2];
GradientAlphaKey[] alphaKey = new GradientAlphaKey[2];
// Populate the color keys at the relative time 0 and 1 (0 and 100%)
colorKey[0].color = Color.red;
colorKey[0].time = 0.0f;
colorKey[1].color = Color.blue;
colorKey[1].time = 1.0f;
// Populate the alpha keys at relative time 0 and 1 (0 and 100%)
alphaKey[0].alpha = 1.0f;
alphaKey[0].time = 0.0f;
alphaKey[1].alpha = 0.0f;
alphaKey[1].time = 1.0f;
gradient.SetKeys(colorKey, alphaKey);
}
// Update is called once per frame
void Update () {
Debug.Log ("Time: "+Time.deltaTime);
camera.backgroundColor = gradient.Evaluate(Time.time%1);
}
}

Dragging a circle

I am beginning to use snap.svg, and stuck in a probably simple question. I draw a circle, and want to let the user drag it around, and when the user stops dragging, I want to know the alert the final position of the circle.
I started with this:
var s = Snap("#svg");
var d = s.circle(20,20,5);
Then I created the following functions as drag event-handlers; I only need the drag-end event so I made the two other event-handlers null:
var endFnc = function(e) {
alert("end: "+e.layerX+","+e.layerY);
}
var startFnc = null;
var moveFnc = null;
Then I installed the drag event handlers:
d.drag(moveFnc,startFnc,endFnc);
Whenever I tried to drag a circle, the end event fired, but, the circle did not move.
So I figured maybe I have to also create the drag move event (although I don't need it):
var moveFnc = function(dx, dy, x, y) {
this.transform('t' + x + ',' + y);
}
Now the circle did move, but, not exactly at the mouse, but approximately 20 pixels at its bottom right.
I read the documentation here: http://snapsvg.io/docs and there seems to be no explanation about how to create working drag events.
How does anyone get this knowledge?!
After struggling for some hours to do this with snap.js, I finally discovered svg.js and its draggable plugin, with which it is so much easier:
var draw = SVG('svg');
var circle = draw.circle(10).attr({cx:30,cy:30,fill:'#f06'});
circle.dragend = function(delta, event) {
alert(this.attr('cx'))
}
circle.draggable();
So, I switched to svg.js ...

Resources