Silverlightでfullscreen & resize

TechCollab2008-05-14


今日はSilverlightでのfullscreenとresizeの実装について整理してみようと思う。WPFではViewboxという便利なレイアウトクラスがあるがSilverlightにはないので独自に実装しなくてはならない。ということで、Silverlight 1.0とSilverlight 2.0 betaのそれぞれの実装についてまとめる。基本的にViewboxの機能を持たせるためにウィンドウのリサイズ、フルスクリーンイベントを受けてCanvasのscaleとtranslateを変更させているだけ。コードはコールバックのロジックのみを載せる。サンプルのソースはこちら


Silverlight 2.0 beta

http://viralfeed.net/sample/fullscreen2/

C#による実装。

    public partial class Page : UserControl
    {
        private double _originalWidth;
        private double _originalHeight;

        public Page()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            _originalWidth = rootCanvas.Width;
            _originalHeight = rootCanvas.Height;

            Resize();
            Application.Current.Host.Content.Resized += new EventHandler(Content_Resized);
        }

        void Content_Resized(object sender, EventArgs e)
        {
            Resize();
        }

        private void FullScreenButton_Click(object sender, RoutedEventArgs e)
        {
            Content content = Application.Current.Host.Content;
            content.IsFullScreen = !content.IsFullScreen;
            Resize();
        }

        private void ImageMenu_MouseEnter(object sender, MouseEventArgs e)
        {
            Image img = (Image)sender;
            string sbName = img.Name + "ZoomIn";

            Storyboard anim = FindName(sbName) as Storyboard;
            anim.Begin();
        }

        private void ImageMenu_MouseLeave(object sender, MouseEventArgs e)
        {
            Image img = (Image)sender;
            string sbName = img.Name + "ZoomOut";

            Storyboard anim = FindName(sbName) as Storyboard;
            anim.Begin();
        }

        private void Resize()
        {
            double currentWidth = Application.Current.Host.Content.ActualWidth;
            double currentHeight = Application.Current.Host.Content.ActualHeight;

            double uniformScaleAmount = Math.Min((currentWidth / _originalWidth), (currentHeight / _originalHeight));
            rootScaleTransform.ScaleX = uniformScaleAmount;
            rootScaleTransform.ScaleY = uniformScaleAmount;

            double scaledWidth = Math.Min(_originalWidth * uniformScaleAmount, currentWidth);
            rootTranslateTransform.X = (Math.Min(rootCanvas.ActualWidth, currentWidth) - scaledWidth) / 2d;
        }
    }
Silverlight 1.0

http://viralfeed.net/sample/fullscreen1/

JavaScriptによる実装。

var _originalWidth;
var _originalHeight;
var slPlugin;

function onLoaded(sender, args)
{   
    slPlugin = sender.getHost(); 
    var rootCanvas = slPlugin.content.FindName("rootCanvas");
    
    _originalWidth = rootCanvas.Width;
    _originalHeight = rootCanvas.Height;   

    slPlugin.content.onResize = onResized;     
    Resize();    
   
}

function toggle_fullScreen(sender, args)
{    
    slPlugin.content.fullScreen = !slPlugin.content.fullScreen;     
    Resize();        
}

function onResized(sender, eventArgs)
{
    Resize();
}

function Resize()
{
    var rootScaleTransform     = slPlugin.content.FindName("rootScaleTransform");
    var rootTranslateTransform = slPlugin.content.FindName("rootTranslateTransform");   
    var rootCanvas             = slPlugin.content.FindName("rootCanvas");
        
    var currentWidth  = slPlugin.content.actualWidth;
    var currentHeight = slPlugin.content.actualHeight;   
    
    var uniformScalceAmount   = Math.min((currentWidth/_originalWidth),(currentHeight/_originalHeight));
    rootScaleTransform.ScaleX = uniformScalceAmount;
    rootScaleTransform.ScaleY = uniformScalceAmount;
    
    var scaledWidth = Math.min(_originalWidth * uniformScalceAmount, currentWidth);
    rootTranslateTransform.X = (Math.Min(rootCanvas.ActualWidth, currentWidth) - scaledWidth) / 45;
}

function ImageMenu_MouseEnter(sender, args)
{
    var TargetId = sender.Name + "ZoomIn";
    var ImageMenuEnterAnimation = sender.findName(TargetId);
    ImageMenuEnterAnimation.begin(); 
}

function ImageMenu_MouseLeave(sender, args)
{
    var TargetId = sender.Name + "ZoomOut";
    var ImageMenuLeaveAnimation = sender.findName(TargetId);
    ImageMenuLeaveAnimation.begin(); 
}
注意事項

当然のことながら配置する際にはxamlとxapのMIME設定を忘れずに。
xap: application/x-silverlight-app
xaml: application/xaml+xml

今日の写真

会社同僚の方の結婚式二次会の様子。二次会の写真は近いうちにSousuke Hirayama | Flickrにupする予定 > to 関係者のみなさま。
http://www.orioria.jp/