摆烂哥教你用CSS绘制一支童年玩具枪枪

2,755 阅读3分钟

“我正在参加 码上掘金体验活动,详情:show出你的创意代码块

概述

没成想掘金也有在线代码平台了,垂死病中惊坐起,这得把我的压箱底货色拿出来了,很早之前在学习 clip-path 时,和小伙伴一起设计过童年玩具枪,本文就记录一下当时设计玩具枪的一些想法。纯 CSS ,纯度极高

代码展示

其实玩具枪的实现不算太难,我们先将玩具枪的各个部件展开,看一下各部分的组成。

whole

可以看到玩具枪共有 7 部分组成,我们绘制完玩具枪 7 部分后,然后通过定位将其组装起来,最后配上简单的动画就能实现封面的玩具枪效果。

下面首先看一下大致的代码结构,然后通过玩具枪托来进行讲解,其余部分的实现都是类似的,就不重复讲解了。

HTML 结构

首先我们来看一下 HTML 部分的结构:

<!-- 与上图七部分一一对应 -->
<div class="camera -x">
  <!-- 玩具枪 -->
  <div class="main">
    <!-- 1.玩具枪主体 -->
    <div class="gun-body"></div>
    <!-- 玩具枪头部 -->
    <div class="gun-front">
      <!-- 2.玩具枪头部内部 -->
      <div class="gun-inner"></div>
      <!-- 3.玩具枪头部中部 -->
      <div class="gun-mid"></div>
      <!-- 4.玩具枪头 -->
      <div class="gun-forend"></div>
    </div>
    <!-- 5.玩具枪托 -->
    <div class="butt">
      <!-- 开关 -->
      <div class="gun-go"></div>
      <div class="butt-body"></div>
    </div>
    <!-- 6.玩具枪支横梁 -->
    <div class="gun-beam"></div>
    <!-- 7.玩具枪 -->
    <div class="gun-switch"></div>
  </div>
</div>

玩具枪托部分

clip-path

玩具枪托比较难以实现,文章就以玩具枪托为切入点,由点及面,绘制玩具枪。

butt

CSS 中有个 clip-path 属性,这个属性可以用来裁剪图像。(这个属性的本质就是裁剪路径)

我们来简单尝试下这个语法(案例来源于:developer.mozilla.org/zh-CN/docs/…

clip-path 可以裁剪多种图形:

  1. circle 定义圆形

语法: circle( [ <shape-radius> ]? [ at <position> ]? )

参数:

  • shape-radius 圆半径,支持百分比
  • position 圆心位置,默认为元素中心点
  1. ellipase 定义椭圆

语法: ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )

参数:

  • shape-radius 椭圆的 x 轴与 y 轴半径
  • position: 椭圆中心,默认元素中心点
  1. polygon 定义多边形等

语法: polygon( <fill-rule>? , [ <length-percentage> <length-percentage> ]# )

参数:

  • fill-rule 内部元素的填充规则,可能的值有 nonzero 和 evenodd,默认值是 nonzero
  • 后续每对参数都是连接点,大家如果有过 CAD 经验,这个就相当于每次绘制一条曲线,然后多个点连接成一个封闭图形。

下面我们来稍微演示一下:

<!-- 三个demo分别使用三种情况 -->
<div class="container">
  <div class="demo"></div>
  <div class="demo"></div>
  <div class="demo"></div>
</div>
.demo:nth-of-type(1) {
  clip-path: circle(25%);
}
.demo:nth-of-type(2) {
  clip-path: ellipse(130px 140px at 10% 20%);
}
.demo:nth-of-type(3) {
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}

demo

从第三个图我们还可以发现,使用 polygon 语法时,默认的原点为左上角。

绘制枪托

枪托部分就是基于 cli-path 的 polygon 实现的,我们先来绘制一下 butt-body。

预先测量获得想要绘制的多边形的参数,然后只需要将对应点坐标写入 clip-path 即可。

.butt .butt-body {
  width: 220px;
  height: 220px;
  background: #1e1e1e;
  clip-path: polygon(
    0 0,
    21px 0,
    30px 15px,
    60px 15px,
    100px 0,
    190px 0,
    220px 15px,
    185px 65px,
    220px 140px,
    220px 190px,
    130px 220px,
    110px 210px,
    140px 160px,
    115px 100px,
    0 120px,
    0 110px,
    80px 95px,
    85px 70px,
    70px 50px,
    20px 50px
  );
}

butt-body

玩具枪托部分就成功实现了。

剩下与原图的区别就在于当前代码并没有立体效果,那立体效果是如果实现的呐?

CSS 中实现 div 的立体效果的最简单方式是 box-shadow ,但我们的枪支,我们想的是整体实现立体效果,于是我们可以使用 drop-shadow 属性。

在 main 部分,添加 drop-shadow 配置

.main {
  filter: drop-shadow(5px 5px 0 #000) drop-shadow(
      5px 15px 10px rgba(0, 0, 0, 0.2)
    );
}

butt-body-filter

立体效果这不就实现了吗?收工收工!!!

总结

其余玩具枪部分都是基于 clip-path 实现的,剩下的部分的实现代码大家可以去码上掘金中阅读和修改,本文就到这里了,谢谢大家的阅读。