This is a migrated thread and some comments may be shown as answers.

Custom transitions

3 Answers 149 Views
TransitionControl
This is a migrated thread and some comments may be shown as answers.
hwsoderlund
Top achievements
Rank 1
hwsoderlund asked on 14 Apr 2010, 10:22 AM
Hi, I am playing around with the transition control and would like to write a custom transition. I have looked at the sample code in the demo, and found the following pixel shader code:

sampler2D input : register(s0); 
sampler2D oldInput : register(s1); 
 
float progress : register(c0); 
 
float4 main(float2 uv : TEXCOORD) : COLOR  
{    
    float4 oldColor = tex2D(oldInput, uv); 
    float4 newColor = tex2D(input, uv); 
     
    float a = (4.0 * progress - (uv.x + uv.y)) * 0.5; 
     
    if (a < 0) a = 0; 
    if (a > 1) a = 1; 
     
    return oldColor * (1 - a) + newColor * a; 

The problem is that I don't understand much of it. Can you give me some more info on the way these animated shaders work? I have googled around and found some info on static shaders, which more or less just act as a filter for an image or something. But nothing on the animated stuff that you guys are using for the transitions. I am trying to create a combination of a fade-in and a zoom effect where the content is faded in from 20% opacity to 100% and at the same time scaled from 150% to 100%. So both these changes should occur simultaneously. Any hints would be much appreciated.


3 Answers, 1 is accepted

Sort by
0
Miroslav Nedyalkov
Telerik team
answered on 15 Apr 2010, 02:00 PM
Hi Henrik,

 You are correct that shader effects act like filters. What we do is to apply the filter on two bitmaps - the current content of the control that is rendered by the Silverlight rendering engine and the old content, previously rendered by it. What we do is to take a picture of the content just before changing it.

Now about the shader effect - we pass these two bitmaps to the shader (actually the current bitmap is passed automatically). The current bitmap is passed to s0 register (the parameter with name input and type sampler2D) and the old one is passed to the s1 register (the parameter with name oldInput and type sampler2D).

The shader code is actually executed for every single pixel of the resulting bitmap (the one that will be actually rendered on the screen).

In order to make the shader animated we use one more parameter called progress that is written to the c0 register and its type is double. Its value 0.0 marks the beginning of the transition (that means the user sees the oldInput only) and the 1.0 - the end (the user sees newInput only). The idea is that your filter depends on the progress and when the progress is animated the filter is animated as well.

For your scenario I would suggest you to inherit from the SlideAndZoomTransitionEffect and to override its OnProgressChanged method. This will allow you to reuse one of our built-in shader effects to accomplish the task - we implement zooming, sliding and fading in this effect you can control it using CLR properties. As example how we use this I will show our default implementation of this method that does slide and zoom animation with fade:

/// <summary>
/// This method is called when the progress of the transition is changed. When overriden it should take care of moving the transition.
/// </summary>
/// <param name="oldProgress">The old progress of the transition.</param>
/// <param name="newProgress">The new progress of the transition.</param>
protected override void OnProgressChanged(double oldProgress, double newProgress)
{
    double directionMultiplier = this.SlideDirection == FlowDirection.RightToLeft ? 1 : -1;
    double minAlpha = this.MinAlpha;
    double minZoom = this.MinZoom;
    double timeBeforeSlide = this.StartSlideAt;
 
    double timeForSlide = (1.0 - timeBeforeSlide * 2);
    double zoomProgress = 0.0;
    double slideProgress = 0.0;
 
    if (newProgress < timeBeforeSlide)
    {
        zoomProgress = newProgress / timeBeforeSlide;
    }
    else if (newProgress <= timeBeforeSlide + timeForSlide)
    {
        zoomProgress = 1.0;
        slideProgress = (newProgress - timeBeforeSlide) / timeForSlide;
    }
    else
    {
        zoomProgress = (1.0 - newProgress) / timeBeforeSlide;
        slideProgress = 1.0;
    }
 
    // New content.
    this.Alpha1 = slideProgress == 0.0 ? (1.0 - ((1.0 - minAlpha) * (1.0 - zoomProgress))) : 1.0;
    this.Zoom1 = 1.0 - ((1.0 - minZoom) * zoomProgress);
 
    var slide = slideProgress * this.Zoom1;
 
    this.YOffset1 = (1.0 - this.Zoom1) / 2;
    this.XOffset1 = (1.0 - this.Zoom1) / 2 + (1.0 - slide) * directionMultiplier;
 
    // Old content.
    this.Alpha2 = 1.0 - ((1.0 - minAlpha) * slideProgress);
    this.Zoom2 = 1.0 - ((1.0 - minZoom) * zoomProgress);
    this.YOffset2 = (1.0 - this.Zoom2) / 2;
    this.XOffset2 = (1.0 - this.Zoom2) / 2 - slide * directionMultiplier;
 
    this.XOffset1 -= (1.0 - this.Zoom1) / 2 + (1.0 - this.Zoom2) / 2;
}

If you have further questions, don't hesitate to ask.

Regards,
Miroslav Nedyalkov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
hwsoderlund
Top achievements
Rank 1
answered on 15 Apr 2010, 03:25 PM
Ok, thanks a lot for the info. Your approach sounds a lot easier than writing my own pixel shader. However, I have tried deriving from SlideAndZoomTransition (I could not find the SlideAndZoomTransitionEffect that you are referring to in your answer), but it does not seem to have an OnProgressChanged event that I can override. I am using the latest SL3 internal build (RadControls_for_Silverlight_2010_1_0412_Dev). Is this perhaps something that have not yet made its way into the code base ?


0
Miroslav Nedyalkov
Telerik team
answered on 19 Apr 2010, 01:38 PM
Hi Henrik,

 I just noticed that this class is marked internal. We will consider making it public.

Kind regards,
Miroslav Nedyalkov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Tags
TransitionControl
Asked by
hwsoderlund
Top achievements
Rank 1
Answers by
Miroslav Nedyalkov
Telerik team
hwsoderlund
Top achievements
Rank 1
Share this question
or