|
|
@@ -1,7 +1,13 @@
|
|
|
<template>
|
|
|
- <div class="nut-marquee" :style="mainCss" ref="marquee">
|
|
|
+ <div class="nut-marquee" :style="mainCss" ref="marquee"
|
|
|
+ @mouseover="mouseover"
|
|
|
+ @mouseout="mouseout"
|
|
|
+ @touchenter="clickStop"
|
|
|
+ @touchleave="clickRun">
|
|
|
<div class="nut-marquee-wrapper" ref='wrap'>
|
|
|
- <slot></slot>
|
|
|
+ <!-- <div class="nut-marquee-item"> -->
|
|
|
+ <slot></slot>
|
|
|
+ <!-- </div> -->
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -10,7 +16,7 @@ export default {
|
|
|
name: 'nut-marquee',
|
|
|
props: {
|
|
|
speed: {
|
|
|
- default: 10,
|
|
|
+ default: 30,
|
|
|
type: Number
|
|
|
},
|
|
|
height: {
|
|
|
@@ -36,6 +42,7 @@ export default {
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ interval: null,
|
|
|
mainCss: {},
|
|
|
offset: {
|
|
|
x: 0,
|
|
|
@@ -48,8 +55,8 @@ export default {
|
|
|
wrap: {
|
|
|
height: 0,
|
|
|
width: 0
|
|
|
- }
|
|
|
-
|
|
|
+ },
|
|
|
+ realGap: 0
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
@@ -65,31 +72,95 @@ export default {
|
|
|
},
|
|
|
methods: {
|
|
|
init() {
|
|
|
- this.initPosition();
|
|
|
//尺寸不需要启动轮播滚动。
|
|
|
+ this.initStyle();
|
|
|
+ this.initWH();
|
|
|
if(!this.needRoll()) return;
|
|
|
+ this.createShadowDom();
|
|
|
+ this.initPosition();
|
|
|
+ this.initOffset();
|
|
|
this.start();
|
|
|
},
|
|
|
- initPosition() {
|
|
|
+ //获取出事高度,以便判断是否需要开启轮播功能。
|
|
|
+ initWH() {
|
|
|
this.marquee = {
|
|
|
height: this.$refs.marquee.clientHeight,
|
|
|
width: this.$refs.marquee.clientWidth
|
|
|
- }
|
|
|
+ }
|
|
|
this.wrap = {
|
|
|
height: this.$refs.wrap.clientHeight,
|
|
|
width: this.$refs.wrap.clientWidth
|
|
|
}
|
|
|
+ },
|
|
|
+ initGap() {
|
|
|
+ //如果传入的为rem
|
|
|
+ if(this.gap.indexOf('rem') > -1) {
|
|
|
+ this.realGap = document.getElementsByTagName("html")[0].style.fontSize.replace('px', '')*this.gap.replace('rem', '');
|
|
|
+ }else if(this.gap.indexOf('px') > -1) {
|
|
|
+ this.realGap = this.gap.replace('px', '');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ initStyle() {
|
|
|
+ let nodes = this.$refs.wrap.children;
|
|
|
+ for(let i = 0; i < nodes.length; i++) {
|
|
|
+ nodes[i].className += ' nut-marquee-item';
|
|
|
+ if(this.direction === 'horizontal') {
|
|
|
+ nodes[i].style.setProperty('margin', `0 ${this.gap}`);
|
|
|
+ nodes[i].style.setProperty('display', `inline`);
|
|
|
+ }else {
|
|
|
+ nodes[i].style.setProperty('margin', `${this.gap} 0`);
|
|
|
+ nodes[i].style.setProperty('display', `block`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ initPosition() {
|
|
|
+ this.marquee = {
|
|
|
+ height: this.$refs.marquee.clientHeight,
|
|
|
+ width: this.$refs.marquee.clientWidth
|
|
|
+ }
|
|
|
+ if(this.direction == 'horizontal') {
|
|
|
+ this.wrap = {
|
|
|
+ height: this.$refs.wrap.clientHeight / 2,
|
|
|
+ width: this.$refs.wrap.clientWidth / 2
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ this.wrap = {
|
|
|
+ height: this.$refs.wrap.clientHeight / 2,
|
|
|
+ width: this.$refs.wrap.clientWidth / 2
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
this.offset.x = this.marquee.width;
|
|
|
this.offset.y = this.marquee.height;
|
|
|
|
|
|
},
|
|
|
+ initOffset() {
|
|
|
+ if(!this.reverse) return;
|
|
|
+ if(this.direction == 'horizontal'){
|
|
|
+ this.offset.x = - this.wrap.width*2;
|
|
|
+ }else{
|
|
|
+ this.offset.y = -this.wrap.height*2;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mouseover() {
|
|
|
+ clearInterval(this.interval);
|
|
|
+ },
|
|
|
+ mouseout() {
|
|
|
+ this.start();
|
|
|
+ },
|
|
|
+ clickStop() {
|
|
|
+ clearInterval(this.interval);
|
|
|
+ },
|
|
|
+ clickRun() {
|
|
|
+ this.start();
|
|
|
+ },
|
|
|
start() {
|
|
|
if(['horizontal', 'vertical'].indexOf(this.direction) == -1) console.warn('参数direction有误,执行默认配置horizontal');
|
|
|
if(this.direction === 'vertical') {
|
|
|
this.startVertical();
|
|
|
} else {
|
|
|
this.startHorizontal();
|
|
|
- }
|
|
|
+ }
|
|
|
},
|
|
|
//判断是否需要滚动
|
|
|
needRoll() {
|
|
|
@@ -109,7 +180,6 @@ export default {
|
|
|
|
|
|
///启动水平滚动,水平滚动处理区域
|
|
|
startHorizontal() {
|
|
|
- this.createShadowDom();
|
|
|
if(!this.reverse) {
|
|
|
this.normalHorizontalRoll();
|
|
|
}else {
|
|
|
@@ -120,9 +190,9 @@ export default {
|
|
|
normalHorizontalRoll() {
|
|
|
let _self = this;
|
|
|
let width = this.wrap.width;
|
|
|
- setInterval(function() {
|
|
|
+ _self.interval = setInterval(function() {
|
|
|
_self.setTransform(_self.$refs.wrap, `translate3d(${_self.offset.x}px, 0, 0)`);
|
|
|
- _self.offset.x = _self.offset.x - 1 ;
|
|
|
+ _self.offset.x = _self.offset.x - 1;
|
|
|
if(-(_self.offset.x) > width) {
|
|
|
_self.offset.x = 0;
|
|
|
}
|
|
|
@@ -130,11 +200,18 @@ export default {
|
|
|
},
|
|
|
//横向反向模式运动
|
|
|
reverseHorizontalRoll() {
|
|
|
-
|
|
|
+ let _self = this;
|
|
|
+ let width = this.wrap.width;
|
|
|
+ _self.interval = setInterval(function() {
|
|
|
+ _self.setTransform(_self.$refs.wrap, `translate3d(${_self.offset.x}px, 0, 0)`);
|
|
|
+ _self.offset.x = _self.offset.x + 1 ;
|
|
|
+ if((_self.offset.x) > 0) {
|
|
|
+ _self.offset.x = - width;
|
|
|
+ }
|
|
|
+ }, this.speed)
|
|
|
},
|
|
|
//启动垂直滚动
|
|
|
startVertical() {
|
|
|
- this.createShadowDom();
|
|
|
if(!this.reverse) {
|
|
|
this.normalVerticalRoll();
|
|
|
}else {
|
|
|
@@ -145,17 +222,25 @@ export default {
|
|
|
normalVerticalRoll() {
|
|
|
let _self = this;
|
|
|
let height = this.wrap.height;
|
|
|
- setInterval(function() {
|
|
|
+ _self.interval = setInterval(function() {
|
|
|
_self.setTransform(_self.$refs.wrap, `translate3d(0, ${_self.offset.y}px, 0)`);
|
|
|
_self.offset.y = _self.offset.y - 1 ;
|
|
|
if(-(_self.offset.y) > height) {
|
|
|
- _self.offset.y = _self.marquee.height;
|
|
|
+ _self.offset.y = 0 - (_self.realGap/2);
|
|
|
}
|
|
|
}, this.speed)
|
|
|
},
|
|
|
//垂直反向模式运动
|
|
|
reverseVerticalRoll() {
|
|
|
-
|
|
|
+ let _self = this;
|
|
|
+ let height = this.wrap.height;
|
|
|
+ _self.interval = setInterval(function() {
|
|
|
+ _self.setTransform(_self.$refs.wrap, `translate3d(0, ${_self.offset.y}px, 0)`);
|
|
|
+ _self.offset.y = _self.offset.y + 1 ;
|
|
|
+ if(-(_self.offset.y) < 0) {
|
|
|
+ _self.offset.y = - height + (_self.realGap);
|
|
|
+ }
|
|
|
+ }, this.speed)
|
|
|
},
|
|
|
/*
|
|
|
* 功能操作区
|
|
|
@@ -170,26 +255,19 @@ export default {
|
|
|
//无限模式中,创建dom来保证2次之间的衔接
|
|
|
createShadowDom(el) {
|
|
|
let con = this.$refs.wrap;
|
|
|
- let childNodes = this.$refs.wrap.children;
|
|
|
- console.log(this.$refs.wrap.children);
|
|
|
- for(let i =0; i < childNodes.length; i++) {
|
|
|
- let node = childNodes[i];
|
|
|
- con.appendChild(node.cloneNode(true));
|
|
|
- }
|
|
|
- return;
|
|
|
- if(!this.reverse == 'horizontal') {
|
|
|
- let firstItem = this.$refs.wrap.firstElementChild;
|
|
|
- console.log(this.$refs.wrap);
|
|
|
- let cloneNode = firstItem.cloneNode(true);
|
|
|
- cloneNode.style.setProperty('margin-left', this.gap);
|
|
|
- con.appendChild(cloneNode);
|
|
|
- }else {
|
|
|
- let lastItem = this.$refs.wrap.lastElementChild;
|
|
|
- let firstItem = this.$refs.wrap.firstElementChild;
|
|
|
- let cloneNode = lastItem.cloneNode(true);
|
|
|
- cloneNode.style.setProperty('margin-right', this.gap);
|
|
|
- con.insertBefore(cloneNode, firstItem);
|
|
|
+ let childNodes = this.cloneNodes(this.$refs.wrap.children);
|
|
|
+ for(let i =0; i < childNodes.length; i++) {
|
|
|
+ let node = childNodes[i];
|
|
|
+ con.appendChild(node);
|
|
|
}
|
|
|
+ },
|
|
|
+ cloneNodes(nodes) {
|
|
|
+ let destNodes = [];
|
|
|
+ for(let i = 0; i < nodes.length; i++) {
|
|
|
+ nodes[i].className += ' nut-marquee-item';
|
|
|
+ destNodes.push(nodes[i].cloneNode(true));
|
|
|
+ }
|
|
|
+ return destNodes;
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -199,9 +277,18 @@ export default {
|
|
|
<style lang='scss'>
|
|
|
.nut-marquee {
|
|
|
overflow: hidden;
|
|
|
+ width: 100%;
|
|
|
+ white-space: nowrap;
|
|
|
+ height: inherit;
|
|
|
}
|
|
|
.nut-marquee-wrapper {
|
|
|
- white-space: nowrap;
|
|
|
+ display: inline-block;
|
|
|
+ overflow: hidden;
|
|
|
transition: transform 0ms linear;
|
|
|
}
|
|
|
+ .nut-marquee-item {
|
|
|
+ outline: none;
|
|
|
+ overflow: hidden;
|
|
|
+ margin: 0 10px;
|
|
|
+ }
|
|
|
</style>
|