HarmonyOS NEXT - 飞卡 + Swiper切换背景颜色渐变
·
主页面布局左右滑动切换,内部卡片可上滑切换运行效果:

Fly.ets 主界面+Swiper切换+背景颜色变化渐变
import { FlyEvent,FlyComponent } from './FlyComponent';
import { image } from '@kit.ImageKit';
import { resourceManager } from '@kit.LocalizationKit';
import { effectKit } from '@kit.ArkGraphics2D';
@Entry
@Component
export struct Fly {
@State swiperList: string[] = ['0','1','2','3'];
@State cardList: Resource[] = [$r('app.media.1'),$r('app.media.2'),$r('app.media.3'),$r('app.media.2'),$r('app.media.4'),$r('app.media.2'),$r('app.media.3'),$r('app.media.4')];
@State targetIndex: number = 0;
@State bgColor:string = "";
aboutToAppear(){
this.setBackgroundColor()
}
async setBackgroundColor(){
const context = getContext(this);
const media : Resource = this.cardList[this.targetIndex];
//获取resourceManager资源管理器
const resourceMgr: resourceManager.ResourceManager = context.resourceManager;
const fileData = await resourceMgr.getMediaContent(media);
//获取图片的ArrayBufferc
const buffer = fileData.buffer;
//创建imageSource
const imageSource: image.ImageSource = image.createImageSource(buffer);
//创建pixelMap
const pixelMap: image.PixelMap = await imageSource.createPixelMap();
effectKit.createColorPicker(pixelMap, (err, colorPicker) => {
//读取图像主色的颜色值,结果写入Color
let color = colorPicker.getMainColorSync();
this.bgColor = "#" + color.alpha.toString(16) + color.red.toString(16) + color.green.toString(16) + color.blue.toString(16);
console.log('bgColor='+this.bgColor)
})
}
build() {
Column(){
Column() {
Swiper() {
ForEach(this.swiperList, (index:number) => {
Column(){
FlyComponent({
cardData: this.cardList,
cardWidth:300,
cardHeight:400,
onThrowDone: () =>{
console.log('Fly=================完成')
const data: ResourceStr = this.cardList.splice(0,1)[0];
this.cardList.push(data);
},
onDragFlyMove:(e:FlyEvent) =>{
console.log('Fly',JSON.stringify(e))
}
})
Text(`Item ${index + 1}`)
.width('100%')
.height('100px')
.backgroundColor(index % 2 === 0 ? 0xFF6347 : 0xCCCCCC)
}
})
}
.onChange((index:number)=>{
this.targetIndex = index;
this.setBackgroundColor();
})
.displayCount('auto') // 设置显示数量为自动
.loop(true) // 设置循环滑动
.padding('10px') // 设置内边距
.margin('10px') // 设置外边距
.zIndex(1) // 设置z-index为1,确保在重叠时显示在最上层
}
}
.linearGradient({
direction: GradientDirection.Bottom, // 渐变方向
repeating: false, // 渐变颜色是否重复
colors: [[this.bgColor, 0.0], [0xffffff, 0.5]] // 数组末尾元素占比小于1时满足重复着色效果
})
}
}
FlyComponent.ets 飞卡组件
export interface FlyEvent{
left: number;
top: number;
distance: number;
}
//飞卡组件
@Entry
@Component
export struct FlyComponent {
@Prop cardData: Resource[] = [];
// 正常卡片宽度
@State cardWidth: number = 260;
// 正常卡片高度
@State cardHeight: number = 300;
// 卡片层叠的横向边距
@State leftPad: number = 10;
// 卡片层叠的纵向边距
@State topPad: number = 6;
// 卡片背景色
@State cardBgColor: string = "#fff";
// 卡片拖拽方向
@State dragDirection: String = "all";
// 卡片的圆角弧度
@State flyborderRadius: number = 10;
// 卡片触发飞卡效果的距离
@State throwTriggerDistance: number = 100;
// 飞卡的移动距离
@State throwDistance: number = 1000;
// 是否开启卡片描边效果
@State hasBorder: boolean = false;
// 是否开启阴影效果
@State hasShadow: boolean = true;
// 是否可用
@State disabled: boolean = false;
@State left: number = 0;
@State top: number = 0;
@State startLeft: number = 0;
@State startTop: number = 0;
@State isDrag: boolean = false;
@State isThrow: boolean = false;
@State needBack: boolean = false;
@State isAnimating: boolean = false;
@State left2: number = 0;
@State top2: number = 0;
@State width2: number = 0;
@State height2: number = 0;
@State left3: number = 0;
@State top3: number = 0;
@State width3: number = 0;
@State height3: number = 0;
@State left4: number = 0;
@State top4: number = 0;
@State width4: number = 0;
@State height4: number = 0;
@State opacity4: number = 0;
@State paddingLeft: number = 0;
@State paddingTop: number = 0;
public onThrowDone:Function | null = null;
public onDragFlyStart:Function | null = null;
public onDragFlyMove:Function | null = null;
public onDragStop:Function | null = null;
public onThrowFail:Function | null = null;
public onThrowStart:Function | null = null;
aboutToAppear(): void {
this.resetAllCard();
}
getDistance(x1: number, y1: number, x2: number, y2: number): number {
const _x: number = Math.abs(x1 - x2);
const _y: number = Math.abs(y1 - y2);
return Math.sqrt(_x * _x + _y * _y);
}
touchStart(e: TouchEvent) {
if (this.isAnimating) {
return;
}
this.isDrag = true;
this.needBack = false;
this.isThrow = false;
const curTouch: TouchObject = e.touches[0];
this.startLeft = curTouch.x - this.left;
this.startTop = curTouch.y - this.top;
if(this.onDragFlyStart){
this.onDragFlyStart();
}
}
touchMove(e: TouchEvent) {
if (this.disabled) {
return;
}
if (this.isAnimating) {
return;
}
const curTouch: TouchObject = e.touches[0];
if (this.dragDirection == "all" || this.dragDirection == "horizontal") {
this.left =
curTouch.x - this.startLeft;
}
if (this.dragDirection == "all" || this.dragDirection == "vertical") {
this.top = curTouch.y - this.startTop;
}
const distance: number = this.getDistance(0, 0, this.left, this.top);
if(this.onDragFlyMove){
this.onDragFlyMove({ left: this.left, top: this.top, distance: distance });
}
}
touchCancel(e: TouchEvent) {
let distance: number = this.getDistance(0, 0, this.left, this.top);
this.isDrag = false;
if(this.onDragStop){
this.onDragStop({ left: this.left, top: this.top, distance: distance });
}
if (this.isAnimating) {
return;
}
const that = this;
const curTouch = e.touches[0];
distance = this.getDistance(0, 0, this.left, this.top);
if (distance > this.throwTriggerDistance) {
this.makeCardThrow();
} else {
this.makeCardBack();
}
}
resetAllCardDown() {
this.left = 0;
this.top = 0;
this.width2 = (this.cardWidth - this.leftPad * 2);
this.height2 = (this.cardHeight - this.topPad * 2);
this.left2 = this.leftPad;
this.top2 = (this.topPad * 3);
this.width3 = (this.cardWidth - this.leftPad * 4);
this.height3 = (this.cardHeight - this.topPad * 4);
this.left3 = this.leftPad * 2;
this.top3 = (this.topPad * 6);
this.width4 = (this.cardWidth - this.leftPad * 6);
this.height4 = (this.cardHeight - this.topPad * 6);
this.left4 = this.leftPad * 3;
this.top4 = (this.topPad * 9);
this.opacity4 = 0;
}
resetAllCard() {
this.resetAllCardDown();
}
makeCardThrow() {
const that = this;
this.isThrow = true;
this.needBack = false;
const angle = Math.atan2((this.top - 0), (this.left - 0));
this.left = Math.cos(angle) * this.throwDistance;
this.top = Math.sin(angle) * this.throwDistance;
this.width2 = this.cardWidth;
this.height2 = this.cardHeight;
this.left2 = 0;
this.top2 = 0;
this.width3 = (this.cardWidth - this.leftPad * 2);
this.height3 = (this.cardHeight - this.topPad * 2);
this.left3 = this.leftPad;
this.top3 = (this.topPad * 3);
this.width4 = (this.cardWidth - this.leftPad * 4);
this.height4 = (this.cardHeight - this.topPad * 4);
this.left4 = this.leftPad * 2;
this.top4 = (this.topPad * 6);
this.opacity4 = 1;
this.isAnimating = true;
if(this.onThrowStart){
this.onThrowStart();
}
setTimeout( () => {
that.isThrow = false;
that.isAnimating = false;
if(that.onThrowDone){
that.onThrowDone();
}
that.resetAllCard();
}, 400);
}
makeCardBack() {
const that = this;
this.isThrow = false;
this.needBack = true;
if (this.needBack) {
this.left = 0;
this.top = 0;
}
this.isAnimating = true;
setTimeout( () => {
if( that.onThrowFail){
that.onThrowFail();
}
that.isAnimating = false;
that.needBack = true;
}, 600);
}
@Styles
setImageShadow():void{
.backgroundColor(this.cardBgColor)
.borderRadius(this.flyborderRadius)
.borderWidth(1)
.borderColor("#ccc")
.shadow({ radius: 0, color: "#000", offsetX: 0, offsetY: 0 })
}
build() {
Column() {
Stack() {
Column() {
Image(this.cardData.length > 4 ? this.cardData[3]:$r('app.media.4'))
.borderRadius(this.flyborderRadius)
}
.width(this.width4)
.height(this.height4)
.position({x:this.left4,y:this.top4})
.setImageShadow()
Column() {
Image(this.cardData.length > 3 ? this.cardData[2]:$r('app.media.3'))
.borderRadius(this.flyborderRadius)
}
.width(this.width3)
.height(this.height3)
.position({x:this.left3,y:this.top3})
.setImageShadow()
Column() {
Image(this.cardData.length > 2 ? this.cardData[1]:$r('app.media.2'))
.borderRadius(this.flyborderRadius)
}
.width(this.width2)
.height(this.height2)
.position({x:this.left2,y:this.top2})
.setImageShadow()
Column() {
Image(this.cardData.length > 1 ? this.cardData[0]:$r('app.media.1'))
.borderRadius(this.flyborderRadius)
}
.width(this.cardWidth)
.height(this.cardHeight)
.position({x:this.left,y:this.top})
.onTouch((event?: TouchEvent) => {
if (event) {
if (event.type === TouchType.Down) {
this.touchStart(event);
}
if (event.type === TouchType.Up) {
this.touchCancel(event);
}
if (event.type === TouchType.Move) {
this.touchMove(event);
}
}
})
.setImageShadow()
}
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.width('100%')
.height('100%')
.align(Alignment.Center)
}
}
更多推荐


所有评论(0)