Отскок шарика от краев границ блока?
В родительском блоке имеется шар:
body {
background: black;
}
.box {
position: relative;
overflow: hidden;
margin: 0 auto;
width: 500px;
height: 300px;
border-radius: 5px;
box-shadow: inset 0 0 2px black;
background-color: white;
}
.ball {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: black;
box-shadow: inset -5px -5px 5px rgba(0, 0, 0, .5), 15px 15px 2px rgba(0, 0, 0, .05);
}
<div class="box">
<div class="ball"></div>
</div>
Как можно заставить его бесконечно двигаться и отскакивать от краев границ этого блока?
Ответы (3 шт):
Автор решения: hu-fo
→ Ссылка
var box = document.querySelector('.box')
var ball = document.querySelector('.ball')
var boxRect = box.getBoundingClientRect()
var ballRect = ball.getBoundingClientRect()
// Границы
var boundaries = {
maxX: boxRect.width,
maxY: boxRect.height,
minX: 0,
minY: 0
}
// Позиция шарика
var ballPos = {
x: boundaries.minX,
y: boundaries.minY
}
// эти штуки можно как-нибудь по умному назвать,
// но я тупой, поэтому просто представь, что это
// совокупность скорости и направления движения
var dx = 3,
dy = 3
function animate() {
// если шарик вышел за границы по оси х
// меняем направление
// было dx = 3, стало dx = -3
if (
ballPos.x < boundaries.minX ||
ballPos.x > boundaries.maxX - ballRect.width
) dx = -dx
// тоже самое только по оси y
if (
ballPos.y < boundaries.minY ||
ballPos.y > boundaries.maxY - ballRect.height
) dy = -dy
// ну тут всё понятно
ballPos.x += dx
ballPos.y += dy
ball.style.transform = `translate(${ballPos.x}px, ${ballPos.y}px)`
requestAnimationFrame(animate)
}
requestAnimationFrame(animate)
body {
background: black;
}
.box {
position: relative;
overflow: hidden;
margin: 0 auto;
width: 500px;
height: 300px;
border-radius: 5px;
box-shadow: inset 0 0 2px black;
background-color: white;
}
.ball {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: black;
box-shadow: inset -5px -5px 5px rgba(0, 0, 0, .5), 15px 15px 2px rgba(0, 0, 0, .05);
}
<div class="box">
<div class="ball"></div>
</div>
Автор решения: Sevastopol'
→ Ссылка
Хм... а почему бы это не сделать на CSS? Просто добавить две строчки анимации:
body {
background: black;
}
.box {
position: relative;
overflow: hidden;
margin: 0 auto;
width: 500px;
height: 300px;
border-radius: 5px;
box-shadow: inset 0 0 2px black;
background-color: white;
}
.ball {
position: absolute;
width: 20px;
height: 20px;
border-radius: 100%;
background-color: black;
box-shadow: inset -5px -5px 5px rgba(0, 0, 0, .5), 15px 15px 2px rgba(0, 0, 0, .05);
animation: moveX 3s linear 0s infinite alternate, moveY 3.5s linear 0s infinite alternate;
}
@keyframes moveX {from {left: 0;} to {left: 480px;}}
@keyframes moveY {from {top: 0;} to {top: 280px;}}
<div class="box"><div class="ball"></div></div>
Автор решения: Alexandr_TT
→ Ссылка
А почему бы это не сделать на SVG?
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" height="100vh" viewBox="0 0 400 400">
<rect width="100%" height="100%" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="50%" cy="20%" r="3%" fill="url(#gradB)" >
<animate attributeName="cx" dur="3" values="3%;97%;3%"
repeatCount="indefinite" />
<animate attributeName="cy" dur="2.8" values="3%;97%;3%"
repeatCount="indefinite" />
</circle>
<circle cx="30%" cy="70%" r="3%" fill="url(#gradR)" >
<animate attributeName="cx" dur="2.7" values="97%;3%;97%"
repeatCount="indefinite" />
<animate attributeName="cy" dur="3.1" values="3%;97%;3%"
repeatCount="indefinite" />
</circle>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
<radialGradient id="gradR" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="red" offset="25%"/>
<stop stop-color="rgb(192,0,0)" offset="50%"/>
<stop stop-color="rgb(127,0,0)" offset="70%"/>
<stop stop-color="rgb(64,0,0)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</svg>