2017-06-15 48 views
0

我有一個矩形:製作的UIElement僅可見聚光燈下

<Border x:Name="Elem1" BorderThickness="2" Height="100" Width="200" BorderBrush="Red" /> 

並有Windows.UI.Composition。 射燈與指針togehter移動:

const float LightDistance = 20; 
_compositor = Window.Current.Compositor; 
_pointLight = _compositor.CreatePointLight(); 
_pointLight.Color = Colors.White; 
_pointLight.Targets.Add(ElementCompositionPreview.GetElementVisual(Elem1)); 

PointerMoved += (o, e) => { 
    var point = e.GetCurrentPoint(this).Position; 
    _pointLight.Offset = new Vector3((float)point.X, (float)point.Y, LightDistance); 
}; 

當存在超過rectagle無光,它保持黑色:

enter image description here

我想的矩形的其餘部分是透明的,所以只有開明的部分將是可見的

我試圖添加透明AmblientLight,但APLHA通道是我gnored。

我想這可能由SceneLightingEffect來實現,但如何? :)

+0

你可以使用口罩,而不是聚光燈下,如果它適合你的情況 –

+0

我也試過這個,但沒有成功的。不是因爲它不可能我們,而是因爲,我的有限UWP的knowlegde我不知道如何創建徑向漸變面具和移動它 – Liero

回答

0

特別爲您提供:d

public MainPage() 
    { 
     InitializeComponent(); 
     Loaded += MainPage_Loaded; 
    } 

    private CompositionSurfaceBrush _maskSurfaceBrush; 
    private readonly float _size = 512; 

    private async void MainPage_Loaded(object sender, RoutedEventArgs e) 
    { 
     PointerMoved += MainPage_PointerMoved; 

     var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; 
     var canvasDevice = CanvasDevice.GetSharedDevice(); 
     var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(compositor, canvasDevice); 

     var canvasBitmap = await CanvasBitmap.LoadAsync(canvasDevice, new Uri("ms-appx:///Assets/44578.jpg")); 

     var sourceDrawingSurface = graphicsDevice.CreateDrawingSurface(new Size(_size, _size), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); 
     using (var ds = CanvasComposition.CreateDrawingSession(sourceDrawingSurface)) 
     { 
      ds.Clear(Colors.Transparent); 
      ds.DrawImage(canvasBitmap); 
     } 

     var sourceSurfaceBrush = compositor.CreateSurfaceBrush(sourceDrawingSurface); 

     var maskRenderTarget = new CanvasRenderTarget(canvasDevice, _size, _size, 96); 
     using (var ds = maskRenderTarget.CreateDrawingSession()) 
     { 
      ds.Clear(Colors.Transparent); 
      ds.FillCircle(_size/2, _size/2, _size/8, Colors.Black); 
     } 

     var blur = new GaussianBlurEffect 
     { 
      BlurAmount = 16, 
      Source = maskRenderTarget 
     }; 

     var blurredMaskDrawingSurface = graphicsDevice.CreateDrawingSurface(new Size(_size, _size), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); 
     using (var ds = CanvasComposition.CreateDrawingSession(blurredMaskDrawingSurface)) 
     { 
      ds.Clear(Colors.Transparent); 
      ds.DrawImage(blur); 
     } 

     _maskSurfaceBrush = compositor.CreateSurfaceBrush(blurredMaskDrawingSurface); 

     var composite = new CompositeEffect 
     { 
      Sources = { new CompositionEffectSourceParameter("source"), new CompositionEffectSourceParameter("mask") }, 
      Mode = CanvasComposite.DestinationAtop 
     }; 

     var effectFactory = compositor.CreateEffectFactory(composite); 
     var fxBrush = effectFactory.CreateBrush(); 
     fxBrush.SetSourceParameter("source", sourceSurfaceBrush); 
     fxBrush.SetSourceParameter("mask", _maskSurfaceBrush); 

     var sprite = compositor.CreateSpriteVisual(); 
     sprite.Size = new Vector2(_size, _size); 
     sprite.Brush = fxBrush; 

     ElementCompositionPreview.SetElementChildVisual(this, sprite); 
    } 

    private void MainPage_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
     var position = e.GetCurrentPoint(this).Position.ToVector2(); 

     _maskSurfaceBrush.Offset = position - new Vector2(_size/2, _size/2); 
    } 

作品比以前更好!