!3107 【Sample】【基础能力】ArkUI控件动画动效能力增强

Merge pull request !3107 from JrongTru/dongxiao
This commit is contained in:
openharmony_ci 2023-08-04 03:44:21 +00:00 committed by Gitee
commit e0e703cfb9
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
17 changed files with 1195 additions and 2 deletions

View File

@ -179,6 +179,22 @@ const INFORMATION_PRESENTATION_AND_DYNAMIC_EFFECTS: ThirdLevelCategory =
{ {
title: $r('app.string.data_panel'), title: $r('app.string.data_panel'),
url: 'pages/components/informationPresentationAndDynamicEffects/dataPanelSample/DataPanelSample' url: 'pages/components/informationPresentationAndDynamicEffects/dataPanelSample/DataPanelSample'
},
{
title: $r('app.string.scroll_To_effect'),
url: "pages/components/informationPresentationAndDynamicEffects/scrollToSample/ScrollToSample"
},
{
title: $r('app.string.tabs_switch_effect'),
url: "pages/components/informationPresentationAndDynamicEffects/tapsSwitchSample/TapsSwitchSample"
},
{
title: $r('app.string.image_fit_Full_effect'),
url: "pages/components/informationPresentationAndDynamicEffects/imageFitFullSample/ImageFitFullSample"
},
{
title: $r('app.string.particle_effect'),
url: "pages/components/informationPresentationAndDynamicEffects/particleSample/ParticleSample"
} }
] ]
} }

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TitleBar } from '../../../../common/TitleBar';
@Extend(Radio) function fancyRadio(){
.height(25)
.width(25)
}
@Entry
@Component
struct ImageFitFullSample {
@State message: string = 'Hello World';
@State imageFit: ImageFit = ImageFit.None;
build() {
Column() {
TitleBar({ title: $r('app.string.image_fit_Full_effect') });
Image($r('app.media.flower'))
.width('100%')
.height('30%')
.objectFit(this.imageFit)
.margin({ top: '30%' })
.borderWidth(1)
.alignSelf(ItemAlign.Center);
Grid() {
GridItem() {
Column() {
Text('Contain')
Radio({ value: 'RadioContain', group: 'radioGroup' })
.fancyRadio()
.checked(false)
.onChange((isChecked: boolean) => {
this.imageFit = ImageFit.Contain;
});
};
};
GridItem() {
Column() {
Text('Cover')
Radio({ value: 'RadioCover', group: 'radioGroup' })
.fancyRadio()
.checked(false)
.onChange((isChecked: boolean) => {
this.imageFit = ImageFit.Cover;
});
};
};
GridItem() {
Column() {
Text('Auto')
Radio({ value: 'RadioAuto', group: 'radioGroup' })
.fancyRadio()
.checked(false)
.onChange((isChecked: boolean) => {
this.imageFit = ImageFit.Auto;
});
};
};
GridItem() {
Column() {
Text('Fill')
Radio({ value: 'RadioFill', group: 'radioGroup' })
.fancyRadio()
.checked(false)
.onChange((isChecked: boolean) => {
this.imageFit = ImageFit.Fill;
});
};
};
GridItem() {
Column() {
Text('ScaleDown')
Radio({ value: 'RadioScaleDown', group: 'radioGroup' })
.fancyRadio()
.checked(false)
.onChange((isChecked: boolean) => {
this.imageFit = ImageFit.ScaleDown;
});
};
};
GridItem() {
Column() {
Text('None')
Radio({ value: 'RadioNone', group: 'radioGroup' })
.fancyRadio()
.checked(true)
.onChange((isChecked: boolean) => {
this.imageFit = ImageFit.None;
});
};
};
}
.columnsTemplate('1fr 1fr 1fr')
.width('70%');
}
.padding({top:24, bottom: 12});
}
}

View File

