forked from liweijie/education
1 line
12 KiB
JSON
1 line
12 KiB
JSON
{"remainingRequest":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\layout\\components\\TagsView\\ScrollPane.vue?vue&type=script&lang=js","dependencies":[{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\layout\\components\\TagsView\\ScrollPane.vue","mtime":1787567871547},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\cache-loader\\dist\\cjs.js","mtime":1787309791955},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\babel-loader\\lib\\index.js","mtime":1787309793142},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\cache-loader\\dist\\cjs.js","mtime":1787309791955},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\index.js","mtime":1787309793790}],"contextDependencies":[],"result":[{"type":"Buffer","data":"base64:Ly8KLy8KLy8KLy8KLy8KLy8KDQpjb25zdCB0YWdBbmRUYWdTcGFjaW5nID0gNA0KDQpleHBvcnQgZGVmYXVsdCB7DQogIG5hbWU6ICdTY3JvbGxQYW5lJywNCiAgZGF0YSgpIHsNCiAgICByZXR1cm4gew0KICAgICAgbGVmdDogMA0KICAgIH0NCiAgfSwNCiAgY29tcHV0ZWQ6IHsNCiAgICBzY3JvbGxXcmFwcGVyKCkgew0KICAgICAgcmV0dXJuIHRoaXMuJHJlZnMuc2Nyb2xsQ29udGFpbmVyLiRyZWZzLndyYXANCiAgICB9DQogIH0sDQogIG1vdW50ZWQoKSB7DQogICAgdGhpcy5zY3JvbGxXcmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuZW1pdFNjcm9sbCwgdHJ1ZSkNCiAgfSwNCiAgYmVmb3JlRGVzdHJveSgpIHsNCiAgICB0aGlzLnNjcm9sbFdyYXBwZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5lbWl0U2Nyb2xsKQ0KICB9LA0KICBtZXRob2RzOiB7DQogICAgc21vb3RoU2Nyb2xsVG8odGFyZ2V0KSB7DQogICAgICBjb25zdCAkc2Nyb2xsV3JhcHBlciA9IHRoaXMuc2Nyb2xsV3JhcHBlcg0KICAgICAgY29uc3Qgc3RhcnQgPSAkc2Nyb2xsV3JhcHBlci5zY3JvbGxMZWZ0DQogICAgICBjb25zdCBkaXN0YW5jZSA9IHRhcmdldCAtIHN0YXJ0DQogICAgICBjb25zdCBkdXJhdGlvbiA9IDMwMA0KICAgICAgbGV0IHN0YXJ0VGltZSA9IG51bGwNCg0KICAgICAgZnVuY3Rpb24gZWFzZSh0LCBiLCBjLCBkKSB7DQogICAgICAgIHQgLz0gZCAvIDINCiAgICAgICAgaWYgKHQgPCAxKSByZXR1cm4gYyAvIDIgKiB0ICogdCArIGINCiAgICAgICAgdC0tDQogICAgICAgIHJldHVybiAtYyAvIDIgKiAodCAqICh0IC0gMikgLSAxKSArIGINCiAgICAgIH0NCg0KICAgICAgY29uc3QgZW1pdCA9IHRoaXMuJGVtaXQuYmluZCh0aGlzKQ0KICAgICAgZnVuY3Rpb24gc3RlcCh0aW1lc3RhbXApIHsNCiAgICAgICAgaWYgKCFzdGFydFRpbWUpIHN0YXJ0VGltZSA9IHRpbWVzdGFtcA0KICAgICAgICBjb25zdCBlbGFwc2VkID0gdGltZXN0YW1wIC0gc3RhcnRUaW1lDQogICAgICAgICRzY3JvbGxXcmFwcGVyLnNjcm9sbExlZnQgPSBlYXNlKGVsYXBzZWQsIHN0YXJ0LCBkaXN0YW5jZSwgZHVyYXRpb24pDQogICAgICAgIGlmIChlbGFwc2VkIDwgZHVyYXRpb24pIHsNCiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoc3RlcCkNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAkc2Nyb2xsV3JhcHBlci5zY3JvbGxMZWZ0ID0gdGFyZ2V0DQogICAgICAgICAgZW1pdCgndXBkYXRlQXJyb3dzJykNCiAgICAgICAgfQ0KICAgICAgfQ0KDQogICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoc3RlcCkNCiAgICB9LA0KICAgIGhhbmRsZVNjcm9sbChlKSB7DQogICAgICBjb25zdCBldmVudERlbHRhID0gZS53aGVlbERlbHRhIHx8IC1lLmRlbHRhWSAqIDQwDQogICAgICBjb25zdCAkc2Nyb2xsV3JhcHBlciA9IHRoaXMuc2Nyb2xsV3JhcHBlcg0KICAgICAgJHNjcm9sbFdyYXBwZXIuc2Nyb2xsTGVmdCA9ICRzY3JvbGxXcmFwcGVyLnNjcm9sbExlZnQgKyBldmVudERlbHRhIC8gNA0KICAgICAgdGhpcy4kZW1pdCgndXBkYXRlQXJyb3dzJykNCiAgICB9LA0KICAgIGVtaXRTY3JvbGwoKSB7DQogICAgICB0aGlzLiRlbWl0KCdzY3JvbGwnKQ0KICAgICAgdGhpcy4kZW1pdCgndXBkYXRlQXJyb3dzJykNCiAgICB9LA0KICAgIG1vdmVUb1RhcmdldChjdXJyZW50VGFnKSB7DQogICAgICBjb25zdCAkY29udGFpbmVyID0gdGhpcy4kcmVmcy5zY3JvbGxDb250YWluZXIuJGVsDQogICAgICBjb25zdCAkY29udGFpbmVyV2lkdGggPSAkY29udGFpbmVyLm9mZnNldFdpZHRoDQogICAgICBjb25zdCAkc2Nyb2xsV3JhcHBlciA9IHRoaXMuc2Nyb2xsV3JhcHBlcg0KICAgICAgY29uc3QgdGFnTGlzdCA9IHRoaXMuJHBhcmVudC4kcmVmcy50YWcNCg0KICAgICAgbGV0IGZpcnN0VGFnID0gbnVsbA0KICAgICAgbGV0IGxhc3RUYWcgPSBudWxsDQoNCiAgICAgIGlmICh0YWdMaXN0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgZmlyc3RUYWcgPSB0YWdMaXN0WzBdDQogICAgICAgIGxhc3RUYWcgPSB0YWdMaXN0W3RhZ0xpc3QubGVuZ3RoIC0gMV0NCiAgICAgIH0NCg0KICAgICAgaWYgKGZpcnN0VGFnID09PSBjdXJyZW50VGFnKSB7DQogICAgICAgIHRoaXMuc21vb3RoU2Nyb2xsVG8oMCkNCiAgICAgIH0gZWxzZSBpZiAobGFzdFRhZyA9PT0gY3VycmVudFRhZykgew0KICAgICAgICB0aGlzLnNtb290aFNjcm9sbFRvKCRzY3JvbGxXcmFwcGVyLnNjcm9sbFdpZHRoIC0gJGNvbnRhaW5lcldpZHRoKQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGFnTGlzdC5maW5kSW5kZXgoaXRlbSA9PiBpdGVtID09PSBjdXJyZW50VGFnKQ0KICAgICAgICBjb25zdCBwcmV2VGFnID0gdGFnTGlzdFtjdXJyZW50SW5kZXggLSAxXQ0KICAgICAgICBjb25zdCBuZXh0VGFnID0gdGFnTGlzdFtjdXJyZW50SW5kZXggKyAxXQ0KICAgICAgICBjb25zdCBhZnRlck5leHRUYWdPZmZzZXRMZWZ0ID0gbmV4dFRhZy4kZWwub2Zmc2V0TGVmdCArIG5leHRUYWcuJGVsLm9mZnNldFdpZHRoICsgdGFnQW5kVGFnU3BhY2luZw0KICAgICAgICBjb25zdCBiZWZvcmVQcmV2VGFnT2Zmc2V0TGVmdCA9IHByZXZUYWcuJGVsLm9mZnNldExlZnQgLSB0YWdBbmRUYWdTcGFjaW5nDQoNCiAgICAgICAgaWYgKGFmdGVyTmV4dFRhZ09mZnNldExlZnQgPiAkc2Nyb2xsV3JhcHBlci5zY3JvbGxMZWZ0ICsgJGNvbnRhaW5lcldpZHRoKSB7DQogICAgICAgICAgdGhpcy5zbW9vdGhTY3JvbGxUbyhhZnRlck5leHRUYWdPZmZzZXRMZWZ0IC0gJGNvbnRhaW5lcldpZHRoKQ0KICAgICAgICB9IGVsc2UgaWYgKGJlZm9yZVByZXZUYWdPZmZzZXRMZWZ0IDwgJHNjcm9sbFdyYXBwZXIuc2Nyb2xsTGVmdCkgew0KICAgICAgICAgIHRoaXMuc21vb3RoU2Nyb2xsVG8oYmVmb3JlUHJldlRhZ09mZnNldExlZnQpDQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9LA0KICAgIC8vIOWQkeW3pua7muWKqOWbuuWumui3neemuw0KICAgIHNjcm9sbExlZnQoKSB7DQogICAgICBjb25zdCAkc2Nyb2xsV3JhcHBlciA9IHRoaXMuc2Nyb2xsV3JhcHBlcg0KICAgICAgdGhpcy5zbW9vdGhTY3JvbGxUbyhNYXRoLm1heCgwLCAkc2Nyb2xsV3JhcHBlci5zY3JvbGxMZWZ0IC0gMjAwKSkNCiAgICB9LA0KICAgIC8vIOWQkeWPs+a7muWKqOWbuuWumui3neemuw0KICAgIHNjcm9sbFJpZ2h0KCkgew0KICAgICAgY29uc3QgJHNjcm9sbFdyYXBwZXIgPSB0aGlzLnNjcm9sbFdyYXBwZXINCiAgICAgIGNvbnN0IG1heFNjcm9sbCA9ICRzY3JvbGxXcmFwcGVyLnNjcm9sbFdpZHRoIC0gJHNjcm9sbFdyYXBwZXIuY2xpZW50V2lkdGgNCiAgICAgIHRoaXMuc21vb3RoU2Nyb2xsVG8oTWF0aC5taW4obWF4U2Nyb2xsLCAkc2Nyb2xsV3JhcHBlci5zY3JvbGxMZWZ0ICsgMjAwKSkNCiAgICB9LA0KICAgIC8vIOebtOaOpeW5s+a7kea7muWKqOWIsOacgOW3puerrw0KICAgIHNjcm9sbFRvU3RhcnQoKSB7DQogICAgICB0aGlzLnNtb290aFNjcm9sbFRvKDApDQogICAgfSwNCiAgICAvLyDnm7TmjqXlubPmu5Hmu5rliqjliLDmnIDlj7Pnq68NCiAgICBzY3JvbGxUb0VuZCgpIHsNCiAgICAgIGNvbnN0ICRzY3JvbGxXcmFwcGVyID0gdGhpcy5zY3JvbGxXcmFwcGVyDQogICAgICB0aGlzLnNtb290aFNjcm9sbFRvKCRzY3JvbGxXcmFwcGVyLnNjcm9sbFdpZHRoIC0gJHNjcm9sbFdyYXBwZXIuY2xpZW50V2lkdGgpDQogICAgfSwNCiAgICAvLyDojrflj5bmmK/lkKblj6/ku6Xnu6fnu63lkJHlt6Yv5Y+z5rua5YqoDQogICAgZ2V0U2Nyb2xsU3RhdGUoKSB7DQogICAgICBjb25zdCAkc2Nyb2xsV3JhcHBlciA9IHRoaXMuc2Nyb2xsV3JhcHBlcg0KICAgICAgcmV0dXJuIHsNCiAgICAgICAgY2FuTGVmdDogJHNjcm9sbFdyYXBwZXIuc2Nyb2xsTGVmdCA+IDAsDQogICAgICAgIGNhblJpZ2h0OiAkc2Nyb2xsV3JhcHBlci5zY3JvbGxMZWZ0IDwgJHNjcm9sbFdyYXBwZXIuc2Nyb2xsV2lkdGggLSAkc2Nyb2xsV3JhcHBlci5jbGllbnRXaWR0aCAtIDENCiAgICAgIH0NCiAgICB9DQogIH0NCn0NCg=="},{"version":3,"sources":["ScrollPane.vue"],"names":[],"mappings":";;;;;;;AAOA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"ScrollPane.vue","sourceRoot":"src/layout/components/TagsView","sourcesContent":["<template>\r\n <el-scrollbar ref=\"scrollContainer\" :vertical=\"false\" class=\"scroll-container\" @wheel.native.prevent=\"handleScroll\">\r\n <slot />\r\n </el-scrollbar>\r\n</template>\r\n\r\n<script>\r\nconst tagAndTagSpacing = 4\r\n\r\nexport default {\r\n name: 'ScrollPane',\r\n data() {\r\n return {\r\n left: 0\r\n }\r\n },\r\n computed: {\r\n scrollWrapper() {\r\n return this.$refs.scrollContainer.$refs.wrap\r\n }\r\n },\r\n mounted() {\r\n this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)\r\n },\r\n beforeDestroy() {\r\n this.scrollWrapper.removeEventListener('scroll', this.emitScroll)\r\n },\r\n methods: {\r\n smoothScrollTo(target) {\r\n const $scrollWrapper = this.scrollWrapper\r\n const start = $scrollWrapper.scrollLeft\r\n const distance = target - start\r\n const duration = 300\r\n let startTime = null\r\n\r\n function ease(t, b, c, d) {\r\n t /= d / 2\r\n if (t < 1) return c / 2 * t * t + b\r\n t--\r\n return -c / 2 * (t * (t - 2) - 1) + b\r\n }\r\n\r\n const emit = this.$emit.bind(this)\r\n function step(timestamp) {\r\n if (!startTime) startTime = timestamp\r\n const elapsed = timestamp - startTime\r\n $scrollWrapper.scrollLeft = ease(elapsed, start, distance, duration)\r\n if (elapsed < duration) {\r\n requestAnimationFrame(step)\r\n } else {\r\n $scrollWrapper.scrollLeft = target\r\n emit('updateArrows')\r\n }\r\n }\r\n\r\n requestAnimationFrame(step)\r\n },\r\n handleScroll(e) {\r\n const eventDelta = e.wheelDelta || -e.deltaY * 40\r\n const $scrollWrapper = this.scrollWrapper\r\n $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4\r\n this.$emit('updateArrows')\r\n },\r\n emitScroll() {\r\n this.$emit('scroll')\r\n this.$emit('updateArrows')\r\n },\r\n moveToTarget(currentTag) {\r\n const $container = this.$refs.scrollContainer.$el\r\n const $containerWidth = $container.offsetWidth\r\n const $scrollWrapper = this.scrollWrapper\r\n const tagList = this.$parent.$refs.tag\r\n\r\n let firstTag = null\r\n let lastTag = null\r\n\r\n if (tagList.length > 0) {\r\n firstTag = tagList[0]\r\n lastTag = tagList[tagList.length - 1]\r\n }\r\n\r\n if (firstTag === currentTag) {\r\n this.smoothScrollTo(0)\r\n } else if (lastTag === currentTag) {\r\n this.smoothScrollTo($scrollWrapper.scrollWidth - $containerWidth)\r\n } else {\r\n const currentIndex = tagList.findIndex(item => item === currentTag)\r\n const prevTag = tagList[currentIndex - 1]\r\n const nextTag = tagList[currentIndex + 1]\r\n const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing\r\n const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing\r\n\r\n if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {\r\n this.smoothScrollTo(afterNextTagOffsetLeft - $containerWidth)\r\n } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {\r\n this.smoothScrollTo(beforePrevTagOffsetLeft)\r\n }\r\n }\r\n },\r\n // 向左滚动固定距离\r\n scrollLeft() {\r\n const $scrollWrapper = this.scrollWrapper\r\n this.smoothScrollTo(Math.max(0, $scrollWrapper.scrollLeft - 200))\r\n },\r\n // 向右滚动固定距离\r\n scrollRight() {\r\n const $scrollWrapper = this.scrollWrapper\r\n const maxScroll = $scrollWrapper.scrollWidth - $scrollWrapper.clientWidth\r\n this.smoothScrollTo(Math.min(maxScroll, $scrollWrapper.scrollLeft + 200))\r\n },\r\n // 直接平滑滚动到最左端\r\n scrollToStart() {\r\n this.smoothScrollTo(0)\r\n },\r\n // 直接平滑滚动到最右端\r\n scrollToEnd() {\r\n const $scrollWrapper = this.scrollWrapper\r\n this.smoothScrollTo($scrollWrapper.scrollWidth - $scrollWrapper.clientWidth)\r\n },\r\n // 获取是否可以继续向左/右滚动\r\n getScrollState() {\r\n const $scrollWrapper = this.scrollWrapper\r\n return {\r\n canLeft: $scrollWrapper.scrollLeft > 0,\r\n canRight: $scrollWrapper.scrollLeft < $scrollWrapper.scrollWidth - $scrollWrapper.clientWidth - 1\r\n }\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.scroll-container {\r\n white-space: nowrap;\r\n position: relative;\r\n overflow: hidden;\r\n width: 100%;\r\n ::v-deep {\r\n .el-scrollbar__bar {\r\n bottom: 0px;\r\n }\r\n .el-scrollbar__wrap {\r\n height: 34px;\r\n display: flex;\r\n align-items: center;\r\n }\r\n }\r\n}\r\n</style>\r\n"]}]} |