|
@@ -0,0 +1,1118 @@
|
|
|
+<script setup lang="ts">
|
|
|
+//@ts-ignore
|
|
|
+import MetaMaskSDK from '../utils/metamask-sdk.js'
|
|
|
+//@ts-ignore
|
|
|
+import getZksEra from '../utils/getZksEra.js'
|
|
|
+//@ts-ignore
|
|
|
+import getZksLite from '../utils/getZksLite.js'
|
|
|
+//@ts-ignore
|
|
|
+import getZkSyncBridge from '../utils/getZkSyncBridge.js'
|
|
|
+import * as echarts from 'echarts';
|
|
|
+import {onMounted, ref} from 'vue';
|
|
|
+
|
|
|
+import mySwapAv from '../project/mySwap/avatar.png'
|
|
|
+import mySwapBg from '../project/mySwap/BG.png'
|
|
|
+import starknetIdAv from '../project/starknetId/avatar.png'
|
|
|
+import starknetIdBg from '../project/starknetId/BG.png'
|
|
|
+import starkGateAv from '../project/starkGate/avatar.png'
|
|
|
+import starkGateBg from '../project/starkGate/BG.png'
|
|
|
+import realmsAv from '../project/realms/avatar.png'
|
|
|
+import realmsBg from '../project/realms/BG.png'
|
|
|
+import aspectAv from '../project/aspect/avatar.png'
|
|
|
+import aspectBg from '../project/aspect/BG.png'
|
|
|
+import briqAv from '../project/briq/avatar.png'
|
|
|
+import briqBg from '../project/briq/BG.png'
|
|
|
+import sithSwapAv from '../project/sithSwap/avatar.png'
|
|
|
+import sithSwapBg from '../project/sithSwap/BG.png'
|
|
|
+import fibrousAv from '../project/fibrous/avatar.png'
|
|
|
+import fibrousBg from '../project/fibrous/BG.png'
|
|
|
+
|
|
|
+import router from "@/router";
|
|
|
+import {useSunStore,useAddressStore} from "@/stores/sun";
|
|
|
+import Nav from '@/components/Nav.vue'
|
|
|
+import Footer from '@/components/Footer.vue'
|
|
|
+//@ts-ignore
|
|
|
+import {getAllZksSyncData} from "@/utils/getZksyncData/index.js";
|
|
|
+import {getStark} from "@/utils/stark/main.js";
|
|
|
+import { connect, disconnect } from "get-starknet"
|
|
|
+import axios from 'axios';
|
|
|
+import {Area, Bar} from '@antv/g2plot';
|
|
|
+import moment from "moment";
|
|
|
+
|
|
|
+const sunStore = useSunStore()
|
|
|
+const addressStore = useAddressStore()
|
|
|
+
|
|
|
+type EChartsOption = echarts.EChartsOption;
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ fetchData()
|
|
|
+ fetchData2()
|
|
|
+ connectWallet2()
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+type dataArrType = {
|
|
|
+ name: string,
|
|
|
+ type: string[],
|
|
|
+ BG: string,
|
|
|
+ avatar: string,
|
|
|
+ url:string
|
|
|
+}[]
|
|
|
+let dataArr: dataArrType = [
|
|
|
+ {
|
|
|
+ name: 'mySwap',
|
|
|
+ type: ['DeFi'],
|
|
|
+ BG: mySwapBg,
|
|
|
+ avatar: mySwapAv,
|
|
|
+ url:'https://www.myswap.xyz/'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name:'Starknet.id',
|
|
|
+ type: ['Digitalid ID'],
|
|
|
+ BG:starknetIdBg,
|
|
|
+ avatar:starknetIdAv,
|
|
|
+ url:'https://app.starknet.id/'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'StarkGate',
|
|
|
+ type: ['DEFI'],
|
|
|
+ BG: starkGateBg,
|
|
|
+ avatar: starkGateAv,
|
|
|
+ url:'https://starkgate.starknet.io/terms'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Realms',
|
|
|
+ type: ['GAMEFI', 'NFT'],
|
|
|
+ BG: realmsBg,
|
|
|
+ avatar: realmsAv,
|
|
|
+ url:'https://realms.world/'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'ASPECT',
|
|
|
+ type: ['NFT'],
|
|
|
+ BG: aspectBg,
|
|
|
+ avatar: aspectAv,
|
|
|
+ url:'https://aspect.co/'
|
|
|
+ },
|
|
|
+
|
|
|
+ {
|
|
|
+ name: 'briq',
|
|
|
+ type: ['NFT'],
|
|
|
+ BG: briqBg,
|
|
|
+ avatar: briqAv,
|
|
|
+ url:'https://briq.construction/'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name:'SithSwap',
|
|
|
+ type: ['DEFI','BRIDGE'],
|
|
|
+ BG:sithSwapBg,
|
|
|
+ avatar:sithSwapAv,
|
|
|
+ url:'https://app.sithswap.com/'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Fibrous',
|
|
|
+ type: ['DEFI'],
|
|
|
+ BG: fibrousBg,
|
|
|
+ avatar: fibrousAv,
|
|
|
+ url:'https://app.fibrous.finance/'
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+//连接钱包按钮
|
|
|
+const connectWallet2 = async () => {
|
|
|
+ const starknet = await connect();
|
|
|
+ addressStore.starkNetAddress = starknet.account.address
|
|
|
+ getMoreInfo()
|
|
|
+}
|
|
|
+
|
|
|
+//获取更多信息
|
|
|
+let amount = ref('-')
|
|
|
+let fee = ref('-')
|
|
|
+let contract = ref('-')
|
|
|
+let tradingTimeArr = ref()
|
|
|
+let l1Tol2Tx = ref('-')
|
|
|
+let l2Tol1Tx = ref('-')
|
|
|
+let tx = ref('-')
|
|
|
+
|
|
|
+const getMoreInfo = () => {
|
|
|
+ getStark(addressStore.starkNetAddress).then((res:any)=>{
|
|
|
+ if(res.result === "error"){
|
|
|
+ return
|
|
|
+ }
|
|
|
+ amount.value = res.Vol
|
|
|
+ fee.value = res.fee
|
|
|
+ contract.value = res.activity.contractActivity
|
|
|
+ tradingTimeArr.value = res.transactions
|
|
|
+ l1Tol2Tx.value = res.bridge.DepositTx
|
|
|
+ l2Tol1Tx.value = res.bridge.WithdrawTx
|
|
|
+ tx.value = res.tx
|
|
|
+ processTime()
|
|
|
+ })
|
|
|
+}
|
|
|
+//处理时间数据
|
|
|
+const monthArr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
|
|
+let showMonthNumberArr = ref([0,0,0,0,0,0,0,0,0,0,0,0])
|
|
|
+let showMonthArr = ref()
|
|
|
+const processTime = () => {
|
|
|
+ let nowDate = new Date().toString()
|
|
|
+ let nowDateArr = nowDate.split(' ')
|
|
|
+ let nowMonth = nowDateArr[1]
|
|
|
+ showMonthArr.value = []
|
|
|
+ showMonthArr.value.push(nowMonth)
|
|
|
+ let nowMonthIndex = monthArr.indexOf(nowMonth)
|
|
|
+ const forLoop = () => {
|
|
|
+ for (let i = 11; i !== nowMonthIndex ; i--) {
|
|
|
+ showMonthArr.value.unshift(monthArr[i])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (let i = nowMonthIndex; i !== 0 ; i--) {
|
|
|
+ showMonthArr.value.unshift(monthArr[i-1])
|
|
|
+ if (i === 1) {
|
|
|
+ forLoop()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (tradingTimeArr.value){
|
|
|
+ tradingTimeArr.value.forEach((item:any) => {
|
|
|
+ // if(item.balanceChanges[0].from && item.balanceChanges[0].from.toLowerCase() === addressStore.address.toLowerCase()){
|
|
|
+ let receivedAt = timestampToCtime(item.timestamp)
|
|
|
+ // console.log(receivedAt);
|
|
|
+ let strArr = receivedAt.split(' ')
|
|
|
+ let month = strArr[1]
|
|
|
+ let index = showMonthArr.value.indexOf(month)
|
|
|
+ showMonthNumberArr.value[index]++
|
|
|
+ // }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ initEcharts()
|
|
|
+
|
|
|
+}
|
|
|
+function timestampToCtime(timestamp) {
|
|
|
+ const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
|
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
|
+
|
|
|
+ const date = new Date(timestamp * 1000); // JavaScript使用毫秒为单位的时间戳,所以需要乘以1000
|
|
|
+ const day = days[date.getUTCDay()];
|
|
|
+ const month = months[date.getUTCMonth()];
|
|
|
+ const dayOfMonth = date.getUTCDate();
|
|
|
+ const time = date.getUTCHours() + ':' + ('0' + date.getUTCMinutes()).slice(-2) + ':' + ('0' + date.getUTCSeconds()).slice(-2);
|
|
|
+ const year = date.getUTCFullYear();
|
|
|
+
|
|
|
+ return `${day} ${month} ${dayOfMonth} ${time} UTC ${year}`;
|
|
|
+}
|
|
|
+//初始化echarts
|
|
|
+const initEcharts = () => {
|
|
|
+ let chartDom = document.getElementById('echartsBox1')!
|
|
|
+ let myChart = echarts.init(chartDom);
|
|
|
+ let option: EChartsOption;
|
|
|
+
|
|
|
+ option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisTick: {
|
|
|
+ alignWithLabel: true
|
|
|
+ },
|
|
|
+ data: showMonthArr.value
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ color: '#EC796B',
|
|
|
+ data: showMonthNumberArr.value,
|
|
|
+ type: 'bar'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+
|
|
|
+ option && myChart.setOption(option);
|
|
|
+}
|
|
|
+
|
|
|
+//跳转网页
|
|
|
+const toLink = (url:string) => {
|
|
|
+ window.open(url)
|
|
|
+}
|
|
|
+
|
|
|
+const toPage = (url:string) => {
|
|
|
+ router.push(url)
|
|
|
+}
|
|
|
+const toEmail = (email:string) => {
|
|
|
+ const emailAddress = email; // 替换为你想发送邮件的收件人地址
|
|
|
+ const subject = 'Hello'; // 替换为你想在邮件中设置的主题
|
|
|
+ const body = 'This is the email body.'; // 替换为你想在邮件中设置的内容
|
|
|
+
|
|
|
+ const mailtoUrl = `mailto:${emailAddress}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
|
|
|
+
|
|
|
+ window.open(mailtoUrl);
|
|
|
+}
|
|
|
+
|
|
|
+let affix = ref(false)
|
|
|
+let chart = ref(false)
|
|
|
+
|
|
|
+const affixMouseenter = () => {
|
|
|
+ const slideDiv = document.getElementById("slideDiv");
|
|
|
+ slideDiv.style.bottom = "0";
|
|
|
+}
|
|
|
+
|
|
|
+const affixMouseleave = () => {
|
|
|
+ const slideDiv = document.getElementById("slideDiv");
|
|
|
+ slideDiv.style.bottom = "-608px";
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const getStarkTvl = async () => {
|
|
|
+ const url = 'https://api.llama.fi/v2/historicalChainTvl/Starknet';
|
|
|
+ const response = await axios.get(url);
|
|
|
+ return response.data;
|
|
|
+}
|
|
|
+
|
|
|
+const getZkTvlDetail = async () => {
|
|
|
+ const url = "https://api.llama.fi/protocols";
|
|
|
+ const response = await axios.get(url);
|
|
|
+ let result = [];
|
|
|
+ response.data.forEach((item) => {
|
|
|
+ if (item['chains'].includes("Starknet") && item.category !== "CEX") {
|
|
|
+ result.push({
|
|
|
+ name: item.name,
|
|
|
+ tvl: item['chainTvls']['Starknet'] / 1000000,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ result.sort((a, b) => b.tvl - a.tvl);
|
|
|
+ result = result.slice(0, 10);
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+let change = ref(0)
|
|
|
+let change24h = ref('-')
|
|
|
+let nowTvl = ref('-')
|
|
|
+
|
|
|
+const fetchData = async () => {
|
|
|
+ const result = await getStarkTvl();
|
|
|
+ change.value = ((result[result.length - 1].tvl - result[result.length - 2].tvl) / result[result.length - 2].tvl) * 100;
|
|
|
+ change24h.value = change.value.toFixed(2) + '%'
|
|
|
+ nowTvl.value = (result[result.length - 1].tvl / 1000000).toFixed(2) + 'M'
|
|
|
+
|
|
|
+ let VolData = [];
|
|
|
+ result.forEach(item => {
|
|
|
+ VolData.push({
|
|
|
+ date: new Date(item.date * 1000).toLocaleDateString(),
|
|
|
+ tvl: item.tvl / 1000000,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ const max = Math.max(...VolData.map(item => item.tvl));
|
|
|
+ const chart = new Area('TVLBox',{
|
|
|
+ data: VolData,
|
|
|
+ xField: 'date',
|
|
|
+ yField: 'tvl',
|
|
|
+ smooth: true,
|
|
|
+ isStack: true,
|
|
|
+ padding:[60],
|
|
|
+ color: '#FFF',
|
|
|
+ // label: {
|
|
|
+ // style:{
|
|
|
+ // fill:'#FFF'
|
|
|
+ // },
|
|
|
+ // content: (originData) => {
|
|
|
+ // return `${originData.tvl.toFixed(0)}`;
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ slider: {
|
|
|
+ start: 0,
|
|
|
+ end: 1,
|
|
|
+ formatter: (v) => moment(v).format('YYYY-MM-DD'),
|
|
|
+ textStyle:{
|
|
|
+ fill:'#FFF'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ meta: {
|
|
|
+ tvl: {
|
|
|
+ alias: 'TVL(M)',
|
|
|
+ min: 0,
|
|
|
+ max: max * 1.1,
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ chart.render();
|
|
|
+}
|
|
|
+
|
|
|
+let TVLTopData = ref()
|
|
|
+const fetchData2 = async () => {
|
|
|
+ let result = await getZkTvlDetail();
|
|
|
+ TVLTopData.value = result.slice(0,5)
|
|
|
+
|
|
|
+ const max = Math.max(...result.map(item => item.tvl));
|
|
|
+ const chart = new Bar('TVLTop', {
|
|
|
+ data:result,
|
|
|
+ xField: 'tvl',
|
|
|
+ yField: 'name',
|
|
|
+ color: '#FFF',
|
|
|
+ yAxis: {
|
|
|
+ label: {
|
|
|
+ formatter: (v) => `${v}`,
|
|
|
+ }
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ position: 'right',
|
|
|
+ style:{
|
|
|
+ fill:'#FFF'
|
|
|
+ },
|
|
|
+ formatter: (v) => `${v.tvl.toFixed(2)}`,
|
|
|
+ },
|
|
|
+ meta: {
|
|
|
+ tvl: {
|
|
|
+ alias: 'TVL(M)',
|
|
|
+ max: max * 1.1,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ chart.render();
|
|
|
+}
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <main class="main">
|
|
|
+ <div class="mainBG">
|
|
|
+ <img src="../assets/navBg.png" alt="BG">
|
|
|
+ </div>
|
|
|
+ <Nav @doSth="connectWallet2"/>
|
|
|
+
|
|
|
+ <div class="chainBox">
|
|
|
+ <div class="item" @click="toPage('/zkSync')">
|
|
|
+ zkSync
|
|
|
+ </div>
|
|
|
+ <div class="item" @click="toPage('/layerZero')">
|
|
|
+ Layer Zero
|
|
|
+ </div>
|
|
|
+ <div class="item">
|
|
|
+ StarkNet
|
|
|
+ <div class="line"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="dataBox">
|
|
|
+ <div class="left">
|
|
|
+ <div class="leftTop">
|
|
|
+ <div class="item">
|
|
|
+ <div class="top">
|
|
|
+ <div class="img">
|
|
|
+ <img src="../assets/starkNet/STARKNET.svg" alt="STARKNET">
|
|
|
+ </div>
|
|
|
+ <div class="title">
|
|
|
+ Protocols lnteraction
|
|
|
+ <el-popover
|
|
|
+ placement="bottom"
|
|
|
+ :width="230"
|
|
|
+ trigger="hover"
|
|
|
+ effect="dark"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <img src="../assets/info.svg" alt="info">
|
|
|
+ </template>
|
|
|
+ <div class="popoverText">
|
|
|
+ Number of protocolsinteracted
|
|
|
+ </div>
|
|
|
+ <div class="popoverText">
|
|
|
+ with out of allavailable protocols
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="number">
|
|
|
+ {{ contract }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="item">
|
|
|
+ <div class="top">
|
|
|
+ <div class="img">
|
|
|
+ <img class="img" src="../assets/group4.svg" alt="group2">USDT
|
|
|
+ </div>
|
|
|
+ <div class="title">
|
|
|
+ <span style="width: 150px">vol</span>
|
|
|
+ <span>fee</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="number">
|
|
|
+ <span class="number" style="width: 150px">
|
|
|
+ {{ amount }}
|
|
|
+ </span>
|
|
|
+ <span class="number">
|
|
|
+ {{fee}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <img width="175" src="../assets/starkNet/starkNet.png" alt="starkNet">
|
|
|
+ </div>
|
|
|
+ <div class="leftBottom">
|
|
|
+ <div class="item">
|
|
|
+ <div class="top">
|
|
|
+ <div class="img">
|
|
|
+ <img src="../assets/starkNet/STARKNET.svg" alt="STARKNET">
|
|
|
+ </div>
|
|
|
+ <div class="title">
|
|
|
+ Total Transactions
|
|
|
+ <el-popover
|
|
|
+ placement="bottom"
|
|
|
+ :width="250"
|
|
|
+ trigger="hover"
|
|
|
+ effect="dark"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <img src="../assets/info.svg" alt="info">
|
|
|
+ </template>
|
|
|
+ <div class="popoverText">
|
|
|
+ Total StarkNet
|
|
|
+ </div>
|
|
|
+ <div class="popoverText">
|
|
|
+ transactions issuedfrom the account
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="number">
|
|
|
+ {{ tx }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="item" style="height: 94px">
|
|
|
+ <div class="top">
|
|
|
+ <div class="img">
|
|
|
+ <img v-show="!sunStore.sun" class="img" src="../assets/official-bridge-white.svg" alt="group2">
|
|
|
+ <img v-show="sunStore.sun" class="img" src="../assets/official-bridge-black.svg" alt="group2">
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;gap:40px">
|
|
|
+ <div style="display: flex;flex-direction: column;gap:20px">
|
|
|
+ <img v-show="!sunStore.sun" src="../assets/L1-To-L2-white.svg" alt="To">
|
|
|
+ <img v-show="sunStore.sun" src="../assets/L1-To-L2.svg" alt="To">
|
|
|
+ <div class="number">
|
|
|
+ {{ l1Tol2Tx }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;flex-direction: column;gap:20px">
|
|
|
+ <img v-show="!sunStore.sun" src="../assets/L2-To-L1-white.svg" alt="To">
|
|
|
+ <img v-show="sunStore.sun" src="../assets/L2-To-L1.svg" alt="To">
|
|
|
+ <div class="number">
|
|
|
+ {{ l2Tol1Tx }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="position: relative">
|
|
|
+ <div style="display: flex;align-items: center;position: absolute;left: 40px;top:10px;z-index: 10;gap:4px">
|
|
|
+ Transactions Over Time
|
|
|
+ <el-popover
|
|
|
+ placement="right"
|
|
|
+ :width="240"
|
|
|
+ trigger="hover"
|
|
|
+ effect="dark"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <img src="../assets/info.svg" alt="info">
|
|
|
+ </template>
|
|
|
+ <div class="popoverText">
|
|
|
+ Number of transactions permonth
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ <div class="right" id="echartsBox1">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div class="projectBox">
|
|
|
+ <div class="item" @click="toLink(item.url)" v-for="item in dataArr">
|
|
|
+ <div class="BG">
|
|
|
+ <img class="BG" :src="item.BG" alt="BG">
|
|
|
+ </div>
|
|
|
+ <div class="infoBox">
|
|
|
+ <div class="avatar">
|
|
|
+ <img class="avatar" :src="item.avatar" alt="avatar">
|
|
|
+ </div>
|
|
|
+ <div class="nameAndType">
|
|
|
+ <div class="name">
|
|
|
+ {{ item.name }}
|
|
|
+ </div>
|
|
|
+ <div class="typeBox">
|
|
|
+ <div class="type" v-for="item1 in item.type">
|
|
|
+ {{ item1 }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="dividingLine"/>
|
|
|
+ <Footer/>
|
|
|
+ <div class="dividingLine"/>
|
|
|
+ <div style="height: 61px;" @mouseenter="affixMouseenter" @mouseleave="affixMouseleave">
|
|
|
+ <div class="dataChart" id="slideDiv">
|
|
|
+ <div class="box">
|
|
|
+ <div class="titleBox">
|
|
|
+ <div class="title">
|
|
|
+ <img src="../assets/title.svg" alt="title">
|
|
|
+ starkNet info
|
|
|
+ </div>
|
|
|
+ <!-- <div class="exit" v-show="chart" @click="chart = false">-->
|
|
|
+ <!-- <img src="../assets/exit.svg" alt="exit">-->
|
|
|
+ <!-- Exit-->
|
|
|
+ <!-- </div>-->
|
|
|
+ </div>
|
|
|
+ <div class="data" >
|
|
|
+ <div class="dataGroup">
|
|
|
+ <div class="dataGroupTitle">
|
|
|
+ <img src="../assets/TVL.svg" alt="TVL">
|
|
|
+ TVL(M)
|
|
|
+ </div>
|
|
|
+ <div class="itemBox">
|
|
|
+ <div class="item">
|
|
|
+ <div class="text1">
|
|
|
+ {{nowTvl}}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="text2">
|
|
|
+ Now
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="item">
|
|
|
+ <div class="text3" v-show="change>=0">
|
|
|
+ {{change24h}}
|
|
|
+ </div>
|
|
|
+ <div class="text3" style="color: red" v-show="change<0">
|
|
|
+ {{change24h}}
|
|
|
+ </div>
|
|
|
+ <div class="text2">
|
|
|
+ 24h
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="verticalLine"/>
|
|
|
+ <div class="dataGroup">
|
|
|
+ <div class="dataGroupTitle">
|
|
|
+ <img src="../assets/tag.svg" alt="TVL">
|
|
|
+ Top 5 TVL(M)
|
|
|
+ </div>
|
|
|
+ <div class="itemBox">
|
|
|
+ <div class="item" v-for="(item,index) in TVLTopData">
|
|
|
+ <div class="text1">
|
|
|
+ {{ item.tvl.toFixed(2) }}M
|
|
|
+ </div>
|
|
|
+ <div class="text2">
|
|
|
+ {{ item.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- <div class="viewMore" v-show="affix" @click="chart = true">-->
|
|
|
+ <!-- <img src="../assets/viewMore.svg" alt="viewMore">-->
|
|
|
+ <!-- view more-->
|
|
|
+ <!-- </div>-->
|
|
|
+ <div class="chartBox">
|
|
|
+ <div class="TVLBox" id="TVLBox">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div class="TVLTop" id="TVLTop">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </main>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.main {
|
|
|
+ width: 1440px;
|
|
|
+ height: 100%;
|
|
|
+ margin: auto;
|
|
|
+ border: 1px solid var(--vt-c-border);
|
|
|
+ border-top: none;
|
|
|
+ border-bottom: none;
|
|
|
+ padding: 30px 60px 0;
|
|
|
+ .dividingLine {
|
|
|
+ width: 100vw;
|
|
|
+ height: 1px;
|
|
|
+ border-bottom: 1px solid var(--vt-c-border);
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ }
|
|
|
+ .mainBG{
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: -1;
|
|
|
+ }
|
|
|
+ .topBar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 0 60px 25px;
|
|
|
+ margin: 0 -60px;
|
|
|
+ border-bottom: 1px solid var(--vt-c-border);
|
|
|
+ .left{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .nav{
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 21px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ padding: 0 60px;
|
|
|
+ height: 100px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: -25px;
|
|
|
+ margin-top: -30px;
|
|
|
+ border-right: 1px solid var(--vt-c-border);
|
|
|
+ position: relative;
|
|
|
+ .line{
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 10px;
|
|
|
+ background: var(--color-text);
|
|
|
+ left: 0;
|
|
|
+ bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .navOne{
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 21px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ padding: 0 60px;
|
|
|
+ height: 100px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: -25px;
|
|
|
+ margin-top: -30px;
|
|
|
+ border-right: 1px solid var(--vt-c-border);
|
|
|
+ margin-left: 57px;
|
|
|
+ border-left: 1px solid var(--vt-c-border);
|
|
|
+ position: relative;
|
|
|
+ .line{
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 10px;
|
|
|
+ background: var(--color-text);
|
|
|
+ left: 0;
|
|
|
+ bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .mid{
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 15px;
|
|
|
+ line-height: 21px;
|
|
|
+ font-family: 'Chillax';
|
|
|
+ text-transform: uppercase;
|
|
|
+ }
|
|
|
+ .right {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap:40px;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ .button {
|
|
|
+ width: fit-content;
|
|
|
+ height: 44px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ background: #010101;
|
|
|
+ padding: 0 24px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 15px;
|
|
|
+ line-height: 20px;
|
|
|
+ color: #FFFFFF;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .connect {
|
|
|
+ width: fit-content;
|
|
|
+ height: 44px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border: 1px solid #010101;
|
|
|
+ border-radius: 30px;
|
|
|
+ padding: 0 24px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 15px;
|
|
|
+ line-height: 20px;
|
|
|
+ color: #010101;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .chainBox{
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin: 0 -60px;
|
|
|
+ .item{
|
|
|
+ padding: 24px 65px;
|
|
|
+ border-right: 1px solid var(--vt-c-border);
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 15px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ position: relative;
|
|
|
+ cursor: pointer;
|
|
|
+ .line{
|
|
|
+ position: absolute;
|
|
|
+ width: 60px;
|
|
|
+ height: 4px;
|
|
|
+ background: var(--color-text);
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ margin: auto;
|
|
|
+ bottom: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .dataBox {
|
|
|
+ height: 365px;
|
|
|
+ margin: 0 -60px;
|
|
|
+ border-bottom: 1px solid var(--vt-c-border);
|
|
|
+ border-top: 1px solid var(--vt-c-border);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .left {
|
|
|
+ width: 845px;
|
|
|
+ height: 100%;
|
|
|
+ border-right: 1px solid var(--vt-c-border);
|
|
|
+ .item {
|
|
|
+ width: 260px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 20px;
|
|
|
+
|
|
|
+ .top {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 6px;
|
|
|
+
|
|
|
+ .img {
|
|
|
+ height: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .publicChainBox{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap:40px;
|
|
|
+ .publicChainItem{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap:20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 18px;
|
|
|
+ //color: #010101;
|
|
|
+ font-family: 'HONOR Sans CN';
|
|
|
+ .popoverText{
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .number {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 26px;
|
|
|
+ line-height: 34px;
|
|
|
+ //color: #010101;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .leftTop {
|
|
|
+ height: 175px;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding-left: 60px;
|
|
|
+ padding-right: 60px;
|
|
|
+ border-bottom: 1px solid var(--vt-c-border);
|
|
|
+ .img{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 700;
|
|
|
+ gap:4px
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .leftBottom {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ height: 175px;
|
|
|
+ padding-left: 60px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .right {
|
|
|
+ height: 365px;
|
|
|
+ width: 596px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .projectBox{
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ overflow:auto;
|
|
|
+ gap: 28px;
|
|
|
+ height: 585px;
|
|
|
+ margin: 0px -60px;
|
|
|
+ padding: 20px 0;
|
|
|
+ border-bottom: 1px solid var(--vt-c-border);
|
|
|
+
|
|
|
+ .item {
|
|
|
+ height: 256px;
|
|
|
+ width: 336px;
|
|
|
+ cursor: pointer;
|
|
|
+ .BG {
|
|
|
+ width: 100%;
|
|
|
+ height: 175px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .infoBox {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+ padding: 0 24px;
|
|
|
+ height: 80px;
|
|
|
+ //border: 1px solid #010101;
|
|
|
+ border-top: none;
|
|
|
+ background: #FFFFFF;
|
|
|
+
|
|
|
+ .avatar {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ border-radius: 50%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nameAndType {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 2px;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 17px;
|
|
|
+ line-height: 22px;
|
|
|
+ color: #010101;
|
|
|
+ }
|
|
|
+
|
|
|
+ .typeBox {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
+ .type {
|
|
|
+ width: fit-content;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
+ color: #b3b3b3;
|
|
|
+ padding: 0 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .type::before {
|
|
|
+ content: "\00B7";
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .dataChart{
|
|
|
+ width: 100vw;
|
|
|
+ position: fixed;
|
|
|
+ bottom: -608px;
|
|
|
+ left: 0;
|
|
|
+ background: rgba(40, 40, 40, 0.96);
|
|
|
+ backdrop-filter: blur(34px);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ transition: bottom 0.3s ease-in-out;
|
|
|
+ .box{
|
|
|
+ width: 1440px;
|
|
|
+ height: 100%;
|
|
|
+ .titleBox{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 20px 0;
|
|
|
+ .title{
|
|
|
+ display: flex;
|
|
|
+ color: #FFF;
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 15px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ gap:8px;
|
|
|
+ opacity: 0.5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .exit{
|
|
|
+ color: #FFF73F;
|
|
|
+ font-family: Space Grotesk;
|
|
|
+ font-size: 15px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ display: flex;
|
|
|
+ gap:8px;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .data{
|
|
|
+ display: flex;
|
|
|
+ gap:80px;
|
|
|
+ align-items: center;
|
|
|
+ padding: 24px 0;
|
|
|
+ border-bottom: 1px solid #4C4C4C;
|
|
|
+ border-top: 1px solid #4C4C4C;
|
|
|
+
|
|
|
+ .dataGroup{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap:16px;
|
|
|
+ .dataGroupTitle{
|
|
|
+ display: flex;
|
|
|
+ color: #FFF;
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 15px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ gap:8px;
|
|
|
+ opacity: 0.5;
|
|
|
+
|
|
|
+ }
|
|
|
+ .itemBox{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap:80px;
|
|
|
+ .item{
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap:8px;
|
|
|
+ .text1{
|
|
|
+ color: #FFF;
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 21px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ }
|
|
|
+ .text2{
|
|
|
+ color: #FFF;
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 14px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: normal;
|
|
|
+ opacity: 0.5;
|
|
|
+ }
|
|
|
+ .text3{
|
|
|
+ color: #57EB92;
|
|
|
+ font-family: HONOR Sans CN;
|
|
|
+ font-size: 21px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .verticalLine{
|
|
|
+ width: 1px;
|
|
|
+ height: 88px;
|
|
|
+ border-right: 1px solid #4c4c4c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .viewMore{
|
|
|
+ width: 100%;
|
|
|
+ padding: 20px 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap:8px;
|
|
|
+ color: #FFF73F;
|
|
|
+ font-family: Space Grotesk;
|
|
|
+ font-size: 15px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: normal;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .chartBox{
|
|
|
+ width: 100%;
|
|
|
+ height: 468px;
|
|
|
+ display: flex;
|
|
|
+ .TVLBox{
|
|
|
+ width: 840px;
|
|
|
+ height: 100%;
|
|
|
+ border-right: 1px solid #4c4c4c;
|
|
|
+ border-left: 1px solid #4c4c4c;
|
|
|
+ }
|
|
|
+ .TVLTop{
|
|
|
+ width: 600px;
|
|
|
+ height: 100%;
|
|
|
+ border-right: 1px solid #4c4c4c;
|
|
|
+ padding: 60px
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::-webkit-scrollbar {
|
|
|
+ width: 4px; /* 滚动条宽度 */
|
|
|
+}
|
|
|
+
|
|
|
+// /* 滚动条轨道 */
|
|
|
+// ::-webkit-scrollbar-track {
|
|
|
+// background: #f1f1f1; /* 轨道背景色 */
|
|
|
+// }
|
|
|
+
|
|
|
+/* 滚动条滑块 */
|
|
|
+::-webkit-scrollbar-thumb {
|
|
|
+ background: #888; /* 滑块背景色 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 滚动条滑块悬停状态 */
|
|
|
+::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: #555; /* 悬停状态下滑块背景色 */
|
|
|
+}
|
|
|
+</style>
|