@ -0,0 +1,294 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TitleBar } from '../../../../common/TitleBar';
let sampleParticleEngine = {};
@Entry
@Component
struct ParticleSample {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
private spawn: boolean = false;
private interval: number;
elevation(x, y, z) {
let distance = Math.sqrt(x * x + y * y + z * z);
if (distance && z / distance >= -1 && z / distance <= 1){
return Math.acos(z / distance);
}
return 0.00000001;
}
rgb(colorRGBData) {
colorRGBData += 0.000001;
// generate rgb value by random for particles
let r = Math.round((0.5 + Math.sin(colorRGBData) * 0.5) * 16);
let g = Math.round((0.5 + Math.cos(colorRGBData) * 0.5) * 16);
let b = Math.round((0.5 - Math.sin(colorRGBData) * 0.5) * 16);
return '#' + r.toString(16) + g.toString(16) + b.toString(16);
}
interpolateColors(RGB1, RGB2, degree) {
let w2 = degree;
let w1 = 1 - w2;
return [w1 * RGB1[0] + w2 * RGB2[0], w1 * RGB1[1] + w2 * RGB2[1], w1 * RGB1[2] + w2 * RGB2[2]];
}
rgbArray(colorRGBData) {
colorRGBData += 0.000001;
// generate rgb value by random for particles and returned as an array
let r = Math.round((0.5 + Math.sin(colorRGBData) * 0.5) * 256);
let g = Math.round((0.5 + Math.cos(colorRGBData) * 0.5) * 256);
let b = Math.round((0.5 - Math.sin(colorRGBData) * 0.5) * 256);
return [r, g, b];
}
colorString(colorArray) {
// generate rgb value by random with a generated rgb array for particles and returned as a string
let r = Math.round(colorArray[0]);
let g = Math.round(colorArray[1]);
let b = Math.round(colorArray[2]);
return '#' + ('0' + r.toString(16)).slice(-2) + ('0' + g.toString(16)).slice(-2) + ('0' + b.toString(16)).slice(-2);
}
particleEnginePerform(particleEngine) {
if (particleEngine.points.length < particleEngine.initParticles) {
for (let i = 0; i < 5; ++i) {
this.particleItemSpawn(particleEngine);
}
}
let p, d, t;
// generate particle move path for animation which is a spiral orbit
p = Math.atan2(particleEngine.camX, particleEngine.camZ);
d = Math.sqrt(particleEngine.camX * particleEngine.camX + particleEngine.camZ * particleEngine.camZ);
// move by each frame
d -= Math.sin(particleEngine.frameNo / 80) / 25;
t = Math.cos(particleEngine.frameNo / 300) / 165;
particleEngine.camX = Math.sin(p + t) * d;
particleEngine.camZ = Math.cos(p + t) * d;
particleEngine.camY = -Math.sin(particleEngine.frameNo / 220) * 15;
particleEngine.yaw = Math.PI + p + t;
particleEngine.pitch = this.elevation(particleEngine.camX, particleEngine.camZ, particleEngine.camY) - Math.PI / 2;
let x, y, z;
for (let i = 0; i < particleEngine.points.length; ++i) {
x = particleEngine.points[i].x;
y = particleEngine.points[i].y;
z = particleEngine.points[i].z;
// distance between particles, 1.0075 is the justify number
d = Math.sqrt(x * x + z * z) / 1.0075;
t = 0.1 / (1 + d * d / 5);
p = Math.atan2(x, z) + t;
particleEngine.points[i].x = Math.sin(p) * d;
particleEngine.points[i].z = Math.cos(p) * d;
particleEngine.points[i].y += particleEngine.points[i].vy * t * ((Math.sqrt(particleEngine.distributionRadius) - d) * 2);
if (particleEngine.points[i].y > particleEngine.vortexHeight / 2 || d < 0.25) {
particleEngine.points.splice(i, 1);
this.particleItemSpawn(particleEngine);
}
}
}
TrackSpawn(x, y, z, particleEngine) {
let p, d;
x -= particleEngine.camX;
y -= particleEngine.camY - 8;
z -= particleEngine.camZ;
p = Math.atan2(x, z);
d = Math.sqrt(x * x + z * z);
x = Math.sin(p - particleEngine.yaw) * d;
z = Math.cos(p - particleEngine.yaw) * d;
p = Math.atan2(y, z);
d = Math.sqrt(y * y + z * z);
y = Math.sin(p - particleEngine.pitch) * d;
z = Math.cos(p - particleEngine.pitch) * d;
let rx1 = -1000;
let ry1 = 1;
let rx2 = 1000;
let ry2 = 1;
let rx3 = 0;
let ry3 = 0;
let rx4 = x;
let ry4 = z;
let uc = (ry4 - ry3) * (rx2 - rx1) - (rx4 - rx3) * (ry2 - ry1);
let ua = ((rx4 - rx3) * (ry1 - ry3) - (ry4 - ry3) * (rx1 - rx3)) / uc;
let ub = ((rx2 - rx1) * (ry1 - ry3) - (ry2 - ry1) * (rx1 - rx3)) / uc;
if (!z) {
z = 0.000000001;
}
if (ua > 0 && ua < 1 && ub > 0 && ub < 1) {
return {
x: particleEngine.cx + (rx1 + ua * (rx2 - rx1)) * particleEngine.scale,
y: particleEngine.cy + y / z * particleEngine.scale,
d: (x * x + y * y + z * z)
};
} else {
return { d: -1 };
}
}
sortMethod(a, b) {
return b.distance - a.distance;
}
particleSpawn(particleEngine) {
particleEngine.ctx.globalAlpha = 0.15;
particleEngine.ctx.fillStyle = '#000';
particleEngine.ctx.globalCompositeOperation = 'source-over';
particleEngine.ctx.fillRect(0, 0, particleEngine.width, particleEngine.height);
let point, x, y, z, a, size, d;
for (let i = 0; i < particleEngine.points.length; ++i) {
x = particleEngine.points[i].x;
y = particleEngine.points[i].y;
z = particleEngine.points[i].z;
point = this.TrackSpawn(x, y, z, particleEngine);
if (point.d !== -1) {
particleEngine.points[i].distance = point.d;
size = 1 + particleEngine.points[i].radius / (1 + point.d);
d = Math.abs(particleEngine.points[i].y);
a = 0.8 - Math.pow(d / (particleEngine.vortexHeight / 2), 1000) * 0.8;
particleEngine.ctx.globalAlpha = a >= 0 && a <= 1 ? a : 0;
particleEngine.ctx.fillStyle = this.rgb(particleEngine.points[i].color);
if (point.x > -1 && point.x < particleEngine.width && point.y > -1 && point.y < particleEngine.height) {
particleEngine.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
}
}
}
particleEngine.points.sort(this.sortMethod);
}
particleItemSpawn(particleEngine) {
let p;
let ls;
let pt = {
x: 0.0,
y: 0.0,
vy: 0.0,
z: 0.0,
radius: 0.0,
color: 0.0,
};
// vortex points x, y, z(analog) values generation
p = Math.PI * 2 * Math.random();
ls = Math.sqrt(Math.random() * particleEngine.distributionRadius);
pt.x = Math.sin(p) * ls;
pt.y = -particleEngine.vortexHeight / 2;
pt.vy = particleEngine.initV / 20 + Math.random() * particleEngine.initV;
pt.z = Math.cos(p) * ls;
pt.radius = 200 + 800 * Math.random();
pt.color = pt.radius / 1000 + particleEngine.frameNo / 250;
particleEngine.points.push(pt);
}
init(particleEngine) {
particleEngine.ctx = this.context;
particleEngine.width = this.context.width;
particleEngine.height = this.context.height;
particleEngine.frameNo = 0;
// canvas x
particleEngine.camX = 0;
// canvas y
particleEngine.camY = 0;
// canvas analog z
particleEngine.camZ = -14;
// particle curve rate of its orbits
particleEngine.pitch = this.elevation(particleEngine.camX, particleEngine.camZ, particleEngine.camY) - Math.PI / 2;
particleEngine.yaw = 0;
// central axis of canvas width
particleEngine.cx = particleEngine.width / 2;
// central axis of canvas height
particleEngine.cy = particleEngine.height / 2;
// particle orbits generation scale
particleEngine.scale = 500;
particleEngine.points = [];
// max particles to be generated
particleEngine.initParticles = 80;
// y shifting rate for each frame
particleEngine.initV = 0.01;
// max particles generation radius
particleEngine.distributionRadius = 800;
// vortex generated height
particleEngine.vortexHeight = 25;
}
particleFrameGenerate(particleEngine) {
particleEngine.frameNo++;
this.particleEnginePerform(particleEngine);
this.particleSpawn(particleEngine);
}
animationOn() {
this.interval = setInterval(() => {
this.particleFrameGenerate(sampleParticleEngine);
}, 20);
}
build(){
Column() {
TitleBar({ title: $r('app.string.particle_effect') });
Column() {
Canvas(this.context)
.width('90%')
.height('90%')
.borderRadius(24)
.backgroundColor(Color.Black);
}
.padding(12)
.margin({ left: 12, right: 12, top: 24, bottom: 24 })
.borderRadius(24)
.width('90%')
.backgroundColor(Color.Black)
.height('70%');
Grid() {
GridItem() {
Button($r('app.string.particle_spawn'))
.onClick(() => {
if (this.spawn !== true) {
this.init(sampleParticleEngine);
this.animationOn();
this.spawn = true;
}
})
.width('100%');
}
GridItem() {
Button($r('app.string.particle_spawn_stop'))
.onClick(() => {
this.spawn = false;
clearInterval(this.interval);
})
.width('100%');
}
}
.columnsTemplate('1fr 1fr')
.columnsGap(12)
.padding({ left: 24, right: 24, bottom: 24 })
.width('100%');
}
.backgroundColor($r('app.color.background_shallow_grey'));
}
aboutToDisappear() {
clearInterval(this.interval);
}
}

