Verwenden Sie die Schieberegler im folgenden Beispiel, um die CSS-Transformations-Eigenschaften Übersetzung, Rotation, Skalierung und Schrägstellung des Würfels im 3D-Raum zu modifizieren. Beobachten Sie, wie der Würfel beim Bewegen durch den 3D-Raum mit dem als z:0px
bezeichneten Element interagiert, das sich an der 3D-Position (0, 0, 0)
befindet.
Transform settings
↻
Translation
↻
Rotation
↻
Scale
↻
Skew
↻
Container Perspective
↻
Other Properties
↻
#allTransformFieldset {
border: none;
padding: 0;
margin-bottom: 4px;
accent-color: blue; /* or any color */
font-family:
Inter, "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell,
"Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
#allTransformFieldset > legend {
margin-bottom: 4px;
}
fieldset {
margin: 0;
}
legend {
font-weight: bold;
padding: 0;
}
#fieldsetSection {
display: flex;
flex-wrap: wrap;
align-items: start;
gap: 8px;
}
#outputSection {
width: 100%;
min-height: 400px;
background: linear-gradient(skyblue, khaki);
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: clip;
}
#outputContainer {
position: absolute;
width: 100%;
height: 100%;
perspective: 200px;
display: flex;
justify-content: center;
align-items: center;
transform-style: preserve-3d;
pointer-events: none;
}
#z0 {
width: 50px;
height: 50px;
background: linear-gradient(
to right bottom,
rgb(223 223 223),
rgb(190 190 190)
);
transform: translateZ(0px);
position: absolute;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: black;
border-radius: 50%;
outline: 1px solid rgb(0 0 0 / 0.35);
pointer-events: all;
}
#perspectiveDot {
width: 4px;
height: 4px;
border-radius: 50%;
background-color: rgb(240 0 0 / 0.5);
transform: translate3d(-2px, -2px, 0px);
position: absolute;
}
#cube {
width: 100px;
height: 100px;
transform-style: preserve-3d;
transition: all 0.075s ease-out;
position: absolute;
pointer-events: all;
}
.face {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: absolute;
backface-visibility: inherit;
font-size: 60px;
color: white;
}
.front {
background: rgb(90 90 90 / 0.7);
transform: translateZ(50px);
}
.back {
background: rgb(0 210 0 / 0.7);
transform: rotateY(180deg) translateZ(50px);
}
.right {
background: rgb(210 0 0 / 0.7);
transform: rotateY(90deg) translateZ(50px);
}
.left {
background: rgb(0 0 210 / 0.7);
transform: rotateY(-90deg) translateZ(50px);
}
.top {
background: rgb(210 210 0 / 0.7);
transform: rotateX(90deg) translateZ(50px);
}
.bottom {
background: rgb(210 0 210 / 0.7);
transform: rotateX(-90deg) translateZ(50px);
}
.transformFieldset {
margin: 0;
}
.controlsContainer {
display: flex;
flex-direction: column;
align-items: start;
gap: 4px;
}
.controlsContainer {
width: 100%;
}
.controlsContainer > div {
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
}
.controlsContainer > div > label {
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
}
button {
font-size: 18px;
border-radius: 50%;
border: #ccc solid 1px;
padding: 0;
width: 26px;
height: 26px;
margin-left: 4px;
}
input[type="range"] {
width: 172px;
}
output {
width: 3em;
}
allTransformFieldset
.querySelectorAll("input[type='range']")
.forEach((rangeInput) => {
// Event listeners for when the range inputs change
rangeInput.addEventListener("input", (el) => {
updateTransform();
});
// Reset the relevant transform setting when the range input is double clicked
rangeInput.addEventListener("dblclick", (el) => {
resetInput(el.target);
updateTransform();
});
});
// Event listeners for when checkbox inputs change
allTransformFieldset
.querySelectorAll("input[type='checkbox']")
.forEach((checkboxInput) => {
checkboxInput.addEventListener("input", (el) => {
updateTransform();
});
});
// "Reset All" button event listener
resetAllButton.addEventListener("click", () => {
allTransformFieldset.querySelectorAll("input").forEach((input) => {
resetInput(input);
});
updateTransform();
});
// Section reset button event listeners
allTransformFieldset
.querySelectorAll(".resetSectionButton")
.forEach((resetSectionButton) => {
resetSectionButton.addEventListener("click", (el) => {
let allRanges = el.target.parentElement.parentElement.querySelectorAll(
"input[type='range']",
);
allRanges.forEach((range) => {
resetInput(range);
});
let allCheckboxes =
el.target.parentElement.parentElement.querySelectorAll(
"input[type='checkbox']",
);
allCheckboxes.forEach((check) => {
resetInput(check);
});
updateTransform();
});
});
const resetInput = (inputEl) => {
if (!inputEl) {
console.warn(`inputEl \`${inputEl}\` is falsy!`);
console.trace();
return;
}
const defaultValue = inputEl.getAttribute("data-default");
if (inputEl.getAttribute("type") === "checkbox") {
inputEl.checked = defaultValue === "checked";
} else {
inputEl.value = defaultValue || "0";
}
};
const updateOutputs = () => {
translateXOutput.value = `${translateXRange.value}px`;
translateYOutput.value = `${translateYRange.value}px`;
translateZOutput.value = `${translateZRange.value}px`;
rotateXOutput.value = `${rotateXRange.value}°`;
rotateYOutput.value = `${rotateYRange.value}°`;
rotateZOutput.value = `${rotateZRange.value}°`;
scaleXOutput.value = `${scaleXRange.value}x`;
scaleYOutput.value = `${scaleYRange.value}x`;
scaleZOutput.value = `${scaleZRange.value}x`;
skewXOutput.value = `${skewXRange.value}°`;
skewYOutput.value = `${skewYRange.value}°`;
perspectiveOutput.value = `${perspectiveRange.value}px`;
perspectiveOriginXOutput.value = `${perspectiveOriginXRange.value}%`;
perspectiveOriginYOutput.value = `${perspectiveOriginYRange.value}%`;
};
const updateTransform = () => {
updateOutputs();
cube.style.transform = `translate3d(${translateXRange.value}px,
${translateYRange.value}px,
${translateZRange.value}px)
rotateX(${rotateXRange.value}deg)
rotateY(${rotateYRange.value}deg)
rotateZ(${rotateZRange.value}deg)
scale3d(${scaleXRange.value},
${scaleYRange.value},
${scaleZRange.value})
skewX(${skewXRange.value}deg)
skewY(${skewYRange.value}deg)`;
cube.style.backfaceVisibility = `${backfaceVisibilityCheckbox.checked ? "visible" : "hidden"}`;
outputContainer.style.perspective = `${perspectiveRange.value}px`;
outputContainer.style.perspectiveOrigin = `${perspectiveOriginXRange.value}% ${perspectiveOriginYRange.value}%`;
perspectiveDot.style.top = `${perspectiveOriginYRange.value}%`;
perspectiveDot.style.left = `${perspectiveOriginXRange.value}%`;
};
updateTransform();
Sie können auch den perspective
-Schieberegler verwenden, um die perspective
-Eigenschaft des Behälters des Würfels anzupassen, die den Abstand zwischen Ihnen und der z=0
-Ebene bestimmt.
Die perspective-origin
-Schieberegler bestimmen, wo Sie als Betrachter in den 3D-Raum blicken, um den Fluchtpunkt der Ansicht zu bestimmen. Dieser Fluchtpunkt wird durch einen kleinen roten Punkt angezeigt. Sie können sich das Modifizieren dieser Schieberegler so vorstellen, als würden Sie Ihren Kopf physisch nach oben, unten, links und rechts bewegen, um verschiedene Teile des Würfels zu sehen, ohne den Würfel selbst zu bewegen.
Das backface-visibility
-Kontrollkästchen bestimmt, ob die Rückseiten des Würfels auf visible
oder hidden
gesetzt sind.
Der Würfel im obigen Beispiel besteht aus sechs -Elementen, die alle mit CSS gestylt sind, um die Flächen des Würfels zu erstellen. Der Würfel wird nicht in einem 2D- oder 3D-Canvas-Kontext gezeichnet, daher
können Sie die Flächen des Würfels mit den Entwicklertools Ihres Browsers inspizieren, wie Sie jedes andere DOM-Element inspizieren würden . Versuchen Sie, mit dem Element-Auswahl-Tool der Entwicklertools Ihres Browsers verschiedene Flächen des Würfels zu inspizieren, während Sie dessen Position und Rotation transformieren.
Hinweis:
Die Reihenfolge, in der Transformationen, einschließlich 3D-Rotationen, angewendet werden, beeinflusst die resultierende Transformation. Im obigen Beispiel werden die Transformationen übersetzt, skaliert, rotiert und dann geneigt. Die Rotationen werden in der Reihenfolge X → Y → Z angewendet.
CSS-Eigenschaften:
Datentypen:
Glossarbegriffe:
SVG -Konzepte: