console
let angle = 20
const outBox = {
name:'outBox',
width: 200,
height: 200,
x: 100,
y: 100,
angle,
background:'red',
}
const inBox = {
name:'inBox',
width: 100,
height: 100,
x: 150,
y: 150,
angle,
background:'blue',
}
const container = document.getElementById('box')
const boxList = [outBox,inBox]
for(let i =0;i < boxList.length;i++ ) {
const div = document.createElement('div')
const styles = boxList[i]
div.className = styles.name
Object.assign(div.style,{
position:'absolute',
top: styles.y + 'px',
left: styles.x + 'px',
width: styles.width + 'px',
height: styles.height + 'px',
transform: `rotate(${styles.angle}deg)`,
background: styles.background
})
container.appendChild(div)
}
const outB = document.querySelector('.outBox')
const inB = document.querySelector('.inBox')
const startData = {
y:0,
x:0,
boxX:0,
boxY:0,
}
function updateInBox () {
inB.style.top = inBox.y + 'px'
inB.style.left = inBox.x + 'px'
}
function handleMove(e){
const diffX =e.clientX - startData.x
const diffY =e.clientY - startData.y
checkImagePosition(diffX,diffY)
updateInBox()
}
function handleUp(){
document.removeEventListener('mousemove',handleMove)
document.removeEventListener('mouseup',handleUp)
}
inB.addEventListener('mousedown',(e)=>{
startData.x = e.clientX
startData.y = e.clientY
startData.boxX = inBox.x
startData.boxY = inBox.y
updateTempData()
document.addEventListener('mousemove',handleMove)
document.addEventListener('mouseup',handleUp)
})
function updateTempData () {
inBox.tempData = getRectData(inBox)
outBox.tempData = getRectData(outBox)
}
function getRectData(data){
let {x,y,width,height,angle} = data
let center = {
x: x + width / 2,
y: y + height / 2,
}
let leftTop = {
x,
y,
}
let rotateLeftTop = calcRotatedPoint(leftTop,center, angle)
return {
center,
rotateLeftTop
}
}
function checkImagePosition(diffX,diffY){
let minLeft = 0
let maxLeft = outBox.width - inBox.width
let minTop = 0
let maxTop = outBox.height - inBox.height
let outBoxRa = outBox.tempData.rotateLeftTop
let inBoxCenter = inBox.tempData.center
let inBoxRa = inBox.tempData.rotateLeftTop
let newInBoxRa = {
x: inBoxRa.x + diffX,
y: inBoxRa.y + diffY,
}
let newInBoxCenter = {
x: inBoxCenter.x + diffX,
y: inBoxCenter.y + diffY,
}
let newInBoxA = calcRotatedPoint(
newInBoxRa,
outBox.tempData.center,
-angle,
)
let radian = angle * (Math.PI / 180)
let list = [newInBoxRa, newInBoxCenter]
let projectionX = newInBoxA.x - outBox.x
if (projectionX < minLeft || projectionX > maxLeft) {
projectionX =(projectionX < minLeft ? minLeft : maxLeft) - projectionX
console.log('projectionX',projectionX)
for(let i =0 ;i < list.length;i++) {
list[i].x += Math.cos(radian) * projectionX
list[i].y += Math.sin(radian) * projectionX
}
}
let projectionY = newInBoxA.y - outBox.y
if (projectionY < minTop || projectionY > maxTop) {
projectionY = (projectionY < minTop ? minTop : maxTop) - projectionY
console.log('projectionY',projectionY)
for(let i =0 ;i < list.length;i++) {
list[i].x -= Math.sin(radian) * projectionY
list[i].y += Math.cos(radian) * projectionY
}
}
let newA = calcRotatedPoint(
newInBoxRa,
newInBoxCenter,
-angle,
)
inBox.x = newA.x
inBox.y = newA.y
}
function calcRotatedPoint (prev, center, angle) {
angle /= 180 / Math.PI
return {
x: (prev.x - center.x) * Math.cos(angle) - (prev.y - center.y) * Math.sin(angle) + center.x,
y: (prev.x - center.x) * Math.sin(angle) + (prev.y - center.y) * Math.cos(angle) + center.y
}
}
let timer = null
document.addEventListener('mousemove',()=>{
document.body.style.cursor = 'default'
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(()=>{
document.body.style.cursor = 'none'
},2000)
})
<div id="box"></div>
#box {
width: 800px;
height:800px;
background-color: skyblue
}