Skip to content

Commit 6fa5779

Browse files
Merge pull request #102 from Community-Toolkit-for-Fluent-UI-Blazor/enhance/fluentcx-slideshow-new-ratio
adds a new aspect ratio... Container will set all images to the size of the containing without maintening the aspect ratio
2 parents f2a4dd2 + ecbfe88 commit 6fa5779

5 files changed

Lines changed: 114 additions & 22 deletions

File tree

examples/demo/FluentUI.Demo.Shared/FluentUI.Blazor.Community.Components.xml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14347,6 +14347,11 @@
1434714347
Represents a value indicating if the show indicator has changed.
1434814348
</summary>
1434914349
</member>
14350+
<member name="F:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1._isSizeChanged">
14351+
<summary>
14352+
Represents a value indicating if the size has changed.
14353+
</summary>
14354+
</member>
1435014355
<member name="P:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1.ShowControls">
1435114356
<summary>
1435214357
Gets or sets a value indicating that the controls are shown.
@@ -14722,9 +14727,6 @@
1472214727
<member name="M:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1.OnAfterRenderAsync(System.Boolean)">
1472314728
<inheritdoc />
1472414729
</member>
14725-
<member name="M:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1.Dispose">
14726-
<inheritdoc />
14727-
</member>
1472814730
<member name="M:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1.DisposeAsync">
1472914731
<inheritdoc />
1473014732
</member>
@@ -14745,6 +14747,11 @@
1474514747
Occurs when all images have been resized.
1474614748
</summary>
1474714749
</member>
14750+
<member name="M:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1.OnContainerSizeCompletedAsync">
14751+
<summary>
14752+
Occurs when all images have been resized.
14753+
</summary>
14754+
</member>
1474814755
<member name="M:FluentUI.Blazor.Community.Components.FluentCxSlideshow`1.OnFillSizeCompletedAsync(System.Int32,System.Int32)">
1474914756
<summary>
1475014757
Occurs when all images have been resized to fill the container.
@@ -14934,6 +14941,11 @@
1493414941
after that, the first image in the slideshow, when stretched, gives the height of the container,
1493514942
and the other images will take that height.</remarks>
1493614943
</member>
14944+
<member name="F:FluentUI.Blazor.Community.Components.SlideshowImageRatio.Container">
14945+
<summary>
14946+
The image covers the entire container, without keeping the aspect ratio.
14947+
</summary>
14948+
</member>
1493714949
<member name="T:FluentUI.Blazor.Community.Components.SlideshowIndicatorPosition">
1493814950
<summary>
1493914951
Gets or sets the position of the indicator.

src/Community.Components/Components/Slideshow/FluentCxSlideshow.razor.cs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace FluentUI.Blazor.Community.Components;
1616
/// <typeparam name="TItem">Type of the item.</typeparam>
1717
[CascadingTypeParameter(nameof(TItem))]
1818
public partial class FluentCxSlideshow<TItem>
19-
: FluentComponentBase, IAsyncDisposable, IDisposable
19+
: FluentComponentBase, IAsyncDisposable
2020
{
2121
#region Fields
2222

@@ -146,6 +146,11 @@ public partial class FluentCxSlideshow<TItem>
146146
/// </summary>
147147
private bool _showIndicatorChanged;
148148

149+
/// <summary>
150+
/// Represents a value indicating if the size has changed.
151+
/// </summary>
152+
private bool _isSizeChanged;
153+
149154
#endregion Fields
150155

151156
#region Properties
@@ -545,7 +550,7 @@ private async Task OnMoveNextAsync()
545550
await SetInternalIndexAsync(Items.Count());
546551
}
547552
}
548-
553+
549554
StartTimer();
550555

551556
async Task SetInternalIndexAsync(int count)
@@ -775,7 +780,7 @@ private async Task OnLoopingModeChangedAsync(bool store = false)
775780
if (_slides.Count > 0 &&
776781
_module is not null)
777782
{
778-
await _module.InvokeVoidAsync(store ? "storeItems" : "restoreItems", Id, _slides.Select(x=> x.Id).ToArray());
783+
await _module.InvokeVoidAsync(store ? "storeItems" : "restoreItems", Id, _slides.Select(x => x.Id).ToArray());
779784
await _module.InvokeVoidAsync("clearTransition", Id);
780785
}
781786