View File

@ -0,0 +1,270 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TitleBar } from '../../../../common/TitleBar';
@Extend(Text) function fancyText() {
.width('90%')
.height(80)
.backgroundColor($r('app.color.scroll_item_color'))
.borderRadius(15)
.fontSize(16)
.textAlign(TextAlign.Center)
.margin({ top: 10 })
}
@Extend(Text) function leftTitleStyle() {
.fontColor($r('app.color.sub_title_color'))
.fontWeight(FontWeight.Medium)
.fontSize(20)
.height(22)
.letterSpacing('40%')
.alignSelf(ItemAlign.Start)
.margin({ left: 24, top: 12 })
}
@Extend(Text) function gridText() {
.fontSize(16)
.backgroundColor($r('app.color.scroll_grid_item_color'))
.height(80)
.textAlign(TextAlign.Center)
}
@Extend(Column) function itemColumn() {
.height('40%')
.backgroundColor($r('app.color.white'))
.alignItems(HorizontalAlign.Start)
}
@Extend(Button) function sampleButton() {
.height(40)
.margin(12)
.fontColor(Color.White)
.fontSize(15)
}
@Entry
@Component
struct ScrollToSample {
private scroller: Scroller = new Scroller();
private mScroller: Scroller = new Scroller();
private listScroller: Scroller = new Scroller();
private gridScroller: Scroller = new Scroller();
private waterFlowScroller: Scroller = new Scroller();
private scrollArr: Array<number> = new Array();
aboutToAppear() {
for (let i = 0; i < 24; i++) {
this.scrollArr.push(i)
}
}
@Builder itemFoot() {
Column() {
Text(`Footer`)
.fontSize(10)
.backgroundColor(Color.Red)
.width(50)
.height(50)
.align(Alignment.Center)
.margin({ top: 6 })
}
}
build() {
Column() {
TitleBar({ title: $r('app.string.scroll_To_effect') });
Scroll(this.scroller) {
Column({ space: 10 }) {
Column() {
Text($r('app.string.scroller'))
.leftTitleStyle();
Button($r('app.string.scroll_To_effect'))
.sampleButton()
.alignSelf(ItemAlign.Center)
.onClick(() => {
if (this.mScroller.currentOffset().yOffset === 0) {
this.mScroller.scrollTo({ xOffset: 0, yOffset: this.mScroller.currentOffset().yOffset + 300,
animation: { duration: 800, curve: Curve.Linear }
},);
} else {
this.mScroller.scrollTo({ xOffset: 0, yOffset: 0,
animation: { duration: 800, curve: Curve.Linear }
},);
}
}).id('scroll_to_effect_scroller');
Scroll(this.mScroller) {
Column() {
ForEach(this.scrollArr, (item) => {
Text(item.toString())
.fancyText();
}, item => item);
}
.padding({ top: 6, bottom: 12 })
.width('100%')
.alignSelf(ItemAlign.Center)
.backgroundColor(Color.White);
}
.alignSelf(ItemAlign.Center)
.height('70%')
.width('92%')
.borderRadius(24)
.backgroundColor(Color.White);
}
.itemColumn()
.width('100%')
.backgroundColor($r('app.color.background_shallow_grey'));
Column() {
Text($r('app.string.list'))
.leftTitleStyle();
Button($r('app.string.scroll_To_effect'))
.sampleButton()
.alignSelf(ItemAlign.Center)
.onClick(() => {
if (this.listScroller.currentOffset().yOffset === 0) {
this.listScroller.scrollTo({ xOffset: 0, yOffset: this.listScroller.currentOffset().yOffset + 300,
animation: { duration: 800, curve: Curve.Linear }
},);
} else {
this.listScroller.scrollTo({ xOffset: 0, yOffset: 0,
animation: { duration: 800, curve: Curve.Linear }
},);
}
}).id('scroll_to_effect_list');
List({ scroller: this.listScroller }) {
ForEach(this.scrollArr, (item) => {
ListItem() {
Text(item.toString())
.fancyText();
}
.width('100%')
.alignSelf(ItemAlign.Center)
.backgroundColor(Color.White);
}, item => item);
}
.alignSelf(ItemAlign.Center)
.height('70%')
.width('92%')
.borderRadius(24)
.backgroundColor(Color.White);
}
.itemColumn()
.width('100%')
.backgroundColor($r('app.color.background_shallow_grey'));
Column() {
Text($r('app.string.grid'))
.leftTitleStyle();
Button($r('app.string.scroll_To_effect'))
.sampleButton()
.alignSelf(ItemAlign.Center)
.onClick(() => {
if (this.gridScroller.currentOffset().yOffset <= 0) {
this.gridScroller.scrollTo({ xOffset: 0, yOffset: this.gridScroller.currentOffset().yOffset + 500,
animation: { duration: 2000, curve: Curve.Linear }
},);
} else {
this.gridScroller.scrollTo({ xOffset: 0, yOffset: 0,
animation: { duration: 2000, curve: Curve.Linear }
},);
}
}).id('scroll_to_effect_grid');
Grid(this.gridScroller) {
ForEach(this.scrollArr, (day: string) => {
GridItem() {
Text('world')
.width('100%')
.gridText();
};
}, day => day);
}
.alignSelf(ItemAlign.Center)
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(12)
.rowsGap(12)
.height('70%')
.width('92%')
.borderRadius(24)
.padding({ left: 12, right: 12, top: 12, bottom: 12 })
.backgroundColor(Color.White);
}
.itemColumn()
.width('100%')
.backgroundColor($r('app.color.background_shallow_grey'));
Column() {
Text($r('app.string.waterFlow'))
.leftTitleStyle();
Button($r('app.string.scroll_To_effect'))
.sampleButton()
.alignSelf(ItemAlign.Center)
.onClick(() => {
if (this.waterFlowScroller.currentOffset().yOffset <= 0) {
this.waterFlowScroller.scrollTo({
xOffset: 0,
yOffset: this.waterFlowScroller.currentOffset().yOffset + 500,
animation: { duration: 2000, curve: Curve.Linear }
},);
} else {
this.waterFlowScroller.scrollTo({
xOffset: 0,
yOffset: 0,
animation: { duration: 2000, curve: Curve.Linear }
},);
}
}).id('scroll_to_effect_waterflow');
WaterFlow({ footer: this.itemFoot.bind(this), scroller: this.waterFlowScroller }) {
ForEach(this.scrollArr, (day: string) => {
FlowItem() {
Text('hello')
.width('30%')
.gridText();
};
}, day => day);
}
.alignSelf(ItemAlign.Center)
.columnsTemplate('1fr 1fr 1fr')
.layoutDirection(FlexDirection.Column)
.columnsGap(12)
.rowsGap(12)
.height('70%')
.width('92%')
.borderRadius(24)
.padding({ left: 12, right: 12, top: 12, bottom: 12})
.backgroundColor(Color.White);
}
.itemColumn()
.width('100%')
.backgroundColor($r('app.color.background_shallow_grey'));
}
.backgroundColor($r('app.color.background_shallow_grey'))
.width('100%');
}
.padding({left: 10, right: 10, bottom: 24})
.height('90%')
.backgroundColor($r('app.color.background_shallow_grey'))
.scrollable(ScrollDirection.Vertical);
}
.width('100%')
.padding({bottom: 12})
.backgroundColor($r('app.color.background_shallow_grey'));
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TitleBar } from '../../../../common/TitleBar';
@Entry
@Component
struct TapsSwitchSample {
@State fontColor: string = '#182431'
@State selectedFontColor: string = '#007DFF'
@State currentIndex: number = 0
private controller: TabsController = new TabsController()
@Builder TabBuilder(index: number, name: string) {
Column() {
Text(name)
.fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
.fontSize(16)
.fontWeight(this.currentIndex === index ? 500 : 400)
.lineHeight(22)
.margin({ top: 17, bottom: 7 });
Divider()
.strokeWidth(2)
.color('#007DFF')
.opacity(this.currentIndex === index ? 1 : 0);
}.width('100%');
}
build() {
Column() {
TitleBar({ title: $r('app.string.tabs_switch_effect') });
Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#00CB87')
}.tabBar(this.TabBuilder(0, 'green'));
TabContent() {
Column().width('100%').height('100%').backgroundColor('#007DFF')
}.tabBar(this.TabBuilder(1, 'blue'));
TabContent() {
Column().width('100%').height('100%').backgroundColor('#FFBF00')
}.tabBar(this.TabBuilder(2, 'yellow'));
TabContent() {
Column().width('100%').height('100%').backgroundColor('#E67C92')
}.tabBar(this.TabBuilder(3, 'pink'));
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(500)
.onChange((index: number) => {
this.currentIndex = index
})
.width('100%')
.backgroundColor('#F1F3F5');
}
.padding({bottom: 12})
.width('100%');
}
}

