如何使用 css 透视来匹配 div 以在视觉上适合 svg 笔记本电脑屏幕?

How to use css perspective to match a div to visually fit inside a svg laptop screen?

我确定这个问题已经令人困惑了。本质上,我想使用 css 绝对定位 div 的透视图,使其看起来像是在我用 svg 创建的笔记本电脑屏幕内部。

我相信使用 perspectiverotateX()rotateY() 的某种组合是可能的,但似乎不太正确。

See this Codepen

这是相关的 css:

.container {
    perspective: 500px;
}
.screenContents {
    transform: rotateX(10deg) rotateY(-10deg);
    /* 16:9 ratio to calculate size */
    --scale: 36;
    width: calc(16px * var(--scale));
    height: calc(9px * var(--scale));
    position: absolute;
    top: 30px;
    left: 300px;
}

Html:

<div class='container'>
    <div class='screenContents'>Screen Contents</div>
</div>
<img src='device.svg' />

我尝试过的其他一些事情是使用 rotateZ()

设置 perspective-origin and/or

SVG 尺寸和信息

如果有用,这里是我根据 svg 计算的一些屏幕尺寸:

area: 1529 sq pixels

(根据每个角点计算出的宽高)

width: ~500px
height: ~350px

我用来求高宽面积的svg画面各点坐标:

top left: 382,514
top right: 882,503
bottom left: 312,187
bottom right: 816,151

此外,svg 只是 Google Pixel Go 笔记本电脑的描摹图,屏幕尺寸为 13.3",比例为 16:9

我觉得这些尺寸必须以某种方式包含在最终计算中。

总结

我想将 div 放置在笔记本电脑屏幕上。我不知道如何正确地做到这一点,可以使用一些指针或疯狂的天才来为我创建一个解决方案。使用 codepen 来解决它。

那么,有没有 css 专家可以提供帮助????

低于CSS

.container {
/*   perspective: 500px; */
}

.screenContents {
 transform: perspective(3651px) rotateY(-30deg) rotateX(18deg) rotate(3deg);
 --scale: 37;
 width: calc(16px * var(--scale));
 height: calc(10px * var(--scale));
}

我创建了一个基于 by @szym 的演示,它使用矩阵计算来获得精确拟合。

我已经创建了一个更好的演示,可以作为一个独立的工具(我将来可能会创建一个),其中有 4 个点可以拖动。该演示使用 jQuery 终端作为 div,但您可以使用任何元素并将其放入图像中。该工具将为您提供 CSS 需要用来将元素放入图像中的信息。元素的大小(宽度和高度)应相似,以免被拉伸或压扁。

该答案的基本解决方案是矩阵计算:

// Computes the matrix3d that maps src points to dst.
function compute_transform(src, dst) {
  // src and dst should have length 4 each
  var count = 4;
  var a = []; // (2*count) x 8 matrix
  var b = []; // (2*count) vector

  for (var i = 0; i < 2 * count; ++i) {
    a.push([0, 0, 0, 0, 0, 0, 0, 0]);
    b.push(0);
  }

  for (var i = 0; i < count; ++i) {
    var j = i + count;
    a[i][0] = a[j][3] = src[i][0];
    a[i][1] = a[j][4] = src[i][1];
    a[i][2] = a[j][5] = 1;
    a[i][3] = a[i][4] = a[i][5] =
      a[j][0] = a[j][1] = a[j][2] = 0;
    a[i][6] = -src[i][0] * dst[i][0];
    a[i][7] = -src[i][1] * dst[i][0];
    a[j][6] = -src[i][0] * dst[i][1];
    a[j][7] = -src[i][1] * dst[i][1];
    b[i] = dst[i][0];
    b[j] = dst[i][1];
  }

  var x = numeric.solve(a, b);
  // matrix3d is homogenous coords in column major!
  // the z coordinate is unused
  var m = [
    x[0], x[3], 0, x[6],
    x[1], x[4], 0, x[7],
    0, 0, 1, 0,
    x[2], x[5], 0, 1
  ];
  return "matrix3d(" + m.join(',') + ')';
}

// the array should have all 4 points
// of the rectangle on the image
var points = []; 

function transform_terminal() {
    var w = geometry.width + 20,
        h = geometry.height + 20;
    var transform = compute_transform(
        [
            [0, 0],
            [w, 0],
            [w, h],
            [0, h]
        ],
        points
    );
    function format(klass, left, top) {
        return `
.${klass} {
   left: ${left}px;
   top: ${top}px;
}`.trim();
    }
    const point_css = $('.point').map(function() {
        var {left, top} = $(this).position();
        var klas = $(this).attr('class').replace(/point /, ''); 
        return format(klas, left, top);
    }).get().join('\n');
    $('.output pre').html(`
.terminal {
    transform: ${transform};
}
/* optional control points */
${point_css}`.trim())
    term.css({
        '--transform': transform
    });
}

代码使用numeric library求解一个线性方程得到矩阵

这是演示:https://codepen.io/jcubic/pen/PojPbZz