Browse Source

补充demo以及文档

杨磊 7 years ago
parent
commit
8b5e8d6ee7
4 changed files with 346 additions and 115 deletions
  1. 35 27
      src/demo/marquee.vue
  2. 124 37
      src/package/marquee/src/marquee.vue
  3. 0 51
      src/package/marquee/src/utils.js
  4. 187 0
      src/view/marquee.vue

+ 35 - 27
src/demo/marquee.vue

@@ -4,34 +4,41 @@
         :name="$route.name"
         :name="$route.name"
         ></nut-demoheader>
         ></nut-demoheader>
         <h5>示例</h5>
         <h5>示例</h5>
-        <p>普通文字横向跑马灯-默认速度</p>
-        <nut-marquee class="demo1" :gap='gap'>
-            <template slot>
-                <div class="txt">我是一个轮播图1</div>
-                <div class="txt">我是一个轮播图2</div>
-                <div class="txt">我是一个轮播图2</div>
-                <div class="txt">我是一个轮播图2</div>
-                <div class="txt">我是一个轮播图2</div>
-                <div class="txt">我是一个轮播图2</div>
-                <div class="txt">我是一个轮播图2</div>
+        <p>水平正向内容跑马灯</p>
+        <nut-marquee class="demo1" :gap='gap' :speed="10">
+            <template slot >
+                <div v-for="(d, idx) in slotDatas" :key='idx' class="txt"><a>www.jd.com</a>{{d}}</div>
             </template>
             </template>
         </nut-marquee>
         </nut-marquee>
-        <p>横向反向</p>
-        <nut-marquee class="demo1" :gap='gap' :reverse="true">
+        <p>水平逆向内容跑马灯</p>
+        <nut-marquee class="demo1" :gap='gap' :reverse="true" :speed='30'>
             <template slot>
             <template slot>
-                <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了</div>
+                <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1</div>
             </template>
             </template>
         </nut-marquee>
         </nut-marquee>
-        <p>纵向内容跑马灯</p>
+        <p>垂直正向内容跑马灯</p>
+        <nut-marquee class="demo1" 
+            :speed='30' 
+            :height="demo3Height" 
+            :direction='v'
+            :gap="gap">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+        </nut-marquee>
+        <p>垂直逆向内容跑马灯</p>
         <nut-marquee class="demo1" 
         <nut-marquee class="demo1" 
-            :speed='20' 
+            :speed='10' 
+            :gap= 'gap'
             :height="demo3Height" 
             :height="demo3Height" 
-            :direction='v'>
-            <div class="txt1">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1</div>
-            <div class="txt1">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了2</div>
+            :direction='v'
+            :reverse="true">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
             <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
             <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
-            <div class="txt1">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了3</div>
-            <div class="txt1">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了4</div>
+            <div class="txt1">我是垂直轮播图3</div>
+            <div class="txt1">我是垂直轮播图4</div>
         </nut-marquee>
         </nut-marquee>
     </div>    
     </div>    
 </template>
 </template>
@@ -41,8 +48,14 @@ export default {
         return {
         return {
             h: '1.2rem',
             h: '1.2rem',
             v: 'vertical',
             v: 'vertical',
-            demo3Height: '1.2rem',
-            gap: '.4rem'
+            demo3Height: '4rem',
+            gap: '.2rem',
+            slotDatas: [
+                '我是轮播图1',
+                '我是轮播图2',
+                '我是轮播图3',
+                '我是轮播图4'
+            ]
         }
         }
     }
     }
 }
 }
@@ -56,13 +69,8 @@ export default {
         width: 80%;
         width: 80%;
     }
     }
     .txt {
     .txt {
-        display: inline;
         line-height: .4rem;
         line-height: .4rem;
-        // margin-right: .4rem;
         white-space: nowrap;
         white-space: nowrap;
     }
     }
-    .txt1 {
-        padding: .1rem;
-    }
 </style>
 </style>
 
 

+ 124 - 37
src/package/marquee/src/marquee.vue

@@ -1,7 +1,13 @@
 <template>
 <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'>
         <div class="nut-marquee-wrapper" ref='wrap'>