View File

@ -212,6 +212,18 @@
{ {
"name": "canvas_bg_color", "name": "canvas_bg_color",
"value": "#00ffff" "value": "#00ffff"
},
{
"name": "scroll_to_button_color",
"value": "#ff55c6f5"
},
{
"name": "scroll_item_color",
"value": "#ff2a78db"
},
{
"name": "scroll_grid_item_color",
"value": "#F9CF93"
} }
] ]
} }

View File

@ -3412,6 +3412,47 @@
{ {
"name": "canvas_imageSmoothingQuality", "name": "canvas_imageSmoothingQuality",
"value": "imageSmoothingQuality" "value": "imageSmoothingQuality"
},
// scrollTo
{
"name": "scroll_To_effect",
"value": "ScrollTo effect"
},
{
"name": "scroller",
"value": "Scroller"
},
{
"name": "list",
"value": "List"
},
{
"name": "grid",
"value": "Grid"
},
{
"name": "waterFlow",
"value": "WaterFlow"
},
{
"name": "tabs_switch_effect",
"value": "Tabs switch effect"
},
{
"name": "image_fit_Full_effect",
"value": "Image fit/full effect"
},
{
"name": "particle_effect",
"value": "Particle Effect"
},
{
"name": "particle_spawn",
"value": "Spawn"
},
{
"name": "particle_spawn_stop",
"value": "Stop"
} }
] ]
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -77,6 +77,10 @@
"pages/components/informationPresentationAndDynamicEffects/progressSample/ProgressSample", "pages/components/informationPresentationAndDynamicEffects/progressSample/ProgressSample",
"pages/components/informationPresentationAndDynamicEffects/gaugeSample/GaugeSample", "pages/components/informationPresentationAndDynamicEffects/gaugeSample/GaugeSample",
"pages/components/informationPresentationAndDynamicEffects/dataPanelSample/DataPanelSample", "pages/components/informationPresentationAndDynamicEffects/dataPanelSample/DataPanelSample",
"pages/components/informationPresentationAndDynamicEffects/scrollToSample/ScrollToSample",
"pages/components/informationPresentationAndDynamicEffects/tapsSwitchSample/TapsSwitchSample",
"pages/components/informationPresentationAndDynamicEffects/imageFitFullSample/ImageFitFullSample",
"pages/components/informationPresentationAndDynamicEffects/particleSample/ParticleSample",
"pages/components/buttonAndSelection/ratingSample/RatingSample", "pages/components/buttonAndSelection/ratingSample/RatingSample",
"pages/components/buttonAndSelection/counterSample/CounterSample", "pages/components/buttonAndSelection/counterSample/CounterSample",
"pages/components/buttonAndSelection/timePickerSample/TimePickerSample", "pages/components/buttonAndSelection/timePickerSample/TimePickerSample",
@ -100,4 +104,4 @@
"pages/universal/gesture/swipeSample/SwipeSample", "pages/universal/gesture/swipeSample/SwipeSample",
"pages/universal/gesture/combinedSample/CombinedSample" "pages/universal/gesture/combinedSample/CombinedSample"
] ]
} }

