HTML5自定义滚屏播放

59次阅读

共计 15326 个字符,预计需要花费 39 分钟才能阅读完成。

手撸了一个自定义的滚屏播报,可以设置放大比例,放大函数和 播报内容等

预览地址:戳这里

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
    <title> 滚屏播放 </title>
   
<style>



html body{ 
    margin:0;
    width:100%;
    height:100%;
    overflow:-moz-scrollbars-vertical;
 }
::-webkit-scrollbar{display:none;}


#container{display: flex;}
#pannel{
    flex-grow: 1;
    flex-basis: 250px;
    border-right:1px solid #e0e3ec;
}

#pannelInput{margin: 10px;}

#showContent{border: 1px dashed #d0d2d8;}
#screen{
    flex-grow: 12;
    background-image:url('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565612569389&di=e0ae3faaf65e673a7b01425b5c3f712c&imgtype=0&src=http%3A%2F%2Fpic1.nipic.com%2F2008-11-25%2F200811251220358_2.jpg')
}
#screen span{position : absolute;}

input,select{
    border-radius: 4px;
    height: 30px;
    line-height: 30px;
    border: 1px solid #DCDFE6;
    padding: 0 5px;
}

input[type=button]{
    background: #3a8ee6;
    border-color: #3a8ee6;
    color: #FFF;
    padding: 0 15px;
margin: 10px;
}



#pannelSetting > div{margin: 5px;}

#start{
    padding: 0 30px;
  
    position: fixed;
    bottom: 30px;
    left: 130px;
}
#screen{
    color:#e2cdb2;
    font-family : cursive;
    text-shadow : 1px 1px 1px #b3933a;
}

