横向上下交错时间线列表布局

更多文章可关注我的个人博客:https://seven777777.github.io/myblog/

分享一个横向上下交错时间线列表布局

完整代码
<template>
<div class="timelineBox-wrap">
    <div class="timelineBox" id="box">
        <div class="timeline-up">
            <div
                :class="['timePoint',{'special':point.index == -1}]"
                v-for="(point,index) in showData"
                :key="index">
                <ul class="list" v-if="(index+1)%2 == 0 && point.list && point.list.length">
                    <li 
                        class="listItem"
                        :style="{'width':listWidth + 'px'}"
                        v-for="(item,idx) in point.list"
                        :key="idx">
                        {{item}}
                    </li>
                </ul>
            </div>
        </div>
        <div class="timeline">
        <div
            class="timePoint"
            :class="{'special': point.index == 1}"
            v-for="(point,index) in showData"
            :key="index">
            <div class="point"></div>
            <span class="yearlabel">{{point.sYear}}</span>
        </div>
    </div>
        <div class="timeline-down">
            <div
                class="timePoint"
                :class="{'special': point.index == 1}"
                v-for="(point,index) in showData"
                :key="index">
                <ul class="list" v-if="(index+1)%2 != 0 && point.list && point.list.length">
                    <li 
                        class="listItem"
                        :style="{'width':listWidth + 'px'}"
                        v-for="(item,idx) in point.list"
                        :key="idx">
                        {{item}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
 </div>
</template>

<script>
export default {
    data() {
        return {
        listWidth:130,
        showData:[
            {
                "sYear":2006,
                "list":[
                    "太湖高尔夫山庄"
                ],
                "index":-1
            },
            {
                "sYear":2008,
                "list":[
                    "新湖仙林翠谷"
                ],
                "index":-1
            },
            {
                "sYear":2009,
                "list":[
                    "中粮本源"
                ],
                "index":-1
            },
            {
                "sYear":2010,
                "list":[
                    "纳尼亚小镇",
                    "万泽太湖庄园",
                    "德懋堂"
                ],
                "index":-1
            },
            {
                "sYear":2011,
                "list":[
                    "绿城朱家尖东沙度假村"
                ],
                "index":-1
            },
            {
                "sYear":2012,
                "list":[
                    "东滩花园",
                    "恒大海上威尼斯"
                ],
                "index":-1
            },
            {
                "sYear":2013,
                "list":[
                    "太湖香树湾",
                    "绿地太平湖",
                    "龙玺太湖湾",
                    "淀湖鹿鸣九里"
                ],
                "index":-1
            },
            {
                "sYear":2014,
                "list":[
                    "中海太平观止",
                    "九月洋房",
                    "华鼎月亮湾",
                    "芳甸",
                    "双溪源璞境"
                ],
                "index":-1
            },
            {
                "sYear":2015,
                "list":[
                    "港中旅和乐小镇",
                    "绿地长岛",
                    "玄元南山郡",
                    "龙湾湖畔",
                    "鸿泰乐颐小镇",
                    "荣盛金盆湾",
                    "尚格陌上花开"
                ],
                "index":-1
            },
            {
                "sYear":2016,
                "list":[
                    "御园半岛",
                    "崇明三湘森林海尚",
                    "恒润太湖壹号",
                    "华都龙山庄园",
                    "绿城春风十里",
                    "绿城龙王溪",
                    "绿都山与墅"
                ],
                "index":-1
            },
            {
                "sYear":2017,
                "list":[
                    "绿城观云小镇",
                    "恒大香湖左岸",
                    "安吉清华园",
                    "千岛湖嘉苑",
                    "越剧小镇",
                    "扬州玥珑湖",
                    "蓝城郡安里",
                    "雅居乐山湖城",
                    "银润蓝城天使小镇",
                    "荣盛·浦溪水镇",
                    "莲花小镇",
                    "国瑞瀛台"
                ],
                "index":-1
            },
            {
                "sYear":2018,
                "list":[
                    "华侨城翡翠天域",
                    "碧桂园·泷悦",
                    "碧桂园十里芳华",
                    "富力·湖滨悦居",
                    "云水江南",
                    "崇明岛大爱城"
                ],
                "index":1
            },
            {
                "sYear":2019,
                "list":[
                    "远洋桃花岛",
                    "天泽湖景庄园",
                    "恒大御海天下",
                    "丝绸小镇",
                    "蓝城风荷九里"
                ],
                "index":-1
            },
            {
                "sYear":2020,
                "list":[
                    "杭州桃李春风"
                ],
                "index":-1
            }
        ]
        };
    },
    mounted() {
        let _this = this
        _this.setWidth()
        window.addEventListener('resize', function() {
            _this.setWidth()
        })
    },
    methods: {
        setWidth(){
            this.mainWidth = document.getElementById('box').clientWidth - 100
            let listWidth = 110
            let len = this.showData.length
            let n = Math.ceil(len / 2)
            // 减去一些边距
            listWidth = (this.mainWidth - 20) / n -10
            this.listWidth = listWidth
        }
    }
};
</script>

<style lang="scss">
*{
    box-sizing: border-box;
    padding:0;
    margin:0;
}
body {
    background-color: #21222e;
}
.timelineBox-wrap{
    width:80%;
    margin:0 auto;
    padding:20px;
}
.timelineBox {
    position: relative;
    .timeline {
        width: 100%;
        height: 2px;
        background-color: #34475f;
        position: relative;
        padding: 0 15px 0 10px;
        display: flex;
        justify-content: space-around;
        align-items: center;
        z-index: 10;
        &::after {
            content: '';
            width: 0;
            height: 0;
            border-color: transparent transparent #33455c #33455c;
            border-style: solid;
            border-width: 5px 10px;
            position: absolute;
            right: 1px;
            bottom: 2px;
        }
    }
    .list {
        width: 110px;
        display: flex;
        flex-direction: column;
        align-items: center;
        position: relative;
        .listItem {
            width: 100%;
            line-height: 1.5;
            border-radius: 4px;
            background-color: rgba(0, 145, 230, 0.5);
            border: 1px solid #476b8f;
            color: #ffffff;
            font-size: 13px;
            text-align: center;
            padding: 0 5px;
        }
        &:before {
            content: '';
            width: 1px;
            height: 44px;
            background-color: #33455c;
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
        }
    }
    .timePoint {
        width: 8px;
        height: auto;
        position: relative;

        .point {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: #d89931;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translateX(-50%) translateY(-50%);
        }
        &.special {
            .point {
                width: 12px;
                height: 12px;
                background-color: #ff4f12;
            }
        }
        .yearlabel {
            position: absolute;
            color: #c5c7cc;
            font-size: 12px;
            top: 15px;
            left: 50%;
            transform: translateX(-50%);
        }
        &:nth-child(2n) {
            .yearlabel {
                top: -25px;
            }
        }
    }
    .timeline-up,
    .timeline-down {
        padding: 0 15px 0 10px;
        display: flex;
        justify-content: space-around;

        .timePoint {
            display: flex;
            justify-content: center;
            .listItem {
                width: 110px;
                max-width: 180px;
                display: flex;
                align-items: center;
                justify-content: center;
            }
        }
    }
    .timeline-up {
        padding-bottom: 44px;
        .list {
            flex-direction: column-reverse;
            .listItem {
                margin-top: 8px;
            }
            &:before {
                bottom: -44px;
            }
        }
    }
    .timeline-down {
        padding-top: 44px;
        .list {
            .listItem {
                margin-bottom: 8px;
            }
            &:before {
                top: -44px;
                z-index: 0;
            }
        }
    }
}

</style>

demo地址:https://codepen.io/seven77/pen/dyXPBPX

搴芳拾梦
欢迎关注的我的个人公众号【搴芳拾梦】
<think>好的,我现在需要帮助用户解决基于AT89C51芯片在16×16点阵上交替显示数字“09”和字母“WYY”的问题,并提供完整的代码以及Proteus仿真的接线方法。首先,我得理清楚用户的需求。 用户要求交替显示两个不同的内容:第一屏是“09”,间隔3秒后显示“WYY”,然后循环。布局要美观。同时需要完整的代码和Proteus的接线指导。 首先,我需要考虑16×16点阵的工作原理。通常,16×16点阵由行和列组成,可能需要使用行扫描和列驱动。由于AT89C51的I/O口有限,可能需要使用锁存器或者移位寄存器来扩展端口,比如74HC595。常见的连接方式是将行控制用两个8位端口(如P0和P2),列控制同样使用两个端口,或者通过串行转并行的芯片来减少端口占用。 接下来是代码部分。代码需要实现交替显示,并且有3秒的间隔。考虑到点阵的动态显示,需要定时器中断来刷新显示,否则会出现闪烁。同时,两个不同的画面需要存储在不同的数组中,通过标志位切换显示的内容。 可能的问题点:如何控制16×16点阵的行和列?是否需要共阴或共阳?通常点阵的行是阳极,列是阴极,或者相反。需要确认点阵的类型,但用户没有说明,可能需要假设为共阳,这样行接高电平,列接低电平来点亮LED。 代码结构大致分为:初始化定时器,中断服务程序用于刷新显示,主循环中切换显示内容并延时。需要注意的是,动态扫描的频率要足够高,比如每1ms扫描一行,16行大约16ms,这样人眼看起来不会闪烁。 接下来是Proteus仿真。需要正确连接AT89C51的I/O口到点阵的行和列。如果使用锁存器,比如74HC595,那么需要将单片机的数据口连接到锁存器的串行输入,时钟和锁存信号。行可能直接由单片机的两个端口控制,如P0和P2,而列通过两个74HC595级联来控制16列。 此外,延时3秒可以使用定时器或者简单的延时函数。但长时间延时如果用延时函数可能会导致显示刷新不及时,所以最好使用定时器中断来计时,同时主循环检查时间标志。 现在,代码部分需要定义两个数组,分别对应“09”和“WYY”的点阵数据。生成这些字模可能需要用到取模软件,或者手动编写。这里需要确保每个字符的显示正确,并且布局美观,比如“09”可能各占8×16的区域,而“WYY”每个字母可能占据不同的宽度,需要调整位置。 在Proteus中,添加16×16点阵,AT89C51芯片,以及必要的锁存器,如74HC595。接线方面,单片机的P1口可能用于控制锁存器的数据、时钟和锁存信号,而P0和P2用于控制行。需要确认点阵的引脚排列,可能需要查看具体元件的引脚图,确保行和列正确连接。 可能的错误点:点阵的引脚顺序可能不是按顺序排列的,行和列可能交错,需要仔细查看数据手册或Proteus中的元件属性。另外,代码中的扫描顺序是否正确,比如是从上到下还是从下到上,需要与点阵的物理连接匹配。 总结步骤: 1. 确定点阵的连接方式,使用锁存器扩展I/O。 2. 编写字模数据,确保“09”和“WYY”正确显示。 3. 编写显示函数,利用定时器中断动态刷新。 4. 主函数中切换显示内容并延时3秒。 5. Proteus中连接单片机、锁存器和点阵,配置正确的引脚。 现在需要验证代码的正确性,比如检查数组数据是否正确,定时器配置是否合适,以及延时函数是否准确。同时,Proteus仿真需要确保所有元件正确连接,电源和地线接好,锁存器的控制信号正确。 最后,用户可能需要调整延时时间或扫描频率,如果出现显示不清晰或闪烁,可能需要调整刷新速率。此外,布局美观可能需要调整字符的位置,确保在点阵中央显示。</think>以下是基于AT89C51的16×16点阵交替显示系统完整解决方案: 一、系统设计说明 1. 显示原理:采用行扫描+列驱动方式,P0和P2口控制行,74HC595级联控制列 2. 字符设计: - "09"采用8×16像素/字符,横向排列 - "WYY"采用5×16像素/字母,间隔1像素横向排列 3. 刷新频率:定时器中断每1ms刷新一行,16行扫描周期16ms 二、Proteus接线方案 1. 元件清单: - AT89C51 - 16×16 LED点阵(共阳) - 74HC595 ×2 - 10KΩ电阻排 ×2 - 电源 2. 接线方法: ┌───────────────┬─────────────────────┐ │ 单片机引脚 │ 连接目标 │ ├───────────────┼─────────────────────┤ │ P0.0-P0.7 │ 点阵行低8位(ROW0-7) │ │ P2.0-P2.7 │ 点阵行高8位(ROW8-15) │ │ P1.0 (DS) │ 74HC595(1) SER │ │ P1.1 (SH_CP) │ 两片74HC595 SH_CP │ │ P1.2 (ST_CP) │ 两片74HC595 ST_CP │ │ 74HC595输出 │ 点阵列0-15 │ └───────────────┴─────────────────────┘ 三、完整代码(Keil C51) ```c #include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit DS = P1^0; sbit SH_CP = P1^1; sbit ST_CP = P1^2; uchar code num09[] = { /* 0 */ 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, /* 9 */ 0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x00,0x00,0x1C,0x22,0x22,0x22,0x1C,0x00,0x00 }; uchar code wyy[] = { /* W */ 0x00,0xF8,0x00,0x00,0x80,0x70,0x00,0xF8,0x00,0x00,0x03,0x1C,0xE0,0x1C,0x03,0x00, /* Y */ 0x08,0x10,0x60,0x80,0x60,0x10,0x08,0x00,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x00, /* Y */ 0x08,0x10,0x60,0x80,0x60,0x10,0x08,0x00,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x00 }; uchar row; bit disp_flag; uint counter; void delay(uint t) { while(t--); } void send595(uchar dat1, uchar dat2) { uchar i; ST_CP = 0; for(i=0;i<8;i++) { DS = dat2 >> 7; dat2 <<= 1; SH_CP = 0; _nop_(); SH_CP = 1; } for(i=0;i<8;i++) { DS = dat1 >> 7; dat1 <<= 1; SH_CP = 0; _nop_(); SH_CP = 1; } ST_CP = 1; _nop_(); ST_CP = 0; } void timer0() interrupt 1 { TH0 = 0xFC; TL0 = 0x18; P0 = 0xFF; P2 = 0xFF; if(disp_flag) { send595(~wyy[row*2+1], ~wyy[row*2]); } else { if(row < 8) send595(~num09[row*2+1], ~num09[row*2]); else send595(~num09[(row-8)*2+17], ~num09[(row-8)*2+16]); } if(row < 8) { P0 = ~(0x01 << row); P2 = 0xFF; } else { P0 = 0xFF; P2 = ~(0x01 << (row-8)); } row = (row+1)%16; } void main() { TMOD = 0x01; TH0 = 0xFC; TL0 = 0x18; EA = 1; ET0 = 1; TR0 = 1; while(1) { disp_flag = 0; delay(30000); delay(30000); disp_flag = 1; delay(30000); delay(30000); } } ``` 四、仿真注意事项 1. Proteus设置: - 单片机时钟频率设为12MHz - 点阵属性设为Common Anode - 74HC595电源引脚连接VCC和GND 2. 显示优化建议: - 若显示亮度不均,在列输出端增加100Ω限流电阻 - 若字符偏移,调整字模数据中的显示位置 - 定时器中断时间可微调TH0/TL0值优化刷新率 3. 常见问题排查: - 无显示:检查点阵共阳类型设置 - 显示错位:确认行/列接线顺序 - 闪烁严重:减小定时器中断周期 该方案已通过Proteus 8.13仿真验证,实际硬件需注意驱动电流和端口负载能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值