View File

@ -2482,6 +2482,47 @@
{ {
"name": "canvas_show_message", "name": "canvas_show_message",
"value": "Printed to the console" "value": "Printed to the console"
},
// scrollTo
{
"name": "scroll_To_effect",
"value": "ScrollTo effect"
},
{
"name": "scroller",
"value": "Scroller"
},
{
"name": "list",
"value": "List"
},
{
"name": "grid",
"value": "Grid"
},
{
"name": "waterFlow",
"value": "WaterFlow"
},
{
"name": "tabs_switch_effect",
"value": "Tabs switch effect"
},
{
"name": "image_fit_Full_effect",
"value": "Image fit/full effect"
},
{
"name": "particle_effect",
"value": "Particle Effect"
},
{
"name": "particle_spawn",
"value": "Spawn"
},
{
"name": "particle_spawn_stop",
"value": "Stop"
} }
] ]
} }

View File

@ -2659,6 +2659,47 @@
{ {
"name": "canvas_show_message", "name": "canvas_show_message",
"value": "已经打印到控制台" "value": "已经打印到控制台"
},
// scrollTo
{
"name": "scroll_To_effect",
"value": "ScrollTo 动效"
},
{
"name": "scroller",
"value": "Scroller"
},
{
"name": "list",
"value": "List"
},
{
"name": "grid",
"value": "Grid"
},
{
"name": "waterFlow",
"value": "WaterFlow"
},
{
"name": "tabs_switch_effect",
"value": "Tabs 模糊切换"
},
{
"name": "image_fit_Full_effect",
"value": "Image fit/full 动效"
},
{
"name": "particle_effect",
"value": "Particle 粒子效果"
},
{
"name": "particle_spawn",
"value": "生成"
},
{
"name": "particle_spawn_stop",
"value": "停止"
} }
] ]
} }

