動態

詳情 返回 返回

設置css的rotate ,perspective為2000px,求div的視覺投影二維座標 - 動態 詳情

設置:transform :rotateX(30deg) rotateY(40deg) rotateZ(0deg)

image.png

/**

  • 計算旋轉後的四個角點 3D 座標(支持動態左上角座標)
  • @param {number} left - 左上角初始 x 座標
  • @param {number} top - 左上角初始 y 座標
  • @param {number} width - 元素寬度
  • @param {number} height - 元素高度
  • @param {number} [x=0] - rotateX 角度(度)
  • @param {number} [y=0] - rotateY 角度(度)
  • @param {number} [z=0] - rotateZ 角度(度)
  • @param {number} [originX=width/2] - 旋轉中心 x(相對於左上角)
  • @param {number} [originY=height/2] - 旋轉中心 y(相對於左上角)
  • @returns {Array<{x: number, y: number, z: number}>} 四個角點的 3D 座標 [左上, 右上, 右下, 左下]
    */

const getTransformedCorners = (
x: number,
y: number,
width: number,
height: number,
rotateX: number,
rotateY: number,
rotateZ: number,
perspective: number = 2000
) => {
// 角度歸一化
const normalizeAngle = (angle: number) => ((angle % 360) + 360) % 360
rotateX = normalizeAngle(rotateX)
rotateY = normalizeAngle(rotateY)
rotateZ = normalizeAngle(rotateZ)

// 轉換為弧度(Z旋轉取反)
const degToRad = (deg: number) => deg * (Math.PI / 180)
const rx = degToRad(rotateX)
const ry = degToRad(rotateY)
const rz = degToRad(-rotateZ) // 關鍵修改處

// 中心點計算
const cx = x + width / 2
const cy = y + height / 2

// 四角局部座標
const corners = [

{ x: -width / 2, y: -height / 2, z: 0 },
{ x: width / 2, y: -height / 2, z: 0 },
{ x: -width / 2, y: height / 2, z: 0 },
{ x: width / 2, y: height / 2, z: 0 }

]

// 旋轉矩陣(CSS順序:先Z後Y再X)
const cosX = Math.cos(rx),

sinX = Math.sin(rx)

const cosY = Math.cos(ry),

sinY = Math.sin(ry)

const cosZ = Math.cos(rz),

sinZ = Math.sin(rz)

// 合併旋轉矩陣:R = Rx Ry Rz
const rotationMatrix = [

[cosY * cosZ, cosY * sinZ, -sinY],
[sinX * sinY * cosZ - cosX * sinZ, sinX * sinY * sinZ + cosX * cosZ, sinX * cosY],
[cosX * sinY * cosZ + sinX * sinZ, cosX * sinY * sinZ - sinX * cosZ, cosX * cosY]

]

// 應用變換
return corners.map((corner) => {

const xRotated = rotationMatrix[0][0] * corner.x + rotationMatrix[0][1] * corner.y
const yRotated = rotationMatrix[1][0] * corner.x + rotationMatrix[1][1] * corner.y
const zRotated = rotationMatrix[2][0] * corner.x + rotationMatrix[2][1] * corner.y

const scale = perspective / (perspective + zRotated)
return {
  x: cx + xRotated * scale,
  y: cy + yRotated * scale
}

})
}

Add a new 評論

Some HTML is okay.