-            <slot></slot>
+            <!-- <div class="nut-marquee-item"> -->
+                <slot></slot>
+            <!-- </div> -->
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
@@ -10,7 +16,7 @@ export default {
     name: 'nut-marquee',
     name: 'nut-marquee',
     props: {
     props: {
         speed: {
         speed: {
-            default: 10,
+            default: 30,
             type: Number
             type: Number
         },
         },
         height: {
         height: {
@@ -36,6 +42,7 @@ export default {
     },
     },
     data() {
     data() {
         return {
         return {
+            interval: null,
             mainCss: {},
             mainCss: {},
             offset: {
             offset: {
                 x: 0,
                 x: 0,
@@ -48,8 +55,8 @@ export default {
             wrap: {
             wrap: {
                 height: 0,
                 height: 0,
                 width: 0
                 width: 0
-            }
-
+            },
+            realGap: 0
         }
         }
     },
     },
     created() {
     created() {
@@ -65,31 +72,95 @@ export default {
     },
     },
     methods: {
     methods: {
         init() {
         init() {
-            this.initPosition();
             //尺寸不需要启动轮播滚动。
             //尺寸不需要启动轮播滚动。
+            this.initStyle();
+            this.initWH();
             if(!this.needRoll()) return;
             if(!this.needRoll()) return;
+            this.createShadowDom();
+            this.initPosition();
+            this.initOffset();
             this.start();
             this.start();
         },
         },
-        initPosition() {
+        //获取出事高度,以便判断是否需要开启轮播功能。
+        initWH() {
             this.marquee = {
             this.marquee = {
                 height: this.$refs.marquee.clientHeight,
                 height: this.$refs.marquee.clientHeight,
                 width: this.$refs.marquee.clientWidth
                 width: this.$refs.marquee.clientWidth
-            }          
+            }
             this.wrap = {
             this.wrap = {
                 height: this.$refs.wrap.clientHeight,
                 height: this.$refs.wrap.clientHeight,
                 width: this.$refs.wrap.clientWidth
                 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.x = this.marquee.width;
             this.offset.y = this.marquee.height;
             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() {
         start() {
             if(['horizontal', 'vertical'].indexOf(this.direction) == -1) console.warn('参数direction有误,执行默认配置horizontal');
             if(['horizontal', 'vertical'].indexOf(this.direction) == -1) console.warn('参数direction有误,执行默认配置horizontal');
             if(this.direction === 'vertical') {
             if(this.direction === 'vertical') {
                 this.startVertical();
                 this.startVertical();
             } else {
             } else {
                 this.startHorizontal();
                 this.startHorizontal();
-            }            
+            }
         },
         },
         //判断是否需要滚动
         //判断是否需要滚动
         needRoll() {
         needRoll() {
@@ -109,7 +180,6 @@ export default {
 
 
         ///启动水平滚动,水平滚动处理区域
         ///启动水平滚动,水平滚动处理区域
         startHorizontal() {
         startHorizontal() {
-            this.createShadowDom();
             if(!this.reverse) {
             if(!this.reverse) {
                 this.normalHorizontalRoll();
                 this.normalHorizontalRoll();
             }else {
             }else {
@@ -120,9 +190,9 @@ export default {
         normalHorizontalRoll() {
         normalHorizontalRoll() {
             let _self = this;
             let _self = this;
             let width = this.wrap.width;
             let width = this.wrap.width;
-            setInterval(function() {
+            _self.interval = setInterval(function() {
                 _self.setTransform(_self.$refs.wrap, `translate3d(${_self.offset.x}px, 0, 0)`);
                 _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) {
                 if(-(_self.offset.x) > width) {
                     _self.offset.x = 0;
                     _self.offset.x = 0;
                 }
                 }
@@ -130,11 +200,18 @@ export default {
         },
         },
         //横向反向模式运动
         //横向反向模式运动
         reverseHorizontalRoll() {
         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() {
         startVertical() {
-            this.createShadowDom();
             if(!this.reverse) {
             if(!this.reverse) {
                 this.normalVerticalRoll();
                 this.normalVerticalRoll();
             }else {
             }else {
@@ -145,17 +222,25 @@ export default {
         normalVerticalRoll() {
         normalVerticalRoll() {
             let _self = this;
             let _self = this;
             let height = this.wrap.height;
             let height = this.wrap.height;
-            setInterval(function() {
+            _self.interval = setInterval(function() {
                 _self.setTransform(_self.$refs.wrap, `translate3d(0, ${_self.offset.y}px, 0)`);
                 _self.setTransform(_self.$refs.wrap, `translate3d(0, ${_self.offset.y}px, 0)`);
                 _self.offset.y = _self.offset.y - 1 ;
                 _self.offset.y = _self.offset.y - 1 ;
                 if(-(_self.offset.y) > height) {
                 if(-(_self.offset.y) > height) {
-                    _self.offset.y = _self.marquee.height;
+                    _self.offset.y = 0 - (_self.realGap/2);
                 }
                 }
             }, this.speed)
             }, this.speed)
         },
         },
         //垂直反向模式运动
         //垂直反向模式运动
         reverseVerticalRoll() {
         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次之间的衔接
         //无限模式中,创建dom来保证2次之间的衔接
         createShadowDom(el) {
         createShadowDom(el) {
             let con = this.$refs.wrap;
             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'>
 <style lang='scss'>
     .nut-marquee {
     .nut-marquee {
         overflow: hidden;
         overflow: hidden;
+        width: 100%;
+        white-space: nowrap;
+        height: inherit;
     }
     }
     .nut-marquee-wrapper {
     .nut-marquee-wrapper {
-        white-space: nowrap;
+        display: inline-block;
+        overflow: hidden;
         transition: transform 0ms linear;
         transition: transform 0ms linear;
     }
     }
+    .nut-marquee-item {
+        outline: none;
+        overflow: hidden;
+        margin: 0 10px;
+    }
 </style>
 </style>

+ 0 - 51
src/package/marquee/src/utils.js

@@ -1,51 +0,0 @@
-function insertKeyFrame (rule) {
-    if (document.styleSheets && document.styleSheets.length) {
-      try {
-        document.styleSheets[0].insertRule(rule, 0)
-      } catch (ex) {
-      }
-    } else {
-      var style = document.createElement('style')
-      style.innerHTML = rule
-      document.head.appendChild(style)
-    }
-  }
-  
-  function deleteKeyFrame (ruleName) {
-    var cssrules = (document.all) ? 'rules' : 'cssRules'
-    var i
-    if (document.styleSheets && document.styleSheets.length && document.styleSheets[0][cssrules]) {
-      for (i = 0; i < document.styleSheets[0][cssrules].length; i += 1) {
-        var rule = document.styleSheets[0][cssrules][i]
-        if (rule.name === ruleName || rule.selectorText === '.' + ruleName) {
-          document.styleSheets[0].deleteRule(i)
-          break
-        }
-      }
-    }
-  }
-  
-  function getWidthHeight () {
-    var w = window
-    var d = document
-    var e = d.documentElement
-    var g = d.getElementsByTagName('body')[0]
-    return {
-      width: w.innerWidth || e.clientWidth || g.clientWidth, height: w.innerHeight || e.clientHeight || g.clientHeight
-    }
-  }
-  
-  function getTextWidth (text, font) {
-    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement('canvas'))
-    var context = canvas.getContext('2d')
-    context.font = font
-    var metrics = context.measureText(text)
-    return metrics.width
-  }
-  
-  export {
-    insertKeyFrame,
-    deleteKeyFrame,
-    getWidthHeight,
-    getTextWidth
-  }

+ 187 - 0
src/view/marquee.vue

@@ -0,0 +1,187 @@
+<template>
+    <div>
+        <nut-docheader 
+        :name="$route.name" 
+        :chName="$route.params.chnName" 
+        type="Component" 
+        desc="跑马灯-支持文字以及内容的横向纵向轮播(当内容过少时不启动轮播)" 
+        :showQrCode="true"></nut-docheader>
+        <h5>示例</h5>
+        <h6>水平正向内容跑马灯</h6>
+        <nut-marquee class="demo1" :gap='gap' :speed="10">
+            <template slot >
+                <div v-for="(d, idx) in slotDatas" :key='idx' class="txt"><a>www.jd.com</a>{{d}}</div>
+            </template>
+        </nut-marquee>
+        <nut-codebox :code="demo1"></nut-codebox>
+
+        <h6>水平逆向内容跑马灯</h6>
+        <nut-marquee class="demo1" :gap='gap' :reverse="true" :speed='30'>
+            <template slot>
+                <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1,前提是我必须超过屏幕容器的宽度才可以哦,这么长的文字都没有超过</div>
+            </template>
+        </nut-marquee>
+        <nut-codebox :code="demo2"></nut-codebox>
+
+        <h6>垂直正向内容跑马灯</h6>
+       <nut-marquee class="demo1" 
+            :speed='30' 
+            :height="demo3Height" 
+            :direction='v'
+            :gap="gap">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+        </nut-marquee>
+        <nut-codebox :code="demo3"></nut-codebox>
+
+        <h6>垂直逆向内容跑马灯</h6>
+        <nut-marquee class="demo1" 
+            :speed='10' 
+            :gap= 'gap'
+            :height="demo3Height" 
+            :direction='v'
+            :reverse="true">
+            <div class="txt1">我是垂直轮播图1</div>
+            <div class="txt1">我是垂直轮播图2</div>
+            <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+            <div class="txt1">我是垂直轮播图3</div>
+            <div class="txt1">我是垂直轮播图4</div>
+        </nut-marquee>
+        <nut-codebox :code="demo4"></nut-codebox>
+
+        <h5>Props</h5>
+        <div class="tbl-wrapper">
+        <table class="u-full-width">
+          <thead>
+            <tr>
+              <th>参数</th>
+              <th>说明</th>
+              <th>类型</th>
+              <th>默认值</th>
+              <th>可选值</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>direction</td>
+              <td>用来控制轮播方向</td>
+              <td>String</td>
+              <td>horizontal</td>
+              <td>horizontal/vertical</td>
+            </tr>
+            <tr>
+              <td>speed</td>
+              <td>轮播的速率-移动1px的时间,单位为ms</td>
+              <td>Number</td>
+              <td>30</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>height</td>
+              <td>direction设置为horizontal时,用来控制外层容器高度的</td>
+              <td>Number</td>
+              <td>auto</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>reverse</td>
+              <td>是否为逆向,正向指的是:从右向左,从下向上。</td>
+              <td>Boolean</td>
+              <td>false</td>
+              <td>--</td>
+            </tr>
+            <tr>
+              <td>gap</td>
+              <td>2个元素之间的间距,仅支持rem或者px,如0.2rem或20px,必须指明单位。</td>
+              <td>String</td>
+              <td>0</td>
+              <td>--</td>
+            </tr>
+          </tbody>
+        </table>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    data(){
+        return{
+            h: '1.2rem',
+            v: 'vertical',
+            demo3Height: '8rem',
+            gap: '.2rem',
+            slotDatas: [
+                '我是轮播图1',
+                '我是轮播图2',
+                '我是轮播图3',
+                '我是轮播图4',
+                '我是轮播图6',
+                '我是轮播图7',
+                '我是轮播图8',
+                '我是轮播图9',
+                '我是轮播图10'
+            ],
+          demo1: `<nut-marquee class="demo1" :gap='gap' :speed="10">
+    <template slot >
+        <div v-for="(d, idx) in slotDatas" :key='idx' class="txt"><a>www.jd.com</a>{{d}}</div>
+    </template>
+</nut-marquee>`,
+          demo2: `<nut-marquee class="demo1" :gap='gap' :reverse="true" :speed='30'>
+    <template slot>
+        <div class="txt">我是一个轮播图,我有好多数字,一个屏幕看不到,只能看到一部分,轮播开始了1,前提是我必须超过屏幕容器的宽度才可以哦,这么长的文字都没有超过</div>
+    </template>
+</nut-marquee>`,
+          demo3: `<nut-marquee class="demo1" 
+    :speed='30' 
+    :height="demo3Height" 
+    :direction='v'
+    :gap="gap">
+    <div class="txt1">我是垂直轮播图1</div>
+    <div class="txt1">我是垂直轮播图2</div>
+    <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+    <div class="txt1">我是垂直轮播图3</div>
+</nut-marquee>`,
+          demo4: `<nut-marquee class="demo1" 
+    :speed='10' 
+    :gap= 'gap'
+    :height="demo3Height" 
+    :direction='v'
+    :reverse="true">
+    <div class="txt1">我是垂直轮播图1</div>
+    <div class="txt1">我是垂直轮播图2</div>
+    <img class="img" src='//nutui.jd.com/asset/img/nutui-logo-2.png'/>
+    <div class="txt1">我是垂直轮播图3</div>
+    <div class="txt1">我是垂直轮播图4</div>
+</nut-marquee>`
+        }
+    },
+    methods:{
+      showMask(){
+        this.maskShow = true;
+      },
+      hideMask(){
+        this.maskShow = false;
+      }
+    }
+}
+</script>
+
+<style>
+    .item {
+        display: inline-block;
+    }
+    .demo1 {
+        background: #fefad8;
+
+    }
+    .img {
+        width: 80%;
+    }
+    .txt {
+        line-height: .4rem;
+        white-space: nowrap;
+    }
+</style>