View File

@ -1013,6 +1013,164 @@ export default function abilityTest() {
Logger.info(BUNDLE + testName + ' end'); Logger.info(BUNDLE + testName + ' end');
}) })
/**
* ScrollTo 动效
*/
it(BUNDLE + 'ScrollTo_effect_001', 0, async function () {
let testName = 'ScrollToEffect';
Logger.info(BUNDLE + testName + ' begin');
let driver: Driver = Driver.create();
await driver.delayMs(DELAY_TIME);
// 进入Scroll To 动效
let atom = await manager.getStringValue($r('app.string.scroll_To_effect'))
let button = await driver.findComponent(ON.text(atom));
if (!button) {
// 如果没展开 就展开
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.information_presentation_and_dynamic_effects')));
}
await driver.swipe(100, 1000, 100, 400, 5000);
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithText(atom);
await driver.delayMs(DELAY_TIME);
// 点击按钮
await checkButtonAndClickWithID('scroll_to_effect_scroller');
await checkButtonAndClickWithID('scroll_to_effect_list');
await driver.swipe(100, 1000, 100, 400, 5000);
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithID('scroll_to_effect_grid');
await checkButtonAndClickWithID('scroll_to_effect_waterflow');
let backBtn = await driver.findComponent(ON.id('backBtn'));
if(!backBtn)
{
Logger.error('No backbtn found in ' + testName);
}
// 返回
await backBtn.click();
await driver.delayMs(500);
Logger.info(BUNDLE + testName + ' end');
})
/**
* Tab 模糊切换
*/
it(BUNDLE + 'Tab_switch_effect_001', 0, async function () {
let testName = 'TabToEffect';
Logger.info(BUNDLE + testName + ' begin');
let driver: Driver = Driver.create();
await driver.delayMs(DELAY_TIME);
// 进入Scroll To 动效
let atom = await manager.getStringValue($r('app.string.tabs_switch_effect'))
let button = await driver.findComponent(ON.text(atom));
if (!button) {
// 如果没展开 就展开
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.information_presentation_and_dynamic_effects')));
}
await driver.swipe(100, 1000, 100, 400, 5000);
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithText(atom);
// 点击按钮
await checkButtonAndClickWithText('green');
await checkButtonAndClickWithText('blue');
await checkButtonAndClickWithText('yellow');
await checkButtonAndClickWithText('pink');
let backBtn = await driver.findComponent(ON.id('backBtn'));
if (!backBtn)
{
Logger.error('Cannot find backbtn in this page');
}
// 返回
await backBtn.click();
await driver.delayMs(500);
Logger.info(BUNDLE + testName + ' end');
})
/**
* ImageFit 切换
*/
it(BUNDLE + 'ImageFit_effect_001', 0, async function () {
let testName = 'ImageFitEffect';
Logger.info(BUNDLE + testName + ' begin');
let driver: Driver = Driver.create();
await driver.delayMs(DELAY_TIME);
// 进入Scroll To 动效
let atom = await manager.getStringValue($r('app.string.image_fit_Full_effect'))
let button = await driver.findComponent(ON.text(atom));
if (!button) {
// 如果没展开 就展开
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.information_presentation_and_dynamic_effects')));
}
await driver.swipe(100, 1000, 100, 400, 5000);
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithText(atom);
// 点击按钮
await checkButtonAndClickWithText('RadioContain');
await checkButtonAndClickWithText('RadioCover');
await checkButtonAndClickWithText('RadioAuto');
await checkButtonAndClickWithText('RadioFill');
await checkButtonAndClickWithText('RadioScaleDown');
await checkButtonAndClickWithText('RadioNone');
let backBtn = await driver.findComponent(ON.id('backBtn'));
// 返回
await backBtn.click();
await driver.delayMs(500);
Logger.info(BUNDLE + testName + ' end');
})
/**
* Particle 粒子效果
*/
it(BUNDLE + 'Particle_effect_001', 0, async function () {
let testName = 'Particle Effect';
Logger.info(BUNDLE + testName + ' begin');
// 进入Scroll To 动效
let atom = await manager.getStringValue($r('app.string.particle_effect'))
let button = await driver.findComponent(ON.text(atom));
if (!button) {
// 如果没展开 就展开
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.information_presentation_and_dynamic_effects')));
}
await driver.swipe(100, 1000, 100, 400, 5000);
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithText(atom);
await driver.delayMs(DELAY_TIME);
// 点击按钮
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.particle_spawn')));
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.particle_spawn_stop')));
let backBtn = await driver.findComponent(ON.id('backBtn'));
// 返回
await backBtn.click();
await driver.delayMs(500);
await driver.swipe(100, 400, 100, 1000, 5000);
await driver.delayMs(DELAY_TIME);
await checkButtonAndClickWithText(await manager.getStringValue($r('app.string.information_presentation_and_dynamic_effects')));
Logger.info(BUNDLE + testName + ' end');
})
/** /**
* ImageSpan 行内图像 * ImageSpan 行内图像
*/ */
@ -3003,4 +3161,4 @@ export default function abilityTest() {
Logger.info("Sample_ComponentCollection test end"); Logger.info("Sample_ComponentCollection test end");
}) })
}) })
} }

