waapi
This commit is contained in:
parent
cd7a18b63f
commit
314b03a9ab
469
src/data/index.ts
Normal file
469
src/data/index.ts
Normal file
@ -0,0 +1,469 @@
|
|||||||
|
// 店铺信息接口
|
||||||
|
export interface Store {
|
||||||
|
城市: string;
|
||||||
|
店铺号: string;
|
||||||
|
店铺: string;
|
||||||
|
备注: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 区域类型
|
||||||
|
export type RegionType =
|
||||||
|
| "奥莱北区"
|
||||||
|
| "奥莱东区"
|
||||||
|
| "博物馆"
|
||||||
|
| "大北区"
|
||||||
|
| "大东区"
|
||||||
|
| "大南区"
|
||||||
|
| "大西区"
|
||||||
|
| "免税";
|
||||||
|
|
||||||
|
// 区域数据接口
|
||||||
|
export interface RegionData {
|
||||||
|
奥莱北区: Store[];
|
||||||
|
奥莱东区: Store[];
|
||||||
|
博物馆: Store[];
|
||||||
|
大北区: Store[];
|
||||||
|
大东区: Store[];
|
||||||
|
大南区: Store[];
|
||||||
|
大西区: Store[];
|
||||||
|
免税: Store[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const regions: RegionData = {
|
||||||
|
"奥莱北区": [
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "B36",
|
||||||
|
"店铺": "北京斯普瑞斯",
|
||||||
|
"备注": "B36-北京斯普瑞斯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T032",
|
||||||
|
"店铺": "北京燕莎奥特莱斯",
|
||||||
|
"备注": "T032-北京燕莎奥特莱斯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T055",
|
||||||
|
"店铺": "北京赛特奥莱",
|
||||||
|
"备注": "T055-北京赛特奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T056",
|
||||||
|
"店铺": "北京八达岭奥莱",
|
||||||
|
"备注": "T056-北京八达岭奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "成都",
|
||||||
|
"店铺号": "T043",
|
||||||
|
"店铺": "成都时代奥莱",
|
||||||
|
"备注": "T043-成都时代奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "成都",
|
||||||
|
"店铺号": "T075",
|
||||||
|
"店铺": "成都佛罗伦萨二期",
|
||||||
|
"备注": "T075-成都佛罗伦萨二期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "A41",
|
||||||
|
"店铺": "亚玛芬上海员工店",
|
||||||
|
"备注": "A41-亚玛芬上海员工店"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "沈阳",
|
||||||
|
"店铺号": "T047",
|
||||||
|
"店铺": "沈阳赛特奥特莱斯",
|
||||||
|
"备注": "T047-沈阳赛特奥特莱斯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "天津",
|
||||||
|
"店铺号": "T033",
|
||||||
|
"店铺": "天津佛罗伦萨",
|
||||||
|
"备注": "T033-天津佛罗伦萨"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "长春",
|
||||||
|
"店铺号": "T046",
|
||||||
|
"店铺": "长春净月赛特奥莱",
|
||||||
|
"备注": "T046-长春净月赛特奥莱"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"奥莱东区": [
|
||||||
|
{
|
||||||
|
"城市": "杭州",
|
||||||
|
"店铺号": "T053",
|
||||||
|
"店铺": "杭州下沙",
|
||||||
|
"备注": "T053-杭州下沙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "南京",
|
||||||
|
"店铺号": "T051",
|
||||||
|
"店铺": "南京汤山百联奥莱",
|
||||||
|
"备注": "T051-南京汤山百联奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "宁波",
|
||||||
|
"店铺号": "T059",
|
||||||
|
"店铺": "宁波杉井奥特莱斯",
|
||||||
|
"备注": "T059-宁波杉井奥特莱斯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "A26",
|
||||||
|
"店铺": "上海奕欧莱奥特莱斯",
|
||||||
|
"备注": "A26-上海奕欧莱奥特莱斯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "A36",
|
||||||
|
"店铺": "上海青浦奥莱",
|
||||||
|
"备注": "A36-青浦奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T074",
|
||||||
|
"店铺": "上海佛罗伦萨小镇",
|
||||||
|
"备注": "T074-上海佛罗伦萨小镇"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "苏州",
|
||||||
|
"店铺号": "T035",
|
||||||
|
"店铺": "苏州奕欧来",
|
||||||
|
"备注": "T035-苏州奕欧来"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "无锡",
|
||||||
|
"店铺号": "T050",
|
||||||
|
"店铺": "无锡百联奥莱",
|
||||||
|
"备注": "T050-无锡百联奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "武汉",
|
||||||
|
"店铺号": "T052",
|
||||||
|
"店铺": "武汉百联奥莱",
|
||||||
|
"备注": "T052-武汉百联奥莱"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "郑州",
|
||||||
|
"店铺号": "T045",
|
||||||
|
"店铺": "郑州杉杉奥莱",
|
||||||
|
"备注": "T045-郑州杉杉奥莱"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"博物馆": [
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T083",
|
||||||
|
"店铺": "始祖鸟博物馆",
|
||||||
|
"备注": "T083-始祖鸟博物馆"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"大北区": [
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "B19",
|
||||||
|
"店铺": "北京王府中环",
|
||||||
|
"备注": "B19-北京王府中环"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "B25",
|
||||||
|
"店铺": "北京颐堤港购物中心",
|
||||||
|
"备注": "B25-北京颐堤港购物中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "B26",
|
||||||
|
"店铺": "北京金融街购物中心",
|
||||||
|
"备注": "B26-北京金融街购物中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "B27",
|
||||||
|
"店铺": "北京SKP",
|
||||||
|
"备注": "B27-北京SKP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T028",
|
||||||
|
"店铺": "北京金源燕莎",
|
||||||
|
"备注": "T028-北京金源燕莎"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T029",
|
||||||
|
"店铺": "北京国贸",
|
||||||
|
"备注": "T029-北京国贸"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T072",
|
||||||
|
"店铺": "北京宜家荟聚",
|
||||||
|
"备注": "T072-北京宜家荟聚"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T082",
|
||||||
|
"店铺": "北京三里屯",
|
||||||
|
"备注": "T082-北京三里屯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "北京",
|
||||||
|
"店铺号": "T102",
|
||||||
|
"店铺": "北京王府半岛",
|
||||||
|
"备注": "T102-北京王府半岛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "大连",
|
||||||
|
"店铺号": "T069",
|
||||||
|
"店铺": "大连恒隆广场",
|
||||||
|
"备注": "T069-大连恒隆广场"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "沈阳",
|
||||||
|
"店铺号": "T106",
|
||||||
|
"店铺": "沈阳万象城",
|
||||||
|
"备注": "T106-沈阳万象城"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "天津",
|
||||||
|
"店铺号": "T031",
|
||||||
|
"店铺": "天津海信广场",
|
||||||
|
"备注": "T031-天津海信广场"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "天津",
|
||||||
|
"店铺号": "T057",
|
||||||
|
"店铺": "天津万象城",
|
||||||
|
"备注": "T057-天津万象城"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"大东区": [
|
||||||
|
{
|
||||||
|
"城市": "杭州",
|
||||||
|
"店铺号": "A44",
|
||||||
|
"店铺": "杭州万象城",
|
||||||
|
"备注": "A44-杭州万象城"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "杭州",
|
||||||
|
"店铺号": "B05",
|
||||||
|
"店铺": "杭州大厦",
|
||||||
|
"备注": "B05-杭州大厦"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "杭州",
|
||||||
|
"店铺号": "T030",
|
||||||
|
"店铺": "杭州湖滨银泰",
|
||||||
|
"备注": "T030-杭州湖滨银泰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "合肥",
|
||||||
|
"店铺号": "T081",
|
||||||
|
"店铺": "合肥银泰",
|
||||||
|
"备注": "T081-合肥银泰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "济南",
|
||||||
|
"店铺号": "T092",
|
||||||
|
"店铺": "济南恒隆",
|
||||||
|
"备注": "T092-济南恒隆"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "南京",
|
||||||
|
"店铺号": "T085",
|
||||||
|
"店铺": "南京IFC",
|
||||||
|
"备注": "T085-南京IFC"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "南京",
|
||||||
|
"店铺号": "T096",
|
||||||
|
"店铺": "南京德基",
|
||||||
|
"备注": "T096-南京德基"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "A06",
|
||||||
|
"店铺": "上海港汇",
|
||||||
|
"备注": "A06-上海港汇"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "A24",
|
||||||
|
"店铺": "上海静安嘉里",
|
||||||
|
"备注": "A24-上海静安嘉里"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "A25",
|
||||||
|
"店铺": "上海浦东嘉里中心",
|
||||||
|
"备注": "A25-上海浦东嘉里中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T063",
|
||||||
|
"店铺": "上海始祖鸟明珠店",
|
||||||
|
"备注": "T063-上海始祖鸟明珠店"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T065",
|
||||||
|
"店铺": "上海恒隆广场",
|
||||||
|
"备注": "T065-上海恒隆广场"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T086",
|
||||||
|
"店铺": "上海IAPM",
|
||||||
|
"备注": "T086-上海IAPM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T097",
|
||||||
|
"店铺": "上海虹桥机场",
|
||||||
|
"备注": "T097-虹桥机场"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "上海",
|
||||||
|
"店铺号": "T999",
|
||||||
|
"店铺": "上海始祖鸟阿尔法中心",
|
||||||
|
"备注": "T999-上海始祖鸟阿尔法中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "苏州",
|
||||||
|
"店铺号": "T066",
|
||||||
|
"店铺": "苏州中心",
|
||||||
|
"备注": "T066-苏州中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "武汉",
|
||||||
|
"店铺号": "T038",
|
||||||
|
"店铺": "武汉武商广场",
|
||||||
|
"备注": "T038-武汉武商广场"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "武汉",
|
||||||
|
"店铺号": "T071",
|
||||||
|
"店铺": "武汉恒隆广场",
|
||||||
|
"备注": "T071-武汉恒隆广场"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "武汉",
|
||||||
|
"店铺号": "T080",
|
||||||
|
"店铺": "武汉梦时代",
|
||||||
|
"备注": "T080-武汉梦时代"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "武汉",
|
||||||
|
"店铺号": "T093",
|
||||||
|
"店铺": "武汉SKP",
|
||||||
|
"备注": "T093-武汉SKP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "长沙",
|
||||||
|
"店铺号": "T095",
|
||||||
|
"店铺": "长沙IFS",
|
||||||
|
"备注": "T095-长沙IFS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "郑州",
|
||||||
|
"店铺号": "T098",
|
||||||
|
"店铺": "郑州正弘城",
|
||||||
|
"备注": "T098-郑州正弘城"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"大南区": [
|
||||||
|
{
|
||||||
|
"城市": "成都",
|
||||||
|
"店铺号": "T084",
|
||||||
|
"店铺": "成都in99",
|
||||||
|
"备注": "T084-成都in99"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "广州",
|
||||||
|
"店铺号": "B21",
|
||||||
|
"店铺": "广州天环",
|
||||||
|
"备注": "B21-广州天环"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "广州",
|
||||||
|
"店铺号": "T061",
|
||||||
|
"店铺": "广州太古汇",
|
||||||
|
"备注": "T061-广州太古汇"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "南宁",
|
||||||
|
"店铺号": "T094",
|
||||||
|
"店铺": "南宁万象城",
|
||||||
|
"备注": "T094-南宁万象城"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "深圳",
|
||||||
|
"店铺号": "B23",
|
||||||
|
"店铺": "深圳湾万象城",
|
||||||
|
"备注": "B23-深圳湾万象城"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "深圳",
|
||||||
|
"店铺号": "B31",
|
||||||
|
"店铺": "深圳罗湖万象城",
|
||||||
|
"备注": "B31-深圳罗湖万象城"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "深圳",
|
||||||
|
"店铺号": "T067",
|
||||||
|
"店铺": "深圳万象天地",
|
||||||
|
"备注": "T067-深圳万象天地"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "深圳",
|
||||||
|
"店铺号": "T079",
|
||||||
|
"店铺": "深圳宝安机场",
|
||||||
|
"备注": "T079-深圳宝安机场"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"大西区": [
|
||||||
|
{
|
||||||
|
"城市": "太原",
|
||||||
|
"店铺号": "T087",
|
||||||
|
"店铺": "太原万象城",
|
||||||
|
"备注": "T087-太原万象城"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "太原",
|
||||||
|
"店铺号": "T099",
|
||||||
|
"店铺": "太原天美",
|
||||||
|
"备注": "T099-太原天美"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "西安",
|
||||||
|
"店铺号": "T109",
|
||||||
|
"店铺": "西安赛格国际5楼",
|
||||||
|
"备注": "T109-西安赛格国际5楼"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "西安",
|
||||||
|
"店铺号": "T110",
|
||||||
|
"店铺": "西安赛格国际1楼",
|
||||||
|
"备注": "T110-西安赛格国际1楼"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"免税": [
|
||||||
|
{
|
||||||
|
"城市": "海口",
|
||||||
|
"店铺号": "DFT0002",
|
||||||
|
"店铺": "海口新海港",
|
||||||
|
"备注": "DFT0002-海口新海港"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"城市": "三亚",
|
||||||
|
"店铺号": "DFT0001",
|
||||||
|
"店铺": "三亚海棠湾免税店",
|
||||||
|
"备注": "DFT0001-三亚海棠湾免税店"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -2,7 +2,9 @@
|
|||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
import assets from '../assets';
|
import assets from '../assets';
|
||||||
|
|
||||||
const regions = [
|
import { regions } from '../data';
|
||||||
|
|
||||||
|
const regionsPos = [
|
||||||
{ w: 68.8, h: 68.8, l: -1, t: -4, src: assets.p1.大北区, tt: '大北区', trt: -13, ad: 6 },
|
{ w: 68.8, h: 68.8, l: -1, t: -4, src: assets.p1.大北区, tt: '大北区', trt: -13, ad: 6 },
|
||||||
{ w: 73.3, h: 73.3, l: 44, t: 20, src: assets.p1.大东区, tt: '大东区', ad: 3 },
|
{ w: 73.3, h: 73.3, l: 44, t: 20, src: assets.p1.大东区, tt: '大东区', ad: 3 },
|
||||||
{ w: 62.3, h: 63.7, l: -32, t: 72, src: assets.p1['大南区&免税'], tt: '大南区&免税', trt: 5, ad: 3 },
|
{ w: 62.3, h: 63.7, l: -32, t: 72, src: assets.p1['大南区&免税'], tt: '大南区&免税', trt: 5, ad: 3 },
|
||||||
@ -10,41 +12,194 @@ const regions = [
|
|||||||
{ w: 52.1, h: 52, l: 3, t: 40, src: assets.p1.奥莱, tt: '奥莱', ad: 2 },
|
{ w: 52.1, h: 52, l: 3, t: 40, src: assets.p1.奥莱, tt: '奥莱', ad: 2 },
|
||||||
{ w: 62.7, h: 62.7, l: 33, t: 74, src: assets.p1.博物馆, tt: '博物馆', tc: '#fff', ad: 0 },
|
{ w: 62.7, h: 62.7, l: 33, t: 74, src: assets.p1.博物馆, tt: '博物馆', tc: '#fff', ad: 0 },
|
||||||
]
|
]
|
||||||
onMounted(() => {
|
|
||||||
const regionBubbles = document.querySelectorAll('.region-bubble');
|
|
||||||
regionBubbles.forEach((bubble, index) => {
|
|
||||||
const pDown = () => {
|
|
||||||
bubble.animate([
|
|
||||||
{ transform: 'translate3d(-50%, -50%, 0) scale(1)', filter: 'brightness(1)' },
|
|
||||||
{ transform: 'translate3d(-50%,-50%, 0) scale(0.92)', filter: 'brightness(0.9)' },
|
|
||||||
], {
|
|
||||||
duration: 500,
|
|
||||||
easing: 'ease-in-out',
|
|
||||||
fill: 'forwards'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const pUp = () => {
|
|
||||||
bubble.querySelector('span')?.animate([
|
|
||||||
{ opacity: 1 },
|
|
||||||
{ opacity: 0 },
|
|
||||||
], {
|
|
||||||
duration: 1000,
|
|
||||||
easing: 'ease-in-out',
|
|
||||||
fill: 'forwards'
|
|
||||||
});
|
|
||||||
bubble.animate([
|
|
||||||
{ transform: 'translate3d(-50%, -50%, 0) scale(0.92)', filter: 'brightness(0.9)' },
|
|
||||||
{ transform: 'translate3d(-50%, -50%, 0) scale(4)', filter: 'brightness(1)', top: '53%', left: '50%' },
|
|
||||||
], {
|
|
||||||
duration: 1000,
|
|
||||||
easing: 'ease-in-out',
|
|
||||||
fill: 'forwards'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 其他元素淡出
|
// 动画管理
|
||||||
regionBubbles.forEach((otherBubble, otherIndex) => {
|
let fadeInAnimations: Animation[] = [];
|
||||||
if (otherIndex == index) return
|
let swapInAnimations: Animation[] = [];
|
||||||
otherBubble.animate([
|
let scaleInAnimations: Animation[] = [];
|
||||||
|
let bubbleDropAnimations: Animation[] = [];
|
||||||
|
|
||||||
|
// 保存所有动画的数组
|
||||||
|
let allAnimations: Animation[] = [];
|
||||||
|
|
||||||
|
// 淡入动画
|
||||||
|
function createFadeInAnimation(element: Element, delay: number = 0) {
|
||||||
|
const animation = element.animate([
|
||||||
|
{ opacity: 0 },
|
||||||
|
{ opacity: 1 }
|
||||||
|
], {
|
||||||
|
duration: 500,
|
||||||
|
easing: 'ease-in-out',
|
||||||
|
delay: delay * 1000,
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
fadeInAnimations.push(animation);
|
||||||
|
allAnimations.push(animation);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap in 动画(渐进显示)
|
||||||
|
function createSwapInAnimation(element: Element, delay: number = 0) {
|
||||||
|
const animation = element.animate([
|
||||||
|
{ clipPath: 'inset(0 100% 0 0)' },
|
||||||
|
{ clipPath: 'inset(0 0% 0 0)' }
|
||||||
|
], {
|
||||||
|
duration: 500,
|
||||||
|
easing: 'ease-in-out',
|
||||||
|
delay: delay * 1000,
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
swapInAnimations.push(animation);
|
||||||
|
allAnimations.push(animation);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale in 动画(容器)
|
||||||
|
function createScaleInContainerAnimation(element: Element, delay: number = 0) {
|
||||||
|
const animation = element.animate([
|
||||||
|
{ transform: 'scale(0)' },
|
||||||
|
{ transform: 'scale(1)' }
|
||||||
|
], {
|
||||||
|
duration: 500,
|
||||||
|
easing: 'cubic-bezier(0.5, 0, 0.71, 1.85)',
|
||||||
|
delay: (delay + 0.2) * 1000,
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
scaleInAnimations.push(animation);
|
||||||
|
allAnimations.push(animation);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale in 动画(文本)
|
||||||
|
function createScaleInTextAnimation(element: Element, delay: number = 0) {
|
||||||
|
const animation = element.animate([
|
||||||
|
{ transform: 'scale(0)' },
|
||||||
|
{ transform: 'scale(1)' }
|
||||||
|
], {
|
||||||
|
duration: 500,
|
||||||
|
easing: 'cubic-bezier(0.5, 0, 0.71, 1.5)',
|
||||||
|
delay: (delay + 0.2 + 0.1) * 1000,
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
scaleInAnimations.push(animation);
|
||||||
|
allAnimations.push(animation);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 气泡下降动画
|
||||||
|
function createBubbleDropAnimation(element: Element, startTop: string, startLeft: string, endTop: string, endLeft: string, delay: number = 0, duration: number = 600) {
|
||||||
|
const animation = element.animate([
|
||||||
|
{
|
||||||
|
top: startTop,
|
||||||
|
left: startLeft,
|
||||||
|
transform: 'translate3d(-50%, -50%, 0) scale(0.1)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
top: endTop,
|
||||||
|
left: endLeft,
|
||||||
|
transform: 'translate3d(-50%, -50%, 0) scale(1)'
|
||||||
|
}
|
||||||
|
], {
|
||||||
|
duration: duration,
|
||||||
|
easing: 'ease-out',
|
||||||
|
delay: (delay + 1) * 1000,
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
bubbleDropAnimations.push(animation);
|
||||||
|
allAnimations.push(animation);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 反向播放所有动画来淡出
|
||||||
|
function reverseAllAnimations() {
|
||||||
|
allAnimations.forEach(animation => {
|
||||||
|
// 确保动画已经完成
|
||||||
|
if (animation.playState === 'finished') {
|
||||||
|
animation.reverse();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 淡出所有动画(备用方案)
|
||||||
|
function fadeOutAllAnimations() {
|
||||||
|
const allElements = document.querySelectorAll('.fade-in, .swap-in, .scale-in-ctn, .scale-in-txt, .region-bubble');
|
||||||
|
allElements.forEach((element) => {
|
||||||
|
element.animate([
|
||||||
|
{ opacity: 1 },
|
||||||
|
{ opacity: 0 }
|
||||||
|
], {
|
||||||
|
duration: 1000,
|
||||||
|
easing: 'ease-in-out',
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露函数供外部使用
|
||||||
|
(window as any).reverseAllAnimations = reverseAllAnimations;
|
||||||
|
(window as any).fadeOutAllAnimations = fadeOutAllAnimations;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 等待一帧确保所有元素都已渲染
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
// 初始化logo淡入动画
|
||||||
|
const logo = document.querySelector('.logo');
|
||||||
|
if (logo) {
|
||||||
|
createFadeInAnimation(logo, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化swap-in动画
|
||||||
|
const swapInElements = document.querySelectorAll('.swap-in');
|
||||||
|
swapInElements.forEach((element) => {
|
||||||
|
const htmlElement = element as HTMLElement;
|
||||||
|
const delay = parseFloat(htmlElement.style.getPropertyValue('--base-delay')?.replace('s', '') || '0');
|
||||||
|
createSwapInAnimation(element, delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化scale-in动画
|
||||||
|
const scaleInContainers = document.querySelectorAll('.scale-in-ctn');
|
||||||
|
scaleInContainers.forEach((element) => {
|
||||||
|
const htmlElement = element as HTMLElement;
|
||||||
|
const delay = parseFloat(htmlElement.style.getPropertyValue('--base-delay')?.replace('s', '') || '0');
|
||||||
|
createScaleInContainerAnimation(element, delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
const scaleInTexts = document.querySelectorAll('.scale-in-txt');
|
||||||
|
scaleInTexts.forEach((element) => {
|
||||||
|
const htmlElement = element as HTMLElement;
|
||||||
|
const delay = parseFloat(htmlElement.style.getPropertyValue('--base-delay')?.replace('s', '') || '0');
|
||||||
|
createScaleInTextAnimation(element, delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化气泡动画
|
||||||
|
const regionBubbles = document.querySelectorAll('.region-bubble');
|
||||||
|
regionBubbles.forEach((bubble, index) => {
|
||||||
|
const region = regionsPos[index];
|
||||||
|
const startTop = `${region.t + 50 - 200 - (100 - region.t)}%`;
|
||||||
|
const startLeft = `${region.l / 2 + 50}%`;
|
||||||
|
const endTop = `${region.t + 50}%`;
|
||||||
|
const endLeft = `${region.l + 50}%`;
|
||||||
|
|
||||||
|
// 设置初始位置
|
||||||
|
(bubble as HTMLElement).style.top = startTop;
|
||||||
|
(bubble as HTMLElement).style.left = startLeft;
|
||||||
|
|
||||||
|
createBubbleDropAnimation(bubble, startTop, startLeft, endTop, endLeft, 0, 600 + region.ad * 100);
|
||||||
|
|
||||||
|
// 点击事件
|
||||||
|
const pDown = () => {
|
||||||
|
bubble.animate([
|
||||||
|
{ transform: 'translate3d(-50%, -50%, 0) scale(1)', filter: 'brightness(1)' },
|
||||||
|
{ transform: 'translate3d(-50%,-50%, 0) scale(0.92)', filter: 'brightness(0.9)' },
|
||||||
|
], {
|
||||||
|
duration: 500,
|
||||||
|
easing: 'ease-in-out',
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const pUp = () => {
|
||||||
|
bubble.querySelector('span')?.animate([
|
||||||
{ opacity: 1 },
|
{ opacity: 1 },
|
||||||
{ opacity: 0 },
|
{ opacity: 0 },
|
||||||
], {
|
], {
|
||||||
@ -52,13 +207,38 @@ onMounted(() => {
|
|||||||
easing: 'ease-in-out',
|
easing: 'ease-in-out',
|
||||||
fill: 'forwards'
|
fill: 'forwards'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bubble.animate([
|
||||||
|
{ transform: 'translate3d(-50%, -50%, 0) scale(0.92)', filter: 'brightness(0.9)' },
|
||||||
|
{ transform: 'translate3d(-50%, -50%, 0) scale(4)', filter: 'brightness(1)', top: '53%', left: '50%' },
|
||||||
|
], {
|
||||||
|
duration: 1000,
|
||||||
|
easing: 'ease-in-out',
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
|
||||||
});
|
// 反向播放所有动画来淡出其他元素
|
||||||
|
reverseAllAnimations();
|
||||||
|
|
||||||
bubble.removeEventListener('pointerdown', pDown);
|
// 淡出其他气泡
|
||||||
}
|
regionBubbles.forEach((otherBubble, otherIndex) => {
|
||||||
bubble.addEventListener('pointerdown', pDown);
|
if (otherIndex == index) return
|
||||||
bubble.addEventListener('pointerup', pUp, { once: true });
|
otherBubble.animate([
|
||||||
|
{ opacity: 1 },
|
||||||
|
{ opacity: 0 },
|
||||||
|
], {
|
||||||
|
duration: 1000,
|
||||||
|
easing: 'ease-in-out',
|
||||||
|
fill: 'forwards'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
bubble.removeEventListener('pointerdown', pDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
bubble.addEventListener('pointerdown', pDown);
|
||||||
|
bubble.addEventListener('pointerup', pUp, { once: true });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -66,18 +246,18 @@ onMounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="p1">
|
<section class="p1">
|
||||||
<img :src="assets.标准logo" alt="" style="top: 6%;left: 8%;width: 12%;--base-delay: 2s;" class="fade-in">
|
<img :src="assets.标准logo" alt="" class="logo" style="top: 6%;left: 8%;width: 12%;opacity: 0;">
|
||||||
<img :src="assets.p1.蓝天" alt="" class="bg">
|
<img :src="assets.p1.蓝天" alt="" class="bg">
|
||||||
<div style="height: 12vw;top: 11.4%;left: 6%">
|
<div style="height: 12vw;top: 11.4%;left: 6%">
|
||||||
<span class="green scale-in-ctn" style="border-radius: 6vw;font-size: 9vw; padding: 0 3vw;height: 100%;">
|
<span class="green scale-in-ctn" style="border-radius: 6vw;font-size: 9vw; padding: 0 3vw;height: 100%;transform: scale(0);--base-delay: 0s;">
|
||||||
<span class="scale-in-txt">太阳脸</span>
|
<span class="scale-in-txt" style="transform: scale(0);">太阳脸</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="green fake scale-in-txt" style="border-radius: 6vw;font-size: 9vw; padding: 0 3vw;height: 100%;">
|
<span class="green fake scale-in-txt" style="border-radius: 6vw;font-size: 9vw; padding: 0 3vw;height: 100%;transform: scale(0);--base-delay: 0s;">
|
||||||
<span class="scale-in-txt">太阳脸</span>
|
<span class="scale-in-txt" style="transform: scale(0);">太阳脸</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="green scale-in-ctn"
|
<span class="green scale-in-ctn"
|
||||||
style="width: 12vw;border-radius: 5vw; padding: 2vw 2vw 2vw 3vw; left: 34vw;height: 100%;">
|
style="width: 12vw;border-radius: 5vw; padding: 2vw 2vw 2vw 3vw; left: 34vw;height: 100%;transform: scale(0);--base-delay: 0s;">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
viewBox="0 0 91.18 90.18" preserveAspectRatio="xMidYMid meet">
|
viewBox="0 0 91.18 90.18" preserveAspectRatio="xMidYMid meet">
|
||||||
<path fill-rule="evenodd" stroke="rgb(255, 255, 255)" stroke-width="12.12px" stroke-linecap="round"
|
<path fill-rule="evenodd" stroke="rgb(255, 255, 255)" stroke-width="12.12px" stroke-linecap="round"
|
||||||
@ -87,7 +267,7 @@ onMounted(() => {
|
|||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span class="green fake scale-in-txt"
|
<span class="green fake scale-in-txt"
|
||||||
style="width: 12vw;border-radius: 5vw; padding: 2vw 2vw 2vw 3vw; left: 34vw;height: 100%;">
|
style="width: 12vw;border-radius: 5vw; padding: 2vw 2vw 2vw 3vw; left: 34vw;height: 100%;transform: scale(0);--base-delay: 0s;">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
viewBox="0 0 91.18 90.18" preserveAspectRatio="xMidYMid meet">
|
viewBox="0 0 91.18 90.18" preserveAspectRatio="xMidYMid meet">
|
||||||
<path fill-rule="evenodd" stroke="rgb(255, 255, 255)" stroke-width="12.12px" stroke-linecap="round"
|
<path fill-rule="evenodd" stroke="rgb(255, 255, 255)" stroke-width="12.12px" stroke-linecap="round"
|
||||||
@ -99,39 +279,36 @@ onMounted(() => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div style="left: 12%;top: 17.2%;width: 73vw;height: 7%;">
|
<div style="left: 12%;top: 17.2%;width: 73vw;height: 7%;">
|
||||||
<span class="black scale-in-ctn" style="border-radius: 7vw;height: 100%;width: 100%;--base-delay:0.1s">
|
<span class="black scale-in-ctn" style="border-radius: 7vw;height: 100%;width: 100%;transform: scale(0);--base-delay:0.1s">
|
||||||
<span>弹性福利之旅</span>
|
<span>弹性福利之旅</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="black fake scale-in-txt" style="border-radius: 7vw;height: 100%;width: 100%;--base-delay:0.1s">
|
<span class="black fake scale-in-txt" style="border-radius: 7vw;height: 100%;width: 100%;transform: scale(0);--base-delay:0.1s">
|
||||||
<span>弹性福利之旅</span>
|
<span>弹性福利之旅</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="green scale-in-ctn"
|
<span class="green scale-in-ctn"
|
||||||
style="padding: 0 1.5vw;top: -17%;font-size: 3.5vw;right: -6%;height: 30%;border-radius: 3vw;--base-delay:0.2s">
|
style="padding: 0 1.5vw;top: -17%;font-size: 3.5vw;right: -6%;height: 30%;border-radius: 3vw;transform: scale(0);--base-delay:0.2s">
|
||||||
<span class="elan block relative">TOUR</span>
|
<span class="elan block relative">TOUR</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="green fake scale-in-txt"
|
<span class="green fake scale-in-txt"
|
||||||
style="padding: 0 1.5vw;top: -17%;font-size: 3.5vw;right: -6%;height: 30%;border-radius: 3vw;--base-delay:0.2s">
|
style="padding: 0 1.5vw;top: -17%;font-size: 3.5vw;right: -6%;height: 30%;border-radius: 3vw;transform: scale(0);--base-delay:0.2s">
|
||||||
<span class="elan block relative">TOUR</span>
|
<span class="elan block relative">TOUR</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div style="top: 11.7%;left: 53%; display: flex; flex-direction: column;">
|
<div style="top: 11.7%;left: 53%; display: flex; flex-direction: column;">
|
||||||
<span class="white relative swap-in" style="left: 30%;height: 5.5vw;--base-delay:0.6s">
|
<span class="white relative swap-in" style="left: 30%;height: 5.5vw;clip-path: inset(0 100% 0 0);--base-delay:0.6s">
|
||||||
<span class="elan">FLEXIBEL</span>
|
<span class="elan">FLEXIBEL</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="white relative swap-in" style="height: 5.5vw;--base-delay:0.9s">
|
<span class="white relative swap-in" style="height: 5.5vw;clip-path: inset(0 100% 0 0);--base-delay:0.9s">
|
||||||
<span class="elan">BENEFITS</span>
|
<span class="elan">BENEFITS</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<img :src="assets.p1.太阳" alt="" style="top: 30%;left: 5%;width: 26%;">
|
<img :src="assets.p1.太阳" alt="" style="top: 30%;left: 5%;width: 26%;">
|
||||||
<div style="width: 86vw;height: 86vw;top: 47%; left: 50%;transform: translate3d(-50%, -50%, 0); z-index: -1;">
|
<div style="width: 86vw;height: 86vw;top: 47%; left: 50%;transform: translate3d(-50%, -50%, 0); z-index: -1;">
|
||||||
<div v-for="i in regions" :style="{
|
<div v-for="i in regionsPos" :style="{
|
||||||
width: i.w + '%', height: i.h + '%', left: (i.l + 50) + '%', top: (i.t + 50) + '%',
|
width: i.w + '%',
|
||||||
'--t-start': (i.t + 50 - 200 - (100 - i.t)) + '%',
|
height: i.h + '%',
|
||||||
'--l-start': (i.l / 2 + 50) + '%',
|
transform: 'translate3d(-50%, -50%, 0) scale(0)',
|
||||||
'--t-end': (i.t + 50) + '%',
|
|
||||||
'--l-end': (i.l + 50) + '%',
|
|
||||||
animationDuration: (600 + i.ad * 100) + 'ms',
|
|
||||||
}" class="region-bubble">
|
}" class="region-bubble">
|
||||||
|
|
||||||
<img :src="i.src" alt="" style="height: 100%;width: 100%;">
|
<img :src="i.src" alt="" style="height: 100%;width: 100%;">
|
||||||
@ -144,22 +321,22 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="color: white; bottom: 16%;left: 50%;transform: translateX(-50%); font-size: 4.5vw;">
|
<div style="color: white; bottom: 16%;left: 50%;transform: translateX(-50%); font-size: 4.5vw;">
|
||||||
<span class="block tag scale-in-ctn" style="background-color: #000;top: -1vw;left: -12vw;color: transparent; --base-delay:1s;">
|
<span class="block tag scale-in-ctn" style="background-color: #000;top: -1vw;left: -12vw;color: transparent;transform: scale(0);--base-delay:1s;">
|
||||||
<span>点击</span>
|
<span>点击</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="block tag scale-in-ctn" style="background-color: #304A7B;top: 4vw;left: -6vw;color: transparent;--base-delay:1.1s;">
|
<span class="block tag scale-in-ctn" style="background-color: #304A7B;top: 4vw;left: -6vw;color: transparent;transform: scale(0);--base-delay:1.1s;">
|
||||||
<span>选择</span>
|
<span>选择</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="block tag scale-in-ctn" style="background-color: #8FBE56;top: .8vw;left: 4.5vw;color: transparent;--base-delay:1.1s;">
|
<span class="block tag scale-in-ctn" style="background-color: #8FBE56;top: .8vw;left: 4.5vw;color: transparent;transform: scale(0);--base-delay:1.1s;">
|
||||||
<span>阵营</span>
|
<span>阵营</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="block tag scale-in-txt" style="background-color: transparent;top: -1vw;left: -12vw;--base-delay:1.2s;">
|
<span class="block tag scale-in-txt" style="background-color: transparent;top: -1vw;left: -12vw;transform: scale(0);--base-delay:1.2s;">
|
||||||
<span>点击</span>
|
<span>点击</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="block tag scale-in-txt" style="background-color: transparent;top: 4vw;left: -6vw;--base-delay:1.2s;">
|
<span class="block tag scale-in-txt" style="background-color: transparent;top: 4vw;left: -6vw;transform: scale(0);--base-delay:1.2s;">
|
||||||
<span>选择</span>
|
<span>选择</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="block tag scale-in-txt" style="background-color: transparent;top: .8vw;left: 4.5vw;--base-delay:1.3s;">
|
<span class="block tag scale-in-txt" style="background-color: transparent;top: .8vw;left: 4.5vw;transform: scale(0);--base-delay:1.3s;">
|
||||||
<span>阵营</span>
|
<span>阵营</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -173,92 +350,6 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fade-in {
|
|
||||||
opacity: 0;
|
|
||||||
animation: fade-in 0.5s ease-in-out forwards;
|
|
||||||
animation-delay: var(--base-delay, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 使用 @property 注册你的自定义属性 */
|
|
||||||
@property --gradient-stop {
|
|
||||||
syntax: '<percentage>'; /* 告诉浏览器这是一个百分比 */
|
|
||||||
inherits: false; /* 这个属性不被子元素继承 */
|
|
||||||
initial-value: -20%; /* 定义一个初始值 */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes swap-in {
|
|
||||||
/* from/to 也可以,这里 0%/100% 没问题 */
|
|
||||||
from {
|
|
||||||
--gradient-stop: -20%;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
--gradient-stop: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.swap-in {
|
|
||||||
mask-image: linear-gradient(to right, black var(--gradient-stop), transparent calc(var(--gradient-stop) + 20%));
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-size: 100% 100%;
|
|
||||||
|
|
||||||
animation: swap-in 0.5s ease-in-out forwards;
|
|
||||||
animation-delay: var(--base-delay, 0);
|
|
||||||
}
|
|
||||||
@keyframes bubble-drop {
|
|
||||||
0% {
|
|
||||||
top: var(--t-start);
|
|
||||||
left: var(--l-start);
|
|
||||||
transform: translate3d(-50%, -50%, 0) scale(0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
top: var(--t-end);
|
|
||||||
left: var(--l-end);
|
|
||||||
transform: translate3d(-50%, -50%, 0) scale(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.region-bubble {
|
|
||||||
transform: translate3d(-50%, -50%, 0);
|
|
||||||
animation: bubble-drop 2s ease-out forwards;
|
|
||||||
animation-delay: 1s;
|
|
||||||
top: var(--t-start);
|
|
||||||
left: var(--l-start);
|
|
||||||
transform: translate3d(-50%, -50%, 0) scale(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes scale-in {
|
|
||||||
0% {
|
|
||||||
transform: scale(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.scale-in-ctn {
|
|
||||||
transform: scale(0);
|
|
||||||
animation: scale-in 0.5s cubic-bezier(0.5, 0, 0.71, 1.85) forwards;
|
|
||||||
animation-delay: calc(var(--base-delay, 0) + 0.2s);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scale-in-txt {
|
|
||||||
transform: scale(0);
|
|
||||||
animation: scale-in 0.5s cubic-bezier(0.5, 0, 0.71, 1.5) forwards;
|
|
||||||
animation-delay: calc(var(--base-delay, 0) + 0.2s + 0.1s);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
padding: 0.5vw .8vw;
|
padding: 0.5vw .8vw;
|
||||||
@ -308,6 +399,11 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.region-bubble {
|
||||||
|
position: absolute;
|
||||||
|
transform: translate3d(-50%, -50%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
span,
|
span,
|
||||||
div {
|
div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user