手撸了一个自定义的滚屏播报,可以设置放大比例,放大函数和 播报内容等
预览地址:戳这里
<!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>