@@ -817,6 +822,8 @@ public override Task SetParametersAsync(ParameterView parameters)
817822
_isTouchEnabledChanged = parameters.HasValueChanged(nameof(IsTouchEnabled), IsTouchEnabled);
818823
_isLoopingModeChanged = parameters.HasValueChanged(nameof(LoopMode), LoopMode);
819824
_showIndicatorChanged = parameters.HasValueChanged(nameof(ShowIndicators), ShowIndicators);
825+
_isSizeChanged = parameters.HasValueChanged(nameof(Width), Width) ||
826+
parameters.HasValueChanged(nameof(Height), Height);
820827

821828
return base.SetParametersAsync(parameters);
822829
}
@@ -897,6 +904,19 @@ protected override async Task OnParametersSetAsync()
897904
{
898905
await OnLoopingModeChangedAsync();
899906
}
907+
908+
if (_isSizeChanged)
909+
{
910+
await OnSetSizeAsync();
911+
}
912+
}
913+
914+
private async Task OnSetSizeAsync()
915+
{
916+
if (_module is not null)
917+
{
918+
await _module.InvokeVoidAsync("setSize", Id, Width.GetValueOrDefault(), Height.GetValueOrDefault());
919+
}
900920
}
901921

902922
/// <inheritdoc />
@@ -921,7 +941,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
921941
}
922942

923943
/// <inheritdoc />
924-
public void Dispose()
944+
public async ValueTask DisposeAsync()
925945
{
926946
if (_timer is not null)
927947
{
@@ -933,12 +953,6 @@ public void Dispose()
933953

934954
_dotnetReference?.Dispose();
935955

936-
GC.SuppressFinalize(this);
937-
}
938-
939-
/// <inheritdoc />
940-
public async ValueTask DisposeAsync()
941-
{
942956
if (DeviceInfoState.DeviceInfo is not null)
943957
{
944958
DeviceInfoState.DeviceInfo.OrientationChanged -= OnOrientationChanged;
@@ -996,6 +1010,18 @@ public async Task OnAutoSizeCompletedAsync()
9961010
}
9971011
}
9981012

1013+
/// <summary>
1014+
/// Occurs when all images have been resized.
1015+
/// </summary>
1016+
[JSInvokable("setContainerSizeCompleted")]
1017+
public async Task OnContainerSizeCompletedAsync()
1018+
{
1019+
if (OnImagesResizeCompleted.HasDelegate)
1020+
{
1021+
await OnImagesResizeCompleted.InvokeAsync();
1022+
}
1023+
}
1024+
9991025
/// <summary>
10001026
/// Occurs when all images have been resized to fill the container.
10011027
/// </summary>

src/Community.Components/Components/Slideshow/FluentCxSlideshow.razor.js

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const _instances = [];
22
const auto = 0;
33
const fill = 1;
4+
const container = 2;
45
const horizontal = 0;
56
const moveNext = 0;
67
const movePrevious = 1;
@@ -87,6 +88,25 @@ function setFillSizeImage(instance, img, imageIdCollection) {
8788
instance.dotnetReference.invokeMethodAsync('setFillSizeCompleted', w, h);
8889
}
8990

91+
function setContainerSizeImage(instance, img, imageIdCollection) {
92+
const w = instance.width;
93+
const h = instance.height;
94+
95+
img.width = w;
96+
img.height = h;
97+
98+
for (let i = 1; i < imageIdCollection.length; ++i) {
99+
const childImg = document.getElementById(imageIdCollection[i]);
100+
101+
if (childImg) {
102+
childImg.width = w;
103+
childImg.height = h;
104+
}
105+
}
106+
107+
instance.dotnetReference.invokeMethodAsync('setContainerSizeCompleted', w, h);
108+
}
109+
90110
function setFillSizeImages(instance, imageIdCollection) {
91111
const img = document.getElementById(imageIdCollection[0]);
92112

@@ -107,6 +127,26 @@ function setFillSizeImages(instance, imageIdCollection) {
107127
}
108128
}
109129

130+
function setContainerSizeImages(instance, imageIdCollection) {
131+
const img = document.getElementById(imageIdCollection[0]);
132+
133+
if (img) {
134+
// If the image wasn't loaded.
135+
if (img.naturalHeight === 0 || img.naturalWidth === 0) {
136+
// Force loading
137+
img.loading = 'eager';
138+
img.src = img.src;
139+
140+
img.onload = () => {
141+
setContainerSizeImage(instance, img, imageIdCollection);
142+
};
143+
}
144+
else {
145+
setContainerSizeImage(instance, img, imageIdCollection);
146+
}
147+
}
148+
}
149+
110150
function setSizeFromParent(instance, width, height) {
111151
if (instance) {
112152
const rect = instance.parent.getBoundingClientRect();
@@ -187,15 +227,15 @@ export function setImagesSize(containerId, imageRatio, imageIdCollection) {
187227
else if (imageRatio === fill) {
188228
setFillSizeImages(instance, imageIdCollection);
189229
}
230+
else if (imageRatio === container) {
231+
setContainerSizeImages(instance, imageIdCollection);
232+
}
190233
}
191234
}
192235

193236
function onTouchStart(instance, e) {
194237
instance.startX = e.touches[0].clientX;
195238
instance.startY = e.touches[0].clientY;
196-
197-
198-
console.log(`Touch start: (${instance.startX}, ${instance.startY})`);
199239
}
200240

201241
function onTouchEnd(instance, e, touchThreshold) {
@@ -224,14 +264,10 @@ function onTouchEnd(instance, e, touchThreshold) {
224264
}
225265
}
226266
}
227-
228-
console.log(`Touch end: (${endX}, ${endY}) - Delta: (${deltaX}, ${deltaY})`);
229267
}
230268

