手撸了一个自定义的滚屏播报,可以设置放大比例,放大函数和 播报内容等
预览地址:戳这里
<!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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。