如何在CSS3 3D变换中匹配真实照片和对象的3D透视图

马拉科斯

情况:

在我的特殊情况下,我有3D相框图像和2D照片。我希望使用CSS3转换功能(旋转,缩放,倾斜)将2D照片与3D帧匹配。

问题:

我无法使用手动方法(也就是键入旋转值并观察其作用)精确地将两者匹配。

理想解决方案#1

存在在线可视化工具,该工具可以让您拖动照片的各个角(就像photoshop一样),并且可以为您提供正确的CSS3变换值。

理想的解决方案#2

存在非可视工具-与以前一样,但是您手动输入4个点坐标(图像角),它为您提供正确的CSS3变换值。

真正解决这个问题

如果没有这样的工具(我的搜索没有找到),我希望有人尝试解释一下其背后的数学,以便我自己计算-甚至可能吗?

我为您准备了JSFiddle演示,供您摆弄:演示

/* Main issue here */

.transform {
  transform: rotateX(34deg) rotateZ(13deg) rotateY(-10deg) scaleY(1) scaleX(1) skewY(0deg) skewX(0deg) translateY(0px) translateX(20px);
  transform-origin: 50% 0% 0;
}
/* Supporting styles */

.container {
  position: relative;
  width: 500px;
  height: 500px;
}
.frame,
.photo {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.photo {
  top: 50px;
  left: 95px;
  right: 65px;
  bottom: 270px;
}
.frame img,
.photo img {
  width: 100%
}
.frame {
  z-index: 2;
}
<div class="container">

  <div class="frame">
    <img src="http://cdn.idesigned.cz/img/cc08acc7b9b08ab53bf935d720210f13.png" />
  </div>

  <div class="photo">
    <div class="transform">
      <img src="https://static.pexels.com/photos/7976/pexels-photo.jpg" />
    </div>
  </div>

</div>

更多的

如果您可以使用3-d转换(例如rotateZ),则还可以提供matrix3d可以根据所需的点对应关系进行计算的值。

这是一个小提琴:https : //jsfiddle.net/szym/03s5mwjv/

我使用numeric.js解决一组4个线性方程找到透视变换矩阵变换srcdst这基本上与getPerspectiveTransformOpenCV中的数学相同

计算出的2-d透视变换是使用齐次坐标的3x3矩阵CSSmatrix3d是使用齐次坐标的4x4矩阵,因此我们需要z为轴添加一个标识行/列此外,matrix3d以列优先顺序指定。

一旦获得,matrix3d就可以将其粘贴到样式表中。但是请记住,矩阵是在假设(0, 0)为原点的情况下计算的,因此您还需要设置transformOrigin: 0 0

// Computes the matrix3d that maps src points to dst.
function computeTransform(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 homogeneous 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
  ];
  var transform = "matrix3d(";
  for (var i = 0; i < m.length - 1; ++i) {
    transform += m[i] + ", ";
  }
  transform += m[15] + ")";
  return transform;
}

// Collect the four corners by user clicking in the corners
var dst = [];
document.getElementById('frame').addEventListener('mousedown', function(evt) {
  // Make sure the coordinates are within the target element.
  var box = evt.target.getBoundingClientRect();
  var point = [evt.clientX - box.left, evt.clientY - box.top];
  dst.push(point);

  if (dst.length == 4) {
    // Once we have all corners, compute the transform.
    var img = document.getElementById('img');
    var w = img.width,
        h = img.height;
    var transform = computeTransform(
      [
        [0, 0],
        [w, 0],
        [w, h],
        [0, h]
      ],
      dst
    );
    document.getElementById('photo').style.visibility = 'visible';
    document.getElementById('transform').style.transformOrigin = '0 0';
    document.getElementById('transform').style.transform = transform;
    document.getElementById('result').innerHTML = transform;
  }
});
.container {
  position: relative;
  width: 50%;
}
  
#frame,
#photo {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
  
#photo {
  visibility: hidden;
}
  
#frame img,
#photo img {
  width: 100%
}
  
#photo {
  opacity: 0.7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeric/1.2.6/numeric.min.js"></script>
  <p id="result">Click the desired top-left, top-right, bottom-right, bottom-left corners
  <div class="container">
    <div id="frame">
      <img src="http://cdn.idesigned.cz/img/cc08acc7b9b08ab53bf935d720210f13.png" />
    </div>

    <div id="photo">
      <div id="transform">
        <img id="img" src="http://placehold.it/350x150" />
      </div>
    </div>

  </div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在CSS3中反向3D旋转-透视图起源,变换起源?

来自分类Dev

如何使用CSS3创建3D透视图?

来自分类Dev

使用JQuery Slideshow中的透视图进行3D旋转

来自分类Dev

使用JQuery Slideshow中的透视图进行3D旋转

来自分类Dev

如何在3D空间中实现2D透视图(CSS&jQuery)

来自分类Dev

3D矩阵透视变换

来自分类Dev

了解3D Core Animation中的透视变换

来自分类Dev

了解 3D Core Animation 中的透视变换

来自分类Dev

旋转时的CSS 3D多维数据集透视图

来自分类Dev

旋转时的CSS 3D多维数据集透视图

来自分类Dev

如何计算3D转换元素的大小(带有透视图)?

来自分类Dev

如何用一个元素创建3D透视图图像?

来自分类Dev

如何计算3D转换元素的大小(带有透视图)?

来自分类Dev

CSS3变换透视图在FF或IE中不起作用-摆动效果

来自分类Dev

CSS3透视图裁剪

来自分类Dev

3d 向量 - 变换和减法

来自分类Dev

关于3D透视投影和矩阵变换的一些知识

来自分类Dev

3D变换div

来自分类Dev

如何在mplot3d中禁用透视图?

来自分类Dev

如何在mplot3d中禁用透视图?

来自分类Dev

3D CSS变换元素定位

来自分类Dev

CSS滤镜打破3D变换

来自分类Dev

3D旋转-透视

来自分类Dev

如何在CSS3中创建此按钮?

来自分类Dev

如何在CSS3中实现梯形?

来自分类Dev

如何在CSS3中覆盖伪类

来自分类Dev

如何在CSS3中制作闪烁的图像

来自分类Dev

如何在CSS3中创建阴影边框?

来自分类Dev

如何在 CSS3 中创建对角线带?