likes
comments
collection
share

如何用css做一个打印机🖨️?

作者站长头像
站长
· 阅读数 60

先看效果

在表单中输入https://source.unsplash.com/random或其他图片url试试吧~

用css制作3d场景, 一般情况下都是长方体的组合。其实没有想的那么复杂,大家有兴趣可以看看用 CSS 制作 3D 这篇文章。

而要制作一个长方体,我们可以使用 CSS 属性transform-style. 将此设置为preserve-3d允许我们在第三维上转换元素:

现在我们可以利用 CSS 自定义属性来定义长方体的属性(如上面代码片段) 使用自定义属性,我们可以控制长方体的各种特征,等等:

  • --width: 平面上长方体的宽度
  • --height: 平面上长方体的高度
  • --depth: 平面上长方体的深度
  • --x: 平面上的 X 位置
  • --y: 平面上的 Y 位置

知道了相关的操作我们便可以开始制作一个打印机🖨️demo了

先来一个demo

首先,我们可以搭建出我们需要的所有部分,首先可以尝试将所有内容可视化成为一个个盒子。

// 结构大概是这样
.scene
  .printer //打印机
    .printer__side.printer__side--left 
    .printer__side.printer__side--right
    .printer__tray.printer__tray--bottom
    .printer__tray.printer__tray--top
    .printer__top
    .printer__back

基本的框架就像这样 代码上可以看到其实就是一个个的立方体拼接起来的,值得一提如果你使用Dat.GUI可以很方便调整这些参数

再加点细节

为了让你的打印机更真实,我们可以用css来添加: 例如打印机的顶部你可以加一个你的logo,打印机的开口等等......

渐变处理打印机的开启和细节:

.cuboid--top {
  --thickness: var(--depth);
  --shade-one: linear-gradient(#292929, #292929) 100% 50%/14% 54% no-repeat, linear-gradient(var(--p-7), var(--p-7)) 40% 50%/12% 32% no-repeat, linear-gradient(var(--p-7), var(--p-7)) 30% 50%/2% 12% no-repeat, linear-gradient(var(--p-3), var(--p-3)) 0% 50%/66% 50% no-repeat, var(--p-1);
}

还可以用 background-image 来做一个伪元素将其定位到打印机顶部来做打印机的log:

.cuboid--top > div:nth-of-type(1):after {
  content: '';
  position: absolute;
  top: 7%;
  left: 10%;
  height: calc(var(--depth) * 0.12vmin);
  width: calc(var(--depth) * 0.12vmin);
  background: url("https://avatars.githubusercontent.com/u/36911813?s=400&u=102d1c03c513387ec81e0645738f654b23470ad7&v=4");
  background-size: cover;
  transform: rotate(90deg);
  filter: grayscale(0.5);
}

纸张飞舞📄

有了打印机怎么能没纸呢,同理 我们可以用长方体来当作纸,然后使用多个堆叠就是纸堆啦,而我们要的效果是纸张从打印机进入 然后打印出我们想要的东西。样式如下

:root {
  --load-speed: 2;
}

.paper-stack--top .cuboid--paper .paper {
  animation: transfer calc(var(--load-speed) * 0.5s) ease-in-out forwards;
}
.paper-stack--top .cuboid--paper .paper__flyer {
  animation: fly calc(var(--load-speed) * 0.5s) ease-in-out forwards;
}
.paper-stack--top .cuboid--paper .paper__flyer:after {
  animation: feed calc(var(--load-speed) * 0.5s) calc(var(--load-speed) * 0.5s) forwards;
}

@keyframes transfer {
  to {
    transform: translate(0, -270%) rotate(22deg);
  }
}

@keyframes feed {
  to {
    transform: translate(100%, 0);
  }
}

@keyframes fly {
  0% {
    transform: translate3d(0, 0, 0) rotateY(0deg) translate(0, 0);
  }
  50% {
    transform: translate3d(140%, 0, calc(var(--height) * 1.2)) rotateY(-75deg) translate(180%, 0);
  }
  100% {
    transform: translate3d(140%, 0, var(--height)) rotateY(-75deg) translate(0%, 0) rotate(-180deg);
  }
}

我们可以使用 CSS 自定义属性。来计算每个动画的正确延迟。纸张同时旋转和移动。一个动画处理移动容器,另一个动画处理旋转纸张。等动画结束,纸张就会被送入打印机,而动画延迟等于前两个动画的持续时间。然后纸张被定位到该元素的边缘。

这里分别标记了几个颜色来区别不同的元素,你可以更好的看到他是如何工作的

打印时间到

打印机当然是需要能够打印东西啦,这里我们接受一个图片的url,例如(source.unsplash.com/random)当然你也可以用其他的

获得图像源后,我们将预览图像src设置为该URL的值并重置表单的输入值,我们可以监听预览图像的“load”事件。当事件触发时,我们为要打印的纸创建一个新元素并将其附加到printer元素上。

PREVIEW.addEventListener('load', () => {
  PRINTER.classList.add('printing')
  const PRINT = document.createElement('div')
  PRINT.className = 'printed'
  PRINT.innerHTML = `
    <div class="printed__spinner">
      <div class="printed__paper">
        <div class="printed__papiere">
          <img class="printed__image" src=${PREVIEW.src}/>
        </div>
      </div>
      <div class="printed__paper-back"></div>
    </div>
  `
  PRINTER.appendChild(PRINT)
  // 过几秒再把打印机重置回待打印状态
  setTimeout(() => {
    printing = false
    SUBMIT.removeAttribute('disabled')
    PRINTER.classList.remove('printing')
  }, 4500)
})

你甚至可以加个指示灯表示正在打印中

.progress-light {
  background: hsla(var(--progress-hue, 104), 80%, 50%);
}
.printing {
  --progress-hue: 10; /* Equates to red */
}

如此你的打印机就制作完成啦

转载自:https://juejin.cn/post/7156436852176584717
评论
请登录