* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
button {
appearance: none;
padding: 3px;
margin-top: 4px;
}
.wrap {
background-color: #111;
height: calc(100% - 100px);
}
.btn_wrap {
height: 100px;
position: relative;
padding: 10px 60px 0 10px;
}
#fps {
position: absolute;
right: 10px;
top: 10px;
color: rgba(70, 270, 40, 0.8);
}
#starCount {
position: absolute;
right: 10px;
top: 40px;
color: rgba(270, 70, 40, 0.8);
z-index: 50;
transform: translateZ(0px);
}
你的浏览器版本太低
function ready(fn) {
if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') {
fn()
} else {
document.addEventListener('DOMContentLoaded', fn)
}
}
ready(() => {
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
wrap = document.getElementById('wrap'),
addStar = document.getElementById('addStar'),
starCountText = document.getElementById('starCount'),
fpsWrap = document.getElementById('fps'),
clientWidth = wrap.clientWidth,
clientHeight = wrap.clientHeight,
maxLeft = clientWidth * 0.9,
maxTop = clientHeight - clientWidth * 0.1,
imgWidth = Math.floor(clientWidth * 0.1),
// 星星数量
starCount = 10,
// 星星坐标系
starArr = [],
// 帧率计算
frame = 0,
allFrameCount = 0,
lastTime = Date.now(),
lastFameTime = Date.now(),
now,
// 绘图次数
drawCount = 0,
// canvas动画帧
fnReq = null,
// canvas动画延时
timer = null,
// 图片
img = [],
// 图片已加载完数量
imgFlag = 0,
// 离屏绘制
canvasOffscreen = []
canvas.width = clientWidth
canvas.height = clientHeight - 10
function rAF(callback) {
window.requestAnimationFrame(callback) || window.webkitRequestAnimationFrame(callback) || window.mozRequestAnimationFrame(callback) || window.setTimeout(callback, 1000 / 60)
}
// 计算fps
function loop() {
;(now = Date.now()), (fs = now - lastFameTime), (fps = Math.round(1000 / fs))
lastFameTime = now
// 不置 0,在动画的开头及结尾记录此值的差值算出 FPS
allFrameCount++
frame++
if (now > 1000 + lastTime) {
var fps = Math.round((frame * 1000) / (now - lastTime))
fpsWrap.innerHTML = `FPS: ${fps}`
frame = 0
lastTime = now
}
rAF(loop)
}
function randomLeft() {
return Math.floor(Math.random() * maxLeft)
}
function randowTop() {
return Math.floor(Math.random() * maxTop)
}
// 获取当前的宽高
function curImageScale(index) {
var temp = Math.floor(drawCount / 2) + index + '',
count = +temp.substring(temp.length - 1)
return count === 0 ? imgWidth : (imgWidth * count) / 10
}
// 计算缩放后的位置
function scaleCoo(pos, size) {
return pos + (imgWidth - size) / 2
}
// 获取当前图片的位置
function imgIndex(index) {
return (index + Math.floor(drawCount / 2)) % 17
}
// 绘制图形
function draw(value) {
ctx.clearRect(0, 0, clientWidth, clientHeight)
drawCount++
for (let index = 0; index < starCount; index++) {
var _curLeft = starArr[index][0],
_curTop = starArr[index][1]
if (value !== 1) {
// 为1表示动画已经结束,进入延迟阶段
_curLeft = Math.floor(starArr[index][2] + starArr[index][4] * value)
_curTop = Math.floor(starArr[index][3] + starArr[index][5] * value)
starArr[index][0] = _curLeft
starArr[index][1] = _curTop
}
ctx.drawImage(canvasOffscreen[imgIndex(index)], _curLeft, _curTop)
}
}
function drawInit(reset) {
ctx.clearRect(0, 0, clientWidth, clientHeight)
if (reset) {
clearTimeout(timer)
starArr.splice(0)
for (let index = 0; index < starCount; index++) {
var _startLeft = randomLeft(),
_startTop = randowTop()
// 六个坐标分别为当前左、当前上、初始左、初始上、左移动距离、上移动距离
starArr.push([_startLeft, _startTop, _startLeft, _startTop, randomLeft() - _startLeft, randowTop() - _startTop])
}
} else {
for (let index = 0; index < starCount; index++) {
var _startLeft = starArr[index][0],
_startTop = starArr[index][1]
// 六个坐标分别为当前左、当前上、初始左、初始上、左移动距离、上移动距离
starArr[index] = [_startLeft, _startTop, _startLeft, _startTop, randomLeft() - _startLeft, randowTop() - _startTop]
}
}
animation()
timer = setTimeout(() => {
drawInit(false)
}, 1300)
}
// 根据动画函数计算偏移值
function animation() {
fnReq && cancelAnimationFrame(fnReq())
fnReq = Math.animation(0, 1, 'Sine.easeOut', 1300, function(value) {
draw(value)
})
}
for (let i = 0; i < 17; i++) {
img[i] = new Image()
img[i].src = `./images/star_frame-${i}.jpg`
img[i].onload = function() {
//第i张图片加载完成
imgFlag++
// 离屏绘制
canvasOffscreen[i] = document.createElement('canvas')
canvasOffscreen[i].width = imgWidth
canvasOffscreen[i].height = imgWidth
canvasOffscreen[i].getContext('2d').drawImage(img[i], 0, 0, imgWidth, imgWidth)
if (imgFlag === 17) {
//全部加载完成
drawInit(true)
}
}
}
loop()
window.addEventListener(
'resize',
() => {
clientWidth = wrap.clientWidth
clientHeight = wrap.clientHeight
maxLeft = clientWidth * 0.9
maxTop = clientHeight - clientWidth * 0.1
imgWidth = Math.floor(clientWidth * 0.1)
canvas.width = clientWidth
canvas.height = clientHeight - 10
drawInit(true)
},
false
)
addStar.addEventListener(
'click',
function(e) {
e.preventDefault()
starCount += 100
drawInit(true)
starCountText.innerHTML = `星星数目: ${starCount}`
},
false
)
}, false)
一键复制
编辑
Web IDE
原始数据
按行查看
历史