<template>
    <div
        class="table"
        ref="wrapbox"
        @scroll.passive="handleScrolls"
        @mousewheel="wrapboxWheel"
    >
        <div class="table-title">
            <span v-for="item in titleList" :key="item.key">
                {{ item.name }}
            </span>
        </div>
        <div class="wrapper" @click="handleSectionClick($event)" v-if="data.length !== 0">
            <div
                ref="realBox"
                :style="pos"
                @mouseenter="enter"
                @mouseleave="leave"
                @touchstart="touchStart"
                @touchmove="touchMove"
                @touchend="touchEnd"
                class="warp"
            >
                <div ref="slotList" :style="float">
                    <ul class="item">
                        <li v-for="(item, index) in data" :key="index">
                            <!-- v-text="item[i.key] || 0"  @click="handleItem(item)"-->
                            <span
                                class="hideLengthText"
                                :class="i.color"
                                v-for="i in titleList"
                                :key="i.key"
                            >
                                <!-- <el-tooltip
                                class="item"
                                effect="dark"
                                :content="myToString(item[i.key])"
                                placement="top"
                            > -->
                                <span :data-name="item.name" :data-id="item.id">
                                    <template v-if="i.key === 'warnType'">
                                        <i class="blue" v-if="item[i.key] == 1">
                                            蓝色预警
                                        </i>
                                        <i class="yellow" v-if="item[i.key] == 2">
                                            黄色预警
                                        </i>
                                        <i class="red" v-if="item[i.key] == 3">
                                            红色预警
                                        </i>
                                    </template>
                                    <template v-else-if="i.key === 'state'">
                                        <i class="green" v-if="item[i.key] == 1">
                                            <b class="icon icon-green"></b>
                                            基本完好
                                        </i>
                                        <i class="blue" v-if="item[i.key] == 2">
                                            <b class="icon icon-blue"></b>
                                            轻微异常
                                        </i>
                                        <i class="yellow" v-if="item[i.key] == 3">
                                            <b class="icon icon-yellow"></b>
                                            中等异常
                                        </i>
                                        <i class="red" v-if="item[i.key] == 4">
                                            <b class="icon icon-red"></b>
                                            严重异常
                                        </i>
                                    </template>
                                    <template v-else-if="i.key === 'status'">
                                        <i class="red" v-if="item[i.key] == 0">
                                            <!-- <b class="icon icon-green"></b> -->
                                            <img
                                                src="@/views/bigScreen/img/icon-device-offline.png"
                                                alt=""
                                            />
                                            离线
                                        </i>
                                        <i class="green" v-if="item[i.key] == 1">
                                            <!-- <b class="icon icon-blue"></b> -->
                                            <img
                                                src="@/views/bigScreen/img/icon-device-online.png"
                                                alt=""
                                            />
                                            在线
                                        </i>
                                    </template>
                                    <!-- <template v-else-if="i.key === 'type'">
                                        <i v-if="item[i.key] == 1">上行</i>
                                        <i v-if="item[i.key] == 2">下行</i>
                                    </template> -->
                                    <template v-else>
                                        {{ item[i.key] || 0 }}
                                    </template>
                                </span>
                                <!-- </el-tooltip> -->
                            </span>
                        </li>
                    </ul>
                </div>
                <!-- <div v-html="copyHtml" :style="float"></div> -->
            </div>
        </div>
        <el-empty
            v-else
            :image-size="50"
            :image="require('../img/emity-box.png')"
            description="暂无数据"
        ></el-empty>
    </div>
</template>

<script>
import vueSeamlessScroll from 'vue-seamless-scroll'

export default {
    name: 'Example01Basic',
    props: {
        titleList: {
            type: Array,
            default: () => [
                {key: 'type', name: '类型'},
                {key: 'num', name: '数量'},
                {key: 'online', name: '在线'},
                {key: 'offine', name: '离线', color: 'red'},
                {key: 'fault', name: '故障', color: 'green'},
            ],
        },
        data: {
            type: Array,
            // default: () => [
            //     {
            //         type: '车辆载荷',
            //         num: '50',
            //         online: '20',
            //         offine: '20',
            //         fault: '10',
            //     },
            //     {
            //         type: '风速/风向',
            //         num: '50',
            //         online: '20',
            //         offine: '20',
            //         fault: '10',
            //     },
            //     {
            //         type: '地震',
            //         num: '50',
            //         online: '20',
            //         offine: '20',
            //         fault: '10',
            //     },
            //     {
            //         type: '结构温度',
            //         num: '50',
            //         online: '20',
            //         offine: '20',
            //         fault: '10',
            //     },
            //     {
            //         type: '钢结构件温度',
            //         num: '50',
            //         online: '20',
            //         offine: '20',
            //         fault: '10',
            //     },
            //     {
            //         type: '地震',
            //         num: '50',
            //         online: '20',
            //         offine: '20',
            //         fault: '10',
            //     },
            // ],
            default: () => [],
        },
        limitMoveNum: {
            type: Number,
            default: 5,
        },
        classOption: {
            type: Object,
            default: () => {
                return {
                    step: 0.2, // 数值越大速度滚动越快
                    // limitMoveNum: 5, // 开始无缝滚动的数据量 this.dataList.length
                    hoverStop: true, // 是否开启鼠标悬停stop
                    direction: 1, // 0向下 1向上 2向左 3向右
                    openWatch: true, // 开启数据实时监控刷新dom
                    singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
                    singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
                    waitTime: 1000, // 单步运动停止的时间(默认值1000ms)
                }
            },
        },
    },
    components: {
        vueSeamlessScroll,
    },
    data() {
        return {
            xPos: 0,
            yPos: 0,
            delay: 0,
            copyHtml: '',
            height: 0,
            width: 0, // 外容器宽度
            realBoxWidth: 0, // 内容实际宽度
            isMousewheel: false, //是否在执行滑动才做。加这个是为了阻止 滑动到底部的时候直接回到顶部
        }
    },
    computed: {
        // optionSingleHeightTime() {
        //     return {
        //         step: 0.2,
        //         // loop: false,
        //         limitMoveNum: 5,
        //         // waitTime: 2000,
        //         // singleHeight: 1,
        //         // pause: false,
        //     }
        // },
        float() {
            return this.isHorizontal
                ? {float: 'left', overflow: 'hidden'}
                : {overflow: 'hidden'}
        },
        pos() {
            return {
                transform: `translate(${this.xPos}px,${this.yPos}px)`,
                transition: `all ${this.ease} ${this.delay}ms`,
                overflow: 'hidden',
            }
        },
        defaultOption() {
            return {
                step: 1, //步长
                limitMoveNum: 5, //启动无缝滚动最小数据数
                hoverStop: true, //是否启用鼠标hover控制
                direction: 1, // 0 往下 1 往上 2向左 3向右
                openTouch: true, //开启移动端touch
                singleHeight: 0, //单条数据高度有值hoverStop关闭
                singleWidth: 0, //单条数据宽度有值hoverStop关闭
                waitTime: 1000, //单步停止等待时间
                switchOffset: 30,
                autoPlay: true,
                navigation: false,
                switchSingleStep: 134,
                switchDelay: 400,
                switchDisabledClass: 'disabled',
                isSingleRemUnit: false, // singleWidth/singleHeight 是否开启rem度量
            }
        },
        options() {
            this.defaultOption.limitMoveNum = this.limitMoveNum
            return Object.assign({}, this.defaultOption, this.classOption)
            // return copyObj({}, this.defaultOption, this.classOption)
        },
        navigation() {
            return this.options.navigation
        },
        autoPlay() {
            if (this.navigation) return false
            return this.options.autoPlay
        },
        scrollSwitch() {
            return this.data.length >= this.options.limitMoveNum
        },
        hoverStopSwitch() {
            return this.options.hoverStop && this.autoPlay && this.scrollSwitch
        },
        canTouchScroll() {
            return this.options.openTouch
        },
        isHorizontal() {
            return this.options.direction > 1
        },
        baseFontSize() {
            return this.options.isSingleRemUnit
                ? parseInt(
                      window.getComputedStyle(document.documentElement, null).fontSize
                  )
                : 1
        },
        realSingleStopWidth() {
            return this.options.singleWidth * this.baseFontSize
        },
        realSingleStopHeight() {
            return this.options.singleHeight * this.baseFontSize
        },
        step() {
            let singleStep
            let step = this.options.step
            if (this.isHorizontal) {
                singleStep = this.realSingleStopWidth
            } else {
                singleStep = this.realSingleStopHeight
            }
            if (singleStep > 0 && singleStep % step > 0) {
                console.error(
                    '如果设置了单步滚动,step需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确。~~~~~'
                )
            }
            return step
        },
    },
    mounted() {
        this._initMove()
    },
    methods: {
        // myToString(val) {
        //     if (typeof val == 'String') return val
        //     if (val == 0) val = '0'
        //     return val && val.toString()
        // },
        handleItem(key, type) {
            let item = this.data.filter((item) => item[type] == key)[0]
            this.$emit('handleScollItem', item)
        },
        handleSectionClick(e) {
            let target = e.target
            if (target.tagName == 'SPAN') {
                // 根据事件捕获  捕获目标元素节点，执行点击事件
                if (target.dataset.id) {
                    this.handleItem(target.dataset.id, 'id')
                } else {
                    this.handleItem(target.dataset.name, 'name')
                }
            }
        },
        handleScrolls(e) {
            // let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
            // console.log(this.$refs.wrapbox.scrollTop);
            // console.log("高度" + e.target.scrollHeight);
            // console.log("距离上面" + e.target.scrollTop);
            // console.log("元素高度" + e.target.clientHeight);
            // 距离底部 let scrollBottom = e.target.scrollHeight - e.target.scrollTop - e.target.clientHeight;
            this.yPos = -e.target.scrollTop
            // this.$refs.wrapbox.scrollTop = e.target.scrollTop;
        },
        wrapboxWheel(e) {
            const scrollTop = this.$refs.wrapbox.scrollTop
            if (scrollTop < 1 && e.wheelDeltaY > 0) {
                this.$refs.wrapbox.scrollTop = Math.abs(this.yPos)
            }
        },
        arrayEqual(arr1, arr2) {
            if (arr1 === arr2) return true
            if (arr1.length !== arr2.length) return false
            for (let i = 0; i < arr1.length; ++i) {
                if (arr1[i] !== arr2[i]) return false
            }
            return true
        },
        reset() {
            this._cancle()
            this._initMove()
        },
        leftSwitchClick() {
            if (!this.leftSwitchState) return
            // 小于单步距离
            if (Math.abs(this.xPos) < this.options.switchSingleStep) {
                this.xPos = 0
                return
            }
            this.xPos += this.options.switchSingleStep
        },
        rightSwitchClick() {
            if (!this.rightSwitchState) return
            // 小于单步距离
            if (
                this.realBoxWidth - this.width + this.xPos <
                this.options.switchSingleStep
            ) {
                this.xPos = this.width - this.realBoxWidth
                return
            }
            this.xPos -= this.options.switchSingleStep
        },
        _cancle() {
            cancelAnimationFrame(this.reqFrame || '')
        },
        touchStart(e) {
            if (!this.canTouchScroll) return
            let timer
            const touch = e.targetTouches[0] //touches数组对象获得屏幕上所有的touch，取第一个touch
            const {waitTime, singleHeight, singleWidth} = this.options
            this.startPos = {
                x: touch.pageX,
                y: touch.pageY,
            } //取第一个touch的坐标值
            this.startPosY = this.yPos //记录touchStart时候的posY
            this.startPosX = this.xPos //记录touchStart时候的posX
            if (!!singleHeight && !!singleWidth) {
                if (timer) clearTimeout(timer)
                timer = setTimeout(() => {
                    this._cancle()
                }, waitTime + 20)
            } else {
                this._cancle()
            }
        },
        touchMove(e) {
            //当屏幕有多个touch或者页面被缩放过，就不执行move操作
            if (
                !this.canTouchScroll ||
                e.targetTouches.length > 1 ||
                (e.scale && e.scale !== 1)
            )
                return
            const touch = e.targetTouches[0]
            const {direction} = this.options
            this.endPos = {
                x: touch.pageX - this.startPos.x,
                y: touch.pageY - this.startPos.y,
            }
            event.preventDefault() //阻止触摸事件的默认行为，即阻止滚屏
            const dir = Math.abs(this.endPos.x) < Math.abs(this.endPos.y) ? 1 : 0 //dir，1表示纵向滑动，0为横向滑动
            if (dir === 1 && direction < 2) {
                // 表示纵向滑动 && 运动方向为上下
                this.yPos = this.startPosY + this.endPos.y
            } else if (dir === 0 && direction > 1) {
                // 为横向滑动 && 运动方向为左右
                this.xPos = this.startPosX + this.endPos.x
            }
        },
        touchEnd() {
            if (!this.canTouchScroll) return
            let timer
            const direction = this.options.direction
            this.delay = 50
            if (direction === 1) {
                if (this.yPos > 0) this.yPos = 0
            } else if (direction === 0) {
                let h = (this.realBoxHeight / 2) * -1
                if (this.yPos < h) this.yPos = h
            } else if (direction === 2) {
                if (this.xPos > 0) this.xPos = 0
            } else if (direction === 3) {
                let w = this.realBoxWidth * -1
                if (this.xPos < w) this.xPos = w
            }
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                this.delay = 0
                this._move()
            }, this.delay)
        },
        enter() {
            if (this.hoverStopSwitch) this._stopMove()
        },
        leave() {
            this.isMousewheel = false
            if (this.hoverStopSwitch) this._startMove()
        },
        wheel(envent) {
            if (this.data.length < this.options.limitMoveNum) {
                return false
            }
            this.isMousewheel = true
            const h = this.realBoxHeight / 2
            const tranh = h * -1 - 120
            if (envent.wheelDeltaY > 0) {
                this.yPos += 120
                //向上滑动 数值应该更大
                const ys = this.yPos + 120
                if (ys > 20) {
                    this.yPos = 20
                } else {
                    this.yPos += 120
                }
            } else {
                //向下滑动  数值应该更小
                const ys = this.yPos - 120
                if (Math.abs(ys) < h) {
                    this.yPos -= 120
                }
            }
        },
        _move() {
            // 鼠标移入时拦截_move()
            if (this.isHover) return
            if (this.isMousewheel) {
                this._cancle()
                return
            }
            this._cancle() //进入move立即先清除动画 防止频繁touchMove导致多动画同时进行
            this.reqFrame = requestAnimationFrame(
                function () {
                    const h = this.realBoxHeight / 2 //实际高度
                    const w = this.realBoxWidth / 2 //宽度
                    let {direction, waitTime} = this.options
                    let {step} = this
                    // console.log('还是水水水水')
                    // console.log(this.yPos)
                    // console.log(h)
                    if (direction === 1) {
                        // 上
                        if (Math.abs(this.yPos) >= h) {
                            this.$emit('ScrollEnd')
                            this.$refs.wrapbox && (this.$refs.wrapbox.scrollTop = 0)
                            this.yPos = 0
                        }
                        this.yPos -= step
                    } else if (direction === 0) {
                        // 下
                        if (this.yPos >= 0) {
                            this.$emit('ScrollEnd')
                            this.yPos = h * -1
                        }
                        this.yPos += step
                    } else if (direction === 2) {
                        // 左
                        if (Math.abs(this.xPos) >= w) {
                            this.$emit('ScrollEnd')
                            this.xPos = 0
                        }
                        this.xPos -= step
                    } else if (direction === 3) {
                        // 右
                        if (this.xPos >= 0) {
                            this.$emit('ScrollEnd')
                            this.xPos = w * -1
                        }
                        this.xPos += step
                    }
                    if (this.singleWaitTime) clearTimeout(this.singleWaitTime)
                    if (!!this.realSingleStopHeight) {
                        //是否启动了单行暂停配置
                        if (Math.abs(this.yPos) % this.realSingleStopHeight < step) {
                            // 符合条件暂停waitTime
                            this.singleWaitTime = setTimeout(() => {
                                this._move()
                            }, waitTime)
                        } else {
                            this._move()
                        }
                    } else if (!!this.realSingleStopWidth) {
                        if (Math.abs(this.xPos) % this.realSingleStopWidth < step) {
                            // 符合条件暂停waitTime
                            this.singleWaitTime = setTimeout(() => {
                                this._move()
                            }, waitTime)
                        } else {
                            this._move()
                        }
                    } else {
                        this._move()
                    }
                }.bind(this)
            )
        },
        _initMove() {
            this.$nextTick(() => {
                const {switchDelay} = this.options
                const {autoPlay, isHorizontal} = this
                this._dataWarm(this.data)
                this.copyHtml = '' //清空copy
                if (isHorizontal) {
                    this.height = this.$refs.wrap.offsetHeight
                    this.width = this.$refs.wrap.offsetWidth
                    let slotListWidth = this.$refs.slotList.offsetWidth
                    // 水平滚动设置warp width
                    if (autoPlay) {
                        // 修正offsetWidth四舍五入
                        slotListWidth = slotListWidth * 2 + 1
                    }
                    this.$refs.realBox.style.width = slotListWidth + 'px'
                    this.realBoxWidth = slotListWidth
                }

                if (autoPlay) {
                    this.ease = 'ease-in'
                    this.delay = 0
                } else {
                    this.ease = 'linear'
                    this.delay = switchDelay
                    return
                }

                // 是否可以滚动判断
                if (this.scrollSwitch) {
                    let timer
                    if (timer) clearTimeout(timer)
                    this.copyHtml = this.$refs.slotList.innerHTML
                    setTimeout(() => {
                        this.realBoxHeight = this.$refs.realBox.offsetHeight
                        this._move()
                    }, 0)
                } else {
                    this._cancle()
                    this.yPos = this.xPos = 0
                }
            })
        },
        _dataWarm(data) {
            if (data.length > 100) {
                console.warn(
                    `数据达到了${data.length}条有点多哦~,可能会造成部分老旧浏览器卡顿。`
                )
            }
        },
        _startMove() {
            this.isHover = false //开启_move
            this._move()
        },
        _stopMove() {
            this.isHover = true //关闭_move
            // 防止频频hover进出单步滚动,导致定时器乱掉
            if (this.singleWaitTime) clearTimeout(this.singleWaitTime)
            this._cancle()
        },
    },
    watch: {
        data(newData, oldData) {
            this._dataWarm(newData)
            //监听data是否有变更
            if (!this.arrayEqual(newData, oldData)) {
                this.reset()
            }
        },
        autoPlay(bol) {
            if (bol) {
                this.reset()
            } else {
                this._stopMove()
            }
        },
    },
    beforeCreate() {
        this.reqFrame = null // move动画的animationFrame定时器
        this.singleWaitTime = null // single 单步滚动的定时器
        this.isHover = false // mouseenter mouseleave 控制this._move()的开关
        this.ease = 'ease-in'
    },
    beforeDestroy() {
        this._cancle()
        clearTimeout(this.singleWaitTime)
        // window.addEventListener("scroll", this.handleScrolls, false);
    },
}
</script>

<style lang="scss" scoped>
i {
    font-style: normal;
    display: flex;
    // align-items: center;
    // justify-content: center;
}
p {
    margin: 0;
    padding: 0;
    width: 100%;
}
li {
    padding: 5px;
    border-top: 1px solid #1d3a56;
    border-bottom: 1px solid #1d3a56;
}
li:hover {
    cursor: pointer;
}
.icon {
    display: block;
    width: 7px;
    height: 7px;
    transform: rotate(45deg);
    margin-right: 8px;
}
.hideLengthText {
    //width: 400px; /*要显示文字的宽度*/
    text-overflow: ellipsis; /*让截断的文字显示为点点。还有一个值是clip意截断不显示点点*/
    white-space: nowrap; /*让文字不换行*/
    overflow: hidden; /*超出要隐藏*/
}
// .warp ul span[data-v-05ffe0ce] {
//     text-align: start;
// }
.warp ul li[data-v-05ffe0ce] > span:first-child {
    text-align: left; /* 左对齐第一个span */
}
.table {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    .table-title {
        display: flex;
        padding: 10px 5px;
        background: linear-gradient(
            90deg,
            rgba(10, 31, 51, 0.2) 0%,
            #003366 50%,
            rgba(10, 31, 51, 0.2) 100%
        );
        border: 1px solid;
        border-image: linear-gradient(
                90deg,
                rgba(51.00000075995922, 153.00000607967377, 255, 0),
                rgba(178.49999696016312, 216.75006687641144, 255, 0.20000000298023224),
                rgba(51.00000075995922, 153.00000607967377, 255, 0)
            )
            1 1;
        span {
            flex: 1;
            line-height: 18px;
            font-size: 14px;
            text-align: center;
            color: #afd1f1;
        }
    }
}
.wrapper {
    flex: 1;
    width: 100%;
    margin: 0 auto;
    overflow: hidden;
}
.warp {
    width: 100%;
    margin: 0 auto;
    overflow: hidden;
    ul {
        list-style: none;
        padding: 0;
        margin: 0 auto;
        li,
        a {
            display: block;
            height: 30px;
            line-height: 30px;
            display: flex;
            // justify-content: space-between;
            font-size: 15px;
        }
        span {
            flex: 1;
            color: #afd1f1;
            text-align: center;
            font-size: 14px;
        }
        .red {
            color: #ef0f2e;
        }
        .icon-red {
            background-color: #ef0f2e;
        }
        .green {
            color: #1affd9;
        }
        .icon-green {
            background-color: #1affd9;
        }
        .yellow {
            color: #ff9a00;
        }
        .icon-yellow {
            background-color: #ff9a00;
        }
        .blue {
            color: #ffea80;
        }
        .icon-blue {
            background-color: #ffea80;
        }
    }
}
</style>