231269
function onTouchMove(e) {
232270
e.preventDefault();
233-
234-
console.log(`Touch move: (${e.touches[0].clientX}, ${e.touches[0].clientY})`);
235271
}
236272

237273
export function disableOrEnableTouch(containerId, isTouchEnabled, touchThreshold) {
@@ -364,3 +400,12 @@ export function clearTransition(id) {
364400
instance.itemsContainer.style.transform = '';
365401
}
366402
}
403+
404+
export function setSize(id, width, height) {
405+
const instance = getInstance(id);
406+
if (instance) {
407+
instance.width = width;
408+
instance.height = height;
409+
setImagesSize(instance.id, instance.imageRatio, instance.imageIdCollection);
410+
}
411+
}

src/Community.Components/Components/Slideshow/SlideshowImageRatio.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,10 @@ public enum SlideshowImageRatio
1717
/// <remarks>When the dimensions of the container are not set, the width of the container is set to 100%,
1818
/// after that, the first image in the slideshow, when stretched, gives the height of the container,
1919
/// and the other images will take that height.</remarks>
20-
Fill
20+
Fill,
21+
22+
/// <summary>
23+
/// The image covers the entire container, without keeping the aspect ratio.
24+
/// </summary>
25+
Container
2126
}

tests/FluentUI.Blazor.Community.Components.Tests/Components/Slideshow/SlideshowImageRatioTests.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ public void Enum_Should_Have_Auto_And_Fill_Members()
77
{
88
Assert.Equal(0, (int)SlideshowImageRatio.Auto);
99
Assert.Equal(1, (int)SlideshowImageRatio.Fill);
10+
Assert.Equal(2, (int)SlideshowImageRatio.Container);
1011
}
1112

1213
[Theory]
1314
[InlineData(SlideshowImageRatio.Auto, "Auto")]
1415
[InlineData(SlideshowImageRatio.Fill, "Fill")]
16+
[InlineData(SlideshowImageRatio.Container, "Container")]
1517
public void ToString_Should_Return_Correct_Name(SlideshowImageRatio ratio, string expected)
1618
{
1719
Assert.Equal(expected, ratio.ToString());
@@ -20,6 +22,7 @@ public void ToString_Should_Return_Correct_Name(SlideshowImageRatio ratio, strin
2022
[Theory]
2123
[InlineData("Auto", SlideshowImageRatio.Auto)]
2224
[InlineData("Fill", SlideshowImageRatio.Fill)]
25+
[InlineData("Container", SlideshowImageRatio.Container)]
2326
public void Parse_Should_Return_Correct_Enum(string value, SlideshowImageRatio expected)
2427
{
2528
var result = Enum.Parse<SlideshowImageRatio>(value);
@@ -32,6 +35,7 @@ public void GetValues_Should_Contain_All_Members()
3235
var values = System.Enum.GetValues<SlideshowImageRatio>();
3336
Assert.Contains(SlideshowImageRatio.Auto, values);
3437
Assert.Contains(SlideshowImageRatio.Fill, values);
35-
Assert.Equal(2, values.Length);
38+
Assert.Contains(SlideshowImageRatio.Container, values);
39+
Assert.Equal(3, values.Length);
3640
}
3741
}

0 commit comments

Comments
 (0)