#showpart { @include flexbox(row, nowrap, center, center); width: 90vw; height: 90vw; max-width: torem(500px); max-height: torem(500px); border: 1px solid color(black); .box { color: color(white); font-size: torem(20px); &.box--2d { --transform-translate-x: 0; --transform-translate-y: 0; --transform-rotate: 0deg; --transform-scale: 1; --transform-skew-x: 0deg; --transform-skew-y: 0deg; display: none; background-color: color(blue); transform: translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) scale(var(--transform-scale), var(--transform-scale)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)); &.box--active { @include flexbox(row, nowrap, center, center); width: 32vw; height: 32vw; max-width: torem(180px); max-height: torem(180px); } } &.box--3d { --transform-perspective: 1000px; --transform-perspective-origin-x: 150%; --transform-perspective-origin-y: 150%; --transform-transform-style: preserve-3d; --transform-transform-origin-x: 50%; --transform-transform-origin-y: 50%; --transform-backface-visibility: visible; display: none; perspective: var(--transform-perspective); perspective-origin: var(--transform-perspective-origin-x) var(--transform-perspective-origin-y); &.box--active { @include flexbox(row, nowrap, center, center); width: 100%; height: 100%; } .cube { --transform-width: #{torem(160px)}; --transform-half-width: #{torem(80px)}; position: relative; width: var(--transform-width); height: var(--transform-width); transform-style: var(--transform-transform-style); .face { @include flexbox(row, nowrap, center, center); position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform-origin: var(--transform-transform-origin-x) var(--transform-transform-origin-y); backface-visibility: var(--transform-backface-visibility); } .front { background-color: rgba(142, 53, 87, 0.7); transform: translateZ(var(--transform-half-width)); } .back { background-color: rgba(51, 204, 204, 0.7); transform: rotateY(180deg) translateZ(var(--transform-half-width)); } .top { background-color: rgba(255, 204, 0, 0.7); transform: rotateX(90deg) translateZ(var(--transform-half-width)); } .bottom { background-color: rgba(0, 153, 51, 0.7); transform: rotateX(-90deg) translateZ(var(--transform-half-width)); } .left { background-color: rgba(221, 17, 68, 0.7); transform: rotateY(-90deg) translateZ(var(--transform-half-width)); } .right { background-color: rgba(255, 51, 0, 0.7); transform: rotateY(90deg) translateZ(var(--transform-half-width)); } } } } } .transform { .form { display: none; &.form--active { @include flexbox(column); } .inputArea { @include flexbox(row, nowrap, flex-start, center); flex: 0 0 torem(32px); .label { flex: 0 0 auto; min-width: torem(150px); // 2d &.label--translateX { &::after { content: 'translateX(' attr(data-value) 'px)'; } } &.label--translateY { &::after { content: 'translateY(' attr(data-value) 'px)'; } } &.label--rotate { &::after { content: 'rotate(' attr(data-value) 'deg)'; } } &.label--scale { &::after { content: 'scale(' attr(data-value) ')'; } } &.label--skewX { &::after { content: 'skewX(' attr(data-value) 'deg)'; } } &.label--skewY { &::after { content: 'skewY(' attr(data-value) 'deg)'; } } // 3d &.label--perspective { &::after { content: 'perspective: ' attr(data-value); } } &.label--perspective-origin { &::after { content: 'perspective-origin: ' attr(data-value-x) '% ' attr(data-value-y) '%'; } } &.label--transform-style { &::after { content: 'transform-style: ' attr(data-value); } } &.label--transform-origin { &::after { content: 'transform-origin: ' attr(data-value-x) '% ' attr(data-value-y) '%'; } } &.label--backface-visibility { &::after { content: 'backface-visibility: ' attr(data-value); } } } } } }
import { Group } from 'zp-ui'; window.$ = document.querySelector.bind(document); window.$$ = document.querySelectorAll.bind(document); const MAP = { translateX: { unit: 'px', prop: '--transform-translate-x', }, translateY: { unit: 'px', prop: '--transform-translate-y', }, rotate: { unit: 'deg', prop: '--transform-rotate', }, scale: { unit: '', prop: '--transform-scale', }, skewX: { unit: 'deg', prop: '--transform-skew-x', }, skewY: { unit: 'deg', prop: '--transform-skew-y', }, perspective: { unit: 'px', prop: '--transform-perspective', }, 'perspective-origin': { unit: '%', prop: '--transform-perspective-origin', }, 'transform-style': { unit: '', prop: '--transform-transform-style', }, 'transform-origin': { unit: '%', prop: '--transform-transform-origin', }, 'backface-visibility': { unit: '', prop: '--transform-backface-visibility', }, }; const selectObserver = () => { const boxActive = 'box--active'; const formActive = 'form--active'; return { /** * 模式更改的样式设定 */ update({ mode }) { const box2d = $('.box--2d'); const form2d = $('.form--2d'); const box3d = $('.box--3d'); const form3d = $('.form--3d'); if (mode === '3d') { box2d.classList.remove(boxActive); form2d.classList.remove(formActive); box3d.classList.add(boxActive); form3d.classList.add(formActive); } else { box2d.classList.add(boxActive); form2d.classList.add(formActive); box3d.classList.remove(boxActive); form3d.classList.remove(formActive); } }, }; }; const form2dObserver = () => ({ update({ label, value }) { const result = value + MAP[label].unit; // 修改 $('.box--2d').style.setProperty(MAP[label].prop, result); $(`.form--2d .label--${label}`).dataset.value = value; }, }); const form3dObserver = () => ({ update({ label: tmpLabel, group, value }) { let suffix = ''; let label = tmpLabel; if (group && group === 'double') { suffix = label.slice(-2); label = label.slice(0, -2); } const result = value + MAP[label].unit; // 修改 $('.box--3d').style.setProperty(MAP[label].prop + suffix, result); $(`.form--3d .label--${label}`).dataset[`value${suffix.slice(-1).toUpperCase()}`] = value; }, }); const createHandler = ({ select, form2d, form3d }) => ({ /** * 模式切换 */ switchMode: ({ target }) => { const { value } = target; select.setState({ mode: value }); }, /** * 2d表单 */ setValue2D: ({ target }) => { const { value } = target; form2d.setState({ label: target.getAttribute('id'), value, }); }, /** * 3d表单 */ setValue3D: ({ target }) => { const { value, dataset: { group }, } = target; form3d.setState({ label: target.getAttribute('id'), group, value, }); }, }); document.addEventListener('DOMContentLoaded', () => { const select = new Group('select'); select.attach(selectObserver()); const form2d = new Group('form2d'); form2d.attach(form2dObserver()); const form3d = new Group('form3d'); form3d.attach(form3dObserver()); const handler = createHandler({ select, form2d, form3d }); $('#select').addEventListener('change', handler.switchMode, false); $('.form--2d').addEventListener('change', handler.setValue2D, false); $('.form--3d').addEventListener('change', handler.setValue3D, false); // init select.setState({ mode: '2d' }); }, false);