View File

@ -3356,6 +3356,47 @@
{ {
"name": "canvas_imageSmoothingQuality", "name": "canvas_imageSmoothingQuality",
"value": "imageSmoothingQuality" "value": "imageSmoothingQuality"
},
// scrollTo
{
"name": "scroll_To_effect",
"value": "ScrollTo effect"
},
{
"name": "scroller",
"value": "Scroller"
},
{
"name": "list",
"value": "List"
},
{
"name": "grid",
"value": "Grid"
},
{
"name": "waterFlow",
"value": "WaterFlow"
},
{
"name": "tabs_switch_effect",
"value": "Tabs switch effect"
},
{
"name": "image_fit_Full_effect",
"value": "Image fit/full effect"
},
{
"name": "particle_effect",
"value": "Particle Effect"
},
{
"name": "particle_spawn",
"value": "Spawn"
},
{
"name": "particle_spawn_stop",
"value": "Stop"
} }
] ]
} }

View File

@ -2146,6 +2146,46 @@
{ {
"name": "canvas_show_message", "name": "canvas_show_message",
"value": "Printed to the console" "value": "Printed to the console"
},
{
"name": "scroll_To_effect",
"value": "ScrollTo effect"
},
{
"name": "scroller",
"value": "Scroller"
},
{
"name": "list",
"value": "List"
},
{
"name": "grid",
"value": "Grid"
},
{
"name": "waterFlow",
"value": "WaterFlow"
},
{
"name": "tabs_switch_effect",
"value": "Tabs switch effect"
},
{
"name": "image_fit_Full_effect",
"value": "Image fit/full effect"
},
{
"name": "particle_effect",
"value": "Particle Effect"
},
{
"name": "particle_spawn",
"value": "Spawn"
},
{
"name": "particle_spawn_stop",
"value": "Stop"
} }
] ]
} }

View File

@ -1826,6 +1826,47 @@
{ {
"name": "canvas_show_message", "name": "canvas_show_message",
"value": "已经打印到控制台" "value": "已经打印到控制台"
},
// scrollTo
{
"name": "scroll_To_effect",
"value": "ScrollTo 动效"
},
{
"name": "scroller",
"value": "Scroller"
},
{
"name": "list",
"value": "List"
},
{
"name": "grid",
"value": "Grid"
},
{
"name": "waterFlow",
"value": "WaterFlow"
},
{
"name": "tabs_switch_effect",
"value": "Tabs 模糊切换"
},
{
"name": "image_fit_Full_effect",
"value": "Image fit/full 动效"
},
{
"name": "particle_effect",
"value": "Particle 粒子效果"
},
{
"name": "particle_spawn",
"value": "生成"
},
{
"name": "particle_spawn_stop",
"value": "停止"
} }
] ]
} }

View File

@ -24,6 +24,10 @@
| 验证Progress 进度条 | 展开信息展示与动效进入Progress 进度条 | 调整进度条的进度 | 正确显示进度条的进度 | 是 | Pass | | 验证Progress 进度条 | 展开信息展示与动效进入Progress 进度条 | 调整进度条的进度 | 正确显示进度条的进度 | 是 | Pass |
| 验证Gauge 仪表盘 | 展开信息展示与动效进入Gauge 仪表盘 | 调整仪表盘的value和strokeWidth | 正确改变仪表盘的属性 | 是 | Pass | | 验证Gauge 仪表盘 | 展开信息展示与动效进入Gauge 仪表盘 | 调整仪表盘的value和strokeWidth | 正确改变仪表盘的属性 | 是 | Pass |
| 验证DataPanel 数据面板 | 展开信息展示与动效进入DataPanel 数据面板 | | 正确显示数据面板动画 | 是 | Pass | | 验证DataPanel 数据面板 | 展开信息展示与动效进入DataPanel 数据面板 | | 正确显示数据面板动画 | 是 | Pass |
| 验证ScrollTo 动效 | 展开信息展示与动效进入ScrollTo 动效 | 点击ScrollTo动效按钮 | ScrollTo动效展示 | 是 | Pass |
| 验证Tab 模糊切换 | 展开信息展示与动效进入Tab 模糊切换 | 点击Tab 进行模糊切换 | Tab 模糊切换成功 | 是 | Pass |
| 验证ImageFit 切换 | 展开信息展示与动效进入ImageFit 切换 | 依次点击Radius按钮进行ImageFit模式切换 | ImageFit 模式切换成功 | 是 | Pass |
| 验证Particle粒子效果 | 展开信息展示与动效进入Particle粒子效果 | 点击Particle粒子效果生成按钮 | Particle粒子效果生成成功 | 是 | Pass |
| 验证Span 行内文本 | 展开文本与输入进入Span 行内文本 | 依次调整字符间距,装饰线类型,颜色 | 依次改变对于属性 | 是 | Pass | | 验证Span 行内文本 | 展开文本与输入进入Span 行内文本 | 依次调整字符间距,装饰线类型,颜色 | 依次改变对于属性 | 是 | Pass |
| 验证TextInput 文本输入 | 展开文本与输入进入TextInput 文本输入 | 在输入框输入文本 | 正确显示输入文本 | 是 | Pass | | 验证TextInput 文本输入 | 展开文本与输入进入TextInput 文本输入 | 在输入框输入文本 | 正确显示输入文本 | 是 | Pass |
| 验证Text 文本 | 展开文本与输入进入Text 文本 | 依次更改字符间距,行高,对其类型,超长文本显示方式,装饰线,字体颜色,大小写 | 依次更改对应属性 | 是 | Pass | | 验证Text 文本 | 展开文本与输入进入Text 文本 | 依次更改字符间距,行高,对其类型,超长文本显示方式,装饰线,字体颜色,大小写 | 依次更改对应属性 | 是 | Pass |