</style>
</head>
<body>

    <div id='container' >
        <div id='pannel' >
            <div id='pannelInput'>
        
                <label> 内容:</label><input id='content1' type='text' value=''/>
                <input type="button" name='addContent' value="添加滚屏内容" onclick="zzScrollScreen.addContentFoo()" />
                <ul id='showContent'></ul>

            </div>
            <div id='pannelSetting'>
                <div>  
                    <label> 滚动类型:</label>
                    <input type="radio" name="scrollType" value="loop" onclick='zzScrollScreen.scrollTypeFun()' checked/> 循环播放
                    <input type="radio" name="scrollType" value="once" onclick='zzScrollScreen.scrollTypeFun()'/> 播放一次
                </div>
                
                <div>  
                    <label> 滚动方向:</label>
                    <input type="radio" name="direction" value="up" onclick='zzScrollScreen.directionTypeFun()' checked/> 自下而上
                    <input type="radio" name="direction" value="down" onclick='zzScrollScreen.directionTypeFun()'/> 自上而下
                </div>
            
                <div>  
                    <label> 放大比例:</label>
                    <input name='scall' type='number' value='1' onchange='zzScrollScreen.scallChangeFun()'/>
                </div>
            
                <div>  
                    <label> 上屏行数:</label>
                    <input name='displayRows' type='number' value='1' onchange='zzScrollScreen.displayRowsChangeFun()'/>
                </div>
                <div>  
                    <label> 滚动速度:</label>
                    <input name='speed' type='number' value='1' onchange='zzScrollScreen.speedChangeFun()'  />
                </div>
                <div>  
                    <label> 放大效果:</label>
                    <select name='bigger' onchange='zzScrollScreen.biggerChangeFun()'>
                    
                    </select>
                
                </div>
                <div>  
                    <label> 缩小效果:</label>
                    <select name='smaller' onchange='zzScrollScreen.smallerChangeFun()'>
                    
                    </select>
                
                </div>
            </div>
         
          <input type="button" id='start'  name='start' value="开始" onclick="zzScrollScreen.start()" />
        </div>
        <div id='screen' >
         滚屏播放
          
        </div>
      
    </div>

  <script>
 
 
 (function(document,window){
 
 
 
 var clientWidth = document.documentElement.clientWidth || document.body.offsetWidth|| window.innerWidth
 var clientHeight = document.documentElement.clientHeight || document.body.offsetHeight|| window.innerHeight;// 获取页面可见高度  
 var container = document.getElementById('container')
  
    container.style.height = clientHeight + "px";
    
 var i = 1
 var listData =[]
 var options={}
 var pannelInput = document.getElementById('pannelInput')
 var addContent = document.getElementsByName('addContent')

var  screen = document.getElementById('screen')
screen.style.position='relative'


 function addContentFun(){
        i++;
        var newInput = document.createElement("INPUT")
        newInput.name = 'content'+i
        newInput.type='text'
        newInput.onchange = function(){}
        
        pannelInput.appendChild(newInput)
 }
 
 function addContentFoo(){var content1 = document.getElementById('content1')
    var showContent = document.getElementById('showContent')
    if(content1 && content1.value){var newLi = document.createElement("li")
            newLi.name = 'contentLi'
            listData.push(content1.value)
        var textnode = document.createTextNode(content1.value)
            newLi.appendChild(textnode)
        showContent.appendChild(newLi)
    }
 }
 
 
 function scrollTypeFun(){var scrollType = document.getElementsByName('scrollType')
    options.scrollType = Array.from(scrollType).find(item => item.checked).value
 }
 
 
 function directionTypeFun(){var direction = document.getElementsByName('direction')
    options.directionValue = Array.from(direction).find(item => item.checked).value
 }
 

 function scallChangeFun(){var scall = document.getElementsByName('scall')
    options.scallValue = Array.from(scall)[0].value
 }
 
 function displayRowsChangeFun(){var row = document.getElementsByName('displayRows')
    options.rowValue = +Array.from(row)[0].value
 }
 
 function speedChangeFun(){var speed = document.getElementsByName('speed')
    options.speedValue = Array.from(speed)[0].value
 }
 
  function biggerChangeFun(){var bigger = document.getElementsByName('bigger')
    options.biggerValue = Array.from(bigger)[0].value
 }
 
  function smallerChangeFun(){var smaller = document.getElementsByName('smaller')
    options.smallerValue = Array.from(smaller)[0].value
 }
 
 
 function foo(options,copyListData){

  options.liHeight = 80
 
 var curTime = 0
 var currentEle = null
 var ulHeight = clientHeight
 var liHeight = options.liHeight
 var containerHeight = ulHeight + liHeight
 var startTop = ulHeight
 var speedValue = options.speedValue
 var directionValue = options.directionValue
 var scallValue = options.scallValue
 var scalePosition = ulHeight / 2;// 设置开始放大的位置

 var biggerValue = options.biggerValue
 var smallerValue = options.smallerValue
 var rowValue = options.rowValue
 var position = {
            'top': liHeight,
            'middle': ulHeight/2,
            'bottom': ulHeight - liHeight
        }
    scalePosition = position[options.scalePositionModel];
    scalePosition = scalePosition || position.middle;
 var ani = {
        startValue: 0,
        endValue: containerHeight, // 调节行间距
        startTime: 0,
        endTime: parseInt(10000/speedValue) // 总动画时间 // 调节速度
    }
var scaleOptions = {
    smallScale: 1,
    bigScale: +scallValue,
    startInPosition: scalePosition - 30,
    endInPosition: scalePosition - 50,
    startOutPosition: scalePosition + 50,
    endOutPosition: scalePosition + 30,
    easeBiggger: biggerValue,
    easeSmaller: smallerValue
}
 
 function getNextData(){if(!copyListData || copyListData.length === 0) return ''var result =''
    if (options.scrollType === 'once'){result = copyListData.shift()}
    if (options.scrollType === 'loop'){if (options.curIndex === undefined){options.curIndex = copyListData.length === options.rowValue?0:options.rowValue}else {if (options.curIndex >= copyListData.length) {options.curIndex = 0}
        }
        result = copyListData[options.curIndex]
        options.curIndex +=1
    }
    return result

 }
 
 
         
         
 function render() {
    // 缓动函数的算法: 根据开始时间 / 位置, 结束时间 / 位置, 当前位置 计算出当前的位置值
    var curValue = ani.startValue +((ani.endValue - ani.startValue) * (curTime - ani.startTime)) /(ani.endTime - ani.startTime);
    var currentTop = 0;
    for (var i = 0; i < rowValue; i++) {if (directionValue === 'down') {currentTop = curValue + (containerHeight / rowValue) * i
        } else{currentTop = startTop - curValue + (containerHeight / rowValue) * i
        }
        // 每次 render 时,根据消耗的时间 curTime 计算运动距离 curValue,再计算出视口位置 currentTop
        // 处于视口外的数据,则减去 containerHeight,挪到屏幕上方,让所有数据占据整个屏幕
        if (currentTop > startTop) {currentTop -= containerHeight}
        
        var currentElement = document.getElementsByTagName("span")[i]
        currentElement.style.top = currentTop + 'px';
        currentElement.style.left = options.offsetWidth + 'px';
        
    
        
                
        // 获取下一个数据
        if (currentTop > startTop - 5) {if (i !== currentEle) {
                currentEle = i; // 使用 currentEle 标识, 在 startTop - 5 到 在 startTop 的范围内反复执行, 只取一次数据
                currentElement.innerHTML =  getNextData() ||'恭贺新春'}
        }
        var curScaleValue;
        // 放大动画
        if (currentTop < scaleOptions.startOutPosition && currentTop > scaleOptions.endOutPosition) {//t:当前时间 ( 当前 X 值)
            //b:初始值 (初始 Y 值)
            //c:变化量 (变化的 Y 值)
            //d:持续时间 (变化的 X 值)
            //a:
            //p:
            //s:
            let t= currentTop - scaleOptions.startOutPosition,
                b=scaleOptions.smallScale,
                c=scaleOptions.bigScale - scaleOptions.smallScale,
                d=scaleOptions.endOutPosition - scaleOptions.startOutPosition;
            curScaleValue = easeFunction[scaleOptions.easeBiggger](t,b,c,d);
            currentElement.style.transform = 'scale(' + curScaleValue + ')'
        } // 缩小动画
        else if (currentTop < scaleOptions.startInPosition && currentTop > scaleOptions.endInPosition) {
            let t = currentTop - scaleOptions.startInPosition,
                b=scaleOptions.bigScale,
                c=scaleOptions.smallScale - scaleOptions.bigScale,
                d=scaleOptions.endInPosition - scaleOptions.startInPosition;
            curScaleValue =    easeFunction['Linear'](t,b,c,d);
            currentElement.style.transform = 'scale(' + curScaleValue + ')'
        }
        
        
        
    }
    
    curTime += 1000 / 60 // 固定值
    if (curTime > ani.endTime) {curTime = 0 // 从头开始动画 循环播放}
}        

        
 

     
     window.requestAnimFrame = (function () {
        return (
            window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (callback) {window.setTimeout(callback, 1000 / 60)
            }
        )
    })()
    
     ;(function animloop() {render();
            requestAnimFrame(animloop) // 递归完成动画
        })()}
 
 
  
  
 var easeFunction =(function(){function normalize(a, c, p, s) {if (a < Math.abs(c)) {
      a = c
      s = p / 4
    } else {
      //handle the 0/0 case:
      if (c === 0 && a === 0) {s = (p / (2 * Math.PI)) * Math.asin(1)
      } else {s = (p / (2 * Math.PI)) * Math.asin(c / a)
      }
    }
    return {a: a, c: c, p: p, s: s}
  }
function elastic(opts, t, d) {
    return (
      opts.a *
      Math.pow(2, 10 * (t -= 1)) *
      Math.sin(((t * d - opts.s) * (2 * Math.PI)) / opts.p)
    )
  }
  /**
   * Cubic easing out
   * @memberOf fabric.util.ease
   */
  function easeOutCubic(t, b, c, d) {return c * ((t = t / d - 1) * t * t + 1) + b
  }
  /**
   * Cubic easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutCubic(t, b, c, d) {
    t /= d / 2
    if (t < 1) {return (c / 2) * t * t * t + b
    }
    return (c / 2) * ((t -= 2) * t * t + 2) + b
  }
  /**
   * Quartic easing in
   * @memberOf fabric.util.ease
   */
  function easeInQuart(t, b, c, d) {return c * (t /= d) * t * t * t + b
  }
  /**
   * Quartic easing out
   * @memberOf fabric.util.ease
   */
  function easeOutQuart(t, b, c, d) {return -c * ((t = t / d - 1) * t * t * t - 1) + b
  }
  /**
   * Quartic easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutQuart(t, b, c, d) {
    t /= d / 2
    if (t < 1) {return (c / 2) * t * t * t * t + b
    }
    return (-c / 2) * ((t -= 2) * t * t * t - 2) + b
  }
  /**
   * Quintic easing in
   * @memberOf fabric.util.ease
   */
  function easeInQuint(t, b, c, d) {return c * (t /= d) * t * t * t * t + b
  }
  /**
   * Quintic easing out
   * @memberOf fabric.util.ease
   */
  function easeOutQuint(t, b, c, d) {return c * ((t = t / d - 1) * t * t * t * t + 1) + b
  }
  /**
   * Quintic easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutQuint(t, b, c, d) {
    t /= d / 2
    if (t < 1) {return (c / 2) * t * t * t * t * t + b
    }
    return (c / 2) * ((t -= 2) * t * t * t * t + 2) + b
  }
  /**
   * Sinusoidal easing in
   * @memberOf fabric.util.ease
   */
  function easeInSine(t, b, c, d) {return -c * Math.cos((t / d) * (Math.PI / 2)) + c + b
  }
  /**
   * Sinusoidal easing out
   * @memberOf fabric.util.ease
   */
  function easeOutSine(t, b, c, d) {return c * Math.sin((t / d) * (Math.PI / 2)) + b
  }
  /**
   * Sinusoidal easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutSine(t, b, c, d) {return (-c / 2) * (Math.cos((Math.PI * t) / d) - 1) + b
  }
  /**
   * Exponential easing in
   * @memberOf fabric.util.ease
   */
  function easeInExpo(t, b, c, d) {return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b
  }
  /**
   * Exponential easing out
   * @memberOf fabric.util.ease
   */
  function easeOutExpo(t, b, c, d) {return t === d ? b + c : c * (-Math.pow(2, (-10 * t) / d) + 1) + b
  }
  /**
   * Exponential easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutExpo(t, b, c, d) {if (t === 0) {return b}
    if (t === d) {return b + c}
    t /= d / 2
    if (t < 1) {return (c / 2) * Math.pow(2, 10 * (t - 1)) + b
    }
    return (c / 2) * (-Math.pow(2, -10 * --t) + 2) + b
  }
  /**
   * Circular easing in
   * @memberOf fabric.util.ease
   */
  function easeInCirc(t, b, c, d) {return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b
  }
  /**
   * Circular easing out
   * @memberOf fabric.util.ease
   */
  function easeOutCirc(t, b, c, d) {return c * Math.sqrt(1 - (t = t / d - 1) * t) + b
  }
  /**
   * Circular easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutCirc(t, b, c, d) {
    t /= d / 2
    if (t < 1) {return (-c / 2) * (Math.sqrt(1 - t * t) - 1) + b
    }
    return (c / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + b
  }
  /**
   * Elastic easing in
   * @memberOf fabric.util.ease
   */
  function easeInElastic(t, b, c, d) {
    var s = 1.70158,
      p = 0,
      a = c
    if (t === 0) {return b}
    t /= d
    if (t === 1) {return b + c}
    if (!p) {p = d * 0.3}
    var opts = normalize(a, c, p, s)
    return -elastic(opts, t, d) + b
  }
  /**
   * Elastic easing out
   * @memberOf fabric.util.ease
   */
  function easeOutElastic(t, b, c, d) {
    var s = 1.70158,
      p = 0,
      a = c
    if (t === 0) {return b}
    t /= d
    if (t === 1) {return b + c}
    if (!p) {p = d * 0.3}
    var opts = normalize(a, c, p, s)
    return (
      opts.a *
        Math.pow(2, -10 * t) *
        Math.sin(((t * d - opts.s) * (2 * Math.PI)) / opts.p) +
      opts.c +
      b
    )
  }
  /**
   * Elastic easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutElastic(t, b, c, d) {
    var s = 1.70158,
      p = 0,
      a = c
    if (t === 0) {return b}
    t /= d / 2
    if (t === 2) {return b + c}
    if (!p) {p = d * (0.3 * 1.5)
    }
    var opts = normalize(a, c, p, s)
    if (t < 1) {return -0.5 * elastic(opts, t, d) + b
    }
    return (
      opts.a *
        Math.pow(2, -10 * (t -= 1)) *
        Math.sin(((t * d - opts.s) * (2 * Math.PI)) / opts.p) *
        0.5 +
      opts.c +
      b
    )
  }
  /**
   * Backwards easing in
   * @memberOf fabric.util.ease
   */
  function easeInBack(t, b, c, d, s) {if (s === undefined) {s = 1.70158}
    return c * (t /= d) * t * ((s + 1) * t - s) + b
  }
  /**
   * Backwards easing out
   * @memberOf fabric.util.ease
   */
  function easeOutBack(t, b, c, d, s) {if (s === undefined) {s = 1.70158}
    return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b
  }
  /**
   * Backwards easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutBack(t, b, c, d, s) {if (s === undefined) {s = 1.70158}
    t /= d / 2
    if (t < 1) {return (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b
    }
    return (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b
  }
  /**
   * Bouncing easing in
   * @memberOf fabric.util.ease
   */
  function easeInBounce(t, b, c, d) {return c - easeOutBounce(d - t, 0, c, d) + b
  }
  /**
   * Bouncing easing out
   * @memberOf fabric.util.ease
   */
  function easeOutBounce(t, b, c, d) {if ((t /= d) < 1 / 2.75) {return c * (7.5625 * t * t) + b
    } else if (t < 2 / 2.75) {return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b
    } else if (t < 2.5 / 2.75) {return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b
    } else {return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b
    }
  }
  /**
   * Bouncing easing in and out
   * @memberOf fabric.util.ease
   */
  function easeInOutBounce(t, b, c, d) {if (t < d / 2) {return easeInBounce(t * 2, 0, c, d) * 0.5 + b
    }
    return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b
  }
  
  
  
return {Linear: function(t,b,c,d){return c*t/d + b;},
    /**
     * Quadratic easing in
     * @memberOf fabric.util.ease
     */
    easeInQuad: function(t, b, c, d) {return c * (t /= d) * t + b
    },
    /**
     * Quadratic easing out
     * @memberOf fabric.util.ease
     */
    easeOutQuad: function(t, b, c, d) {return -c * (t /= d) * (t - 2) + b
    },
    /**
     * Quadratic easing in and out
     * @memberOf fabric.util.ease
     */
    easeInOutQuad: function(t, b, c, d) {
      t /= d / 2
      if (t < 1) {return (c / 2) * t * t + b
      }
      return (-c / 2) * (--t * (t - 2) - 1) + b
    },
    /**
     * Cubic easing in
     * @memberOf fabric.util.ease
     */
    easeInCubic: function(t, b, c, d) {return c * (t /= d) * t * t + b
    },
    easeOutCubic: easeOutCubic,
    easeInOutCubic: easeInOutCubic,
    easeInQuart: easeInQuart,
    easeOutQuart: easeOutQuart,
    easeInOutQuart: easeInOutQuart,
    easeInQuint: easeInQuint,
    easeOutQuint: easeOutQuint,
    easeInOutQuint: easeInOutQuint,
    easeInSine: easeInSine,
    easeOutSine: easeOutSine,
    easeInOutSine: easeInOutSine,
    easeInExpo: easeInExpo,
    easeOutExpo: easeOutExpo,
    easeInOutExpo: easeInOutExpo,
    easeInCirc: easeInCirc,
    easeOutCirc: easeOutCirc,
    easeInOutCirc: easeInOutCirc,
    easeInElastic: easeInElastic,
    easeOutElastic: easeOutElastic,
    easeInOutElastic: easeInOutElastic,
    easeInBack: easeInBack,
    easeOutBack: easeOutBack,
    easeInOutBack: easeInOutBack,
    easeInBounce: easeInBounce,
    easeOutBounce: easeOutBounce,
    easeInOutBounce: easeInOutBounce
  }
  
  })()
  

function keys(objs){var easeArray=[]
    for(var o in objs){if(o){easeArray.push(o)
        }
    }
    return easeArray
}



 var bigger = document.getElementsByName('bigger')
 var smaller = document.getElementsByName('smaller')
for(var ii in easeFunction){var myOption1 = document.createElement("option"); 
    myOption1.value = ii; 
    myOption1.text = ii; 
    var myOption2 = document.createElement("option"); 
    myOption2.value = ii; 
    myOption2.text = ii; 
    bigger[0].appendChild(myOption1); 
    smaller[0].appendChild(myOption2); 
}


function creatSpan(options,data){if(data.length ===0){data=['']}
    var num = options.rowValue;//9
    var len = data.length;//4
    var floor = Math.floor(num/len) ;//Math.floor(9/4) =2
    var remainder = num%len;//9%4 =1
    var showData = []
    
    for(var m=0;m<floor;m++){showData = showData.concat(data)
    }
    for(var n=0;n<remainder;n++){showData.push(data[n])
    }
    options.curIndex = 0;
    
    for(var ii=0;ii<num;ii++){var textnode = document.createTextNode(showData[ii])
        var newItem = document.createElement("SPAN")

        newItem.appendChild(textnode)
        newItem.style.top = clientHeight + 'px';
        screen.appendChild(newItem)
    }

}
  
  
  function start () {var copyListData = listData.slice()
     var parent = document.getElementById("screen");
     var child = document.getElementsByTagName("span");
    
    for(var j=0;j<child.length;j++){parent.removeChild(child[0])
    }
    
    options.offsetWidth = parent.offsetWidth/2
      scrollTypeFun()
      directionTypeFun()
      scallChangeFun()
      displayRowsChangeFun()
      speedChangeFun()
      biggerChangeFun()
      smallerChangeFun()
      creatSpan(options,copyListData)
      foo(options,copyListData)
  }
 
 

     window.zzScrollScreen =  window.zzScrollScreen || {
        start:start,
        scrollTypeFun:scrollTypeFun,
        directionTypeFun:directionTypeFun,
        scallChangeFun:scallChangeFun,
        displayRowsChangeFun:displayRowsChangeFun,
        speedChangeFun:speedChangeFun,
        biggerChangeFun:biggerChangeFun,
        smallerChangeFun:smallerChangeFun,
        addContentFoo:addContentFoo,
     
     }
 })(document,window)
 
 
  
  </script>

</body>
</html>

正文完
 0