请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
<style>
/* 容器元素 */
#mydiv {
margin: 20px 0 20px calc(50% - 720px); /* 水平方向居中 */
width: 1440px;
height: 810px;
background: skyblue;
box-shadow: 4px 4px 8px #000;
position: relative;
z-index: 1; /* 这个不要缺 */
}
/* 容器元素伪元素 */
#mydiv::before, #mydiv::after {
position: absolute;
content: '';
inset: 0; /* 定位,等同于 top、right、bottom、left 都为 0 */
/* 如果容器和图片尺寸不一致,下句分号前加空格再加 0 0 / 100% 100% */
background: url('https://638183.freep.cn/638183/t24/7/t24.jpg') no-repeat;
}
#mydiv::before {
background-position: var(--begin1) 0; /* 背景位置(值将由JS生成)*/
}
#mydiv::after {
transform: scale(-1, 1); /* 水平方向倒转 */
background-position: var(--begin2) 0; /* 背景位置(值将由JS生成)*/
z-index: -1; /* 重要,避免 :after 覆盖其它元素 */
}
/* 文本居中选择器 */
.tMid { text-align: center; }
</style>
<div id="mydiv"></div>
<p class="tMid"><button id="btnAni">播放/暂停动画</button></p>
<script>
// stop :动画开关;begin1 :移动背景初始值;raf :请求关键帧动画标识
let stop = true, begin1 = 0, raf = null;
// 移动背景函数 :elm - 容器元素,speed - 移动速度(缺省默认 0.5)
function bgMove(elm, speed = 0.5) {
const ww = elm.offsetWidth; // 取容器宽度
// 内嵌移动函数
function moving() {
cancelAnimationFrame(raf); // 注销动画标识(防止速度变快)
begin1 += speed; // ::before 伪元素移动值按速度递增
if (speed > 0 && begin1 >= ww) begin1 = -ww; // 自左向右移动衔接算法
if(speed < 0 && begin1 <= -ww) begin1 = ww; // 自右向左移动衔接算法
// ::after 伪元素移动值算法 :依据 begin1 当前值动态计算
const begin2 = begin1 >= 0 ? -1 * (begin1 - ww + 1) : -1 * (begin1 + ww - 1);
// 处理伪元素所需 CSS 变量值
elm.style.setProperty('--begin1', begin1 + 'px');
elm.style.setProperty('--begin2', begin2 + 'px');
// 依据外部 stop 变量注销或递归运行动画
stop ? cancelAnimationFrame(raf) : raf = requestAnimationFrame(moving);
}
moving(); // 运行 moving 函数
}
// 若需要立即运行请设置 stop = false 同时解开下行代码注释
// bgMove(mydiv, 0.6);
// 动画控制(按钮点击事件)
btnAni.onclick = () => {
stop = !stop; // stop 值取反
bgMove(mydiv, 0.6); // 运行动画
};
</script>
|