RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 796675
Accepted
Alexandr_TT
Alexandr_TT
Asked:2020-03-12 01:06:06 +0000 UTC2020-03-12 01:06:06 +0000 UTC 2020-03-12 01:06:06 +0000 UTC

如何制作图标动画 - 破碎的心

  • 772

我有两个心形图标——完整的和破碎的。

在此处输入图像描述 在此处输入图像描述

有必要制作图标从一种状态到另一种状态的过渡动画。
从图中可以看出,动画被简化为心脏的一半相对于另一半围绕一个共同点旋转。

单击图标时需要开始动画。

javascript
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Alexandr_TT
    2020-03-12T01:06:06Z2020-03-12T01:06:06Z

    要实现动画,您需要绘制一条断层线和两半图标。

    • 我们获取第一个图标并将其加载到矢量编辑器中。

    • 使用工具 - 绘制贝塞尔曲线和直线 - 在此处输入图像描述

      画断线

    在此处输入图像描述

    • 使用相同的工具,我们画出心脏左半边的轮廓,然后再次画出轮廓,但画出心脏的右半边。每次我们使轮廓闭合。
    • 将文件保存Heart.svg在矢量编辑器中
    • 从文件中复制心脏左右两半的补丁。

    下面是右半部分的示例

    <svg id="heart" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200" viewBox="0 0 100 100">
    <style>
    #right-half{
     fill:#dc143c;
    }
    </style> 
      <g>
        <path id="right-half"  d="M63.9 24C58.5 24 53.5 27 50.2 32.5 49.8 35.3 50.5 40.6 50.5 40.6L48.8 45.2 53.8 49.7 47.6 55.5 54 57.8 49.8 61.6C49.7 69.1 50.2 69 50.1 75.4 50.1 75.4 50.2 75.7 50.2 75.7 50.6 75.7 51 75.5 51.1 75.1 53 70.1 58 66.3 63.4 62.2 70.9 56.5 78.6 50.7 79.2 41.1 79.4 36.4 77.9 32 74.8 28.8 73.5 27.4 72 26.3 70.4 25.5 68.4 24.5 66.1 24 63.9 24z"/>
      </g>
    </svg>

    图标的左半部分

    <svg id="heart" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200" viewBox="0 0 100 100">
    <style>
    #left-half{
     fill:#dc143c;
    }
    </style> 
      <g >
        <path  id="left-half" d="m50.1 75.4c0 0 0.1 0.3 0.1 0.3-0.4 0-0.8-0.3-0.9-0.7-1.9-5.1-7-9-12.4-13-7.3-5.5-14.9-11.2-15.6-20.9-0.3-4.5 1.1-8.8 4.2-12 3-3.2 7.2-5.1 11.5-5.1 5.5 0 10.3 3.1 13.4 8.5-0.4 2.9 0.3 8.1 0.3 8.1l-1.7 4.6 5 4.5-6.2 5.8 6.4 2.4-4.2 3.8c0 7.4 0.4 7.4 0.3 13.7z" />
      </g>
    </svg>

    • 我们将心脏的两半连接到一个文件中,并开始为两半编写动画代码。

    编写动画代码

    动画非常简单 - 两半围绕不同方向的公共点旋转。
    要顺时针旋转右半部分,请使用以下命令:

    <animateTransform id="break" attributeName="transform" type="rotate"
     begin="heart.click" dur="1s" repeatCount="1" values="0 50 75.7;7 50 75.7" 
    
    fill="freeze" restart="whenNotActive"/>
    

    动画开始 -begin="heart.click"

    7 градусов绕坐标点旋转50 75.7-values="0 50 75.7;7 50 75.7"

    对于左半部分,旋转将围绕同一点,但逆时针。因此,旋转角度会有一个负值:

    values="0 50 75.7;-7 50 75.7"

    把它们放在一起:

    <svg id="heart" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200" viewBox="0 0 100 100">
    <style>
    #right-half, #left-half{
     fill:#dc143c;
    }
    </style> 
    <title>To break heart</title>
      <g>
        <path id="right-half"  d="M63.9 24C58.5 24 53.5 27 50.2 32.5 49.8 35.3 50.5 40.6 50.5 40.6L48.8 45.2 53.8 49.7 47.6 55.5 54 57.8 49.8 61.6C49.7 69.1 50.2 69 50.1 75.4 50.1 75.4 50.2 75.7 50.2 75.7 50.6 75.7 51 75.5 51.1 75.1 53 70.1 58 66.3 63.4 62.2 70.9 56.5 78.6 50.7 79.2 41.1 79.4 36.4 77.9 32 74.8 28.8 73.5 27.4 72 26.3 70.4 25.5 68.4 24.5 66.1 24 63.9 24z">
          <animateTransform id="break" attributeName="transform" type="rotate" begin="heart.click" dur="1s" repeatCount="1" values="0 50 75.7;7 50 75.7" fill="freeze" restart="whenNotActive"/>
        </path>
      </g>
      <g>
        <path  id="left-half" d="m50.1 75.4c0 0 0.1 0.3 0.1 0.3-0.4 0-0.8-0.3-0.9-0.7-1.9-5.1-7-9-12.4-13-7.3-5.5-14.9-11.2-15.6-20.9-0.3-4.5 1.1-8.8 4.2-12 3-3.2 7.2-5.1 11.5-5.1 5.5 0 10.3 3.1 13.4 8.5-0.4 2.9 0.3 8.1 0.3 8.1l-1.7 4.6 5 4.5-6.2 5.8 6.4 2.4-4.2 3.8c0 7.4 0.4 7.4 0.3 13.7z" >
          <animateTransform attributeName="transform" type="rotate" begin="heart.click" dur="1s" repeatCount="1" values="0 50 75.7;-7 50 75.7" fill="freeze" restart="whenNotActive"/>
        </path>
      </g>
    </svg>

    单击图标时动画开始

    带有反向啄食的动画选项

    <svg id="heart" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200" viewBox="0 0 100 100">
    <style>
    #right-half, left-half{
     fill:#dc143c;
    }
    </style> 
    <title>Icon to break and collect</title>
      <g>  
        <path id="right-half"  d="M63.9 24C58.5 24 53.5 27 50.2 32.5 49.8 35.3 50.5 40.6 50.5 40.6L48.8 45.2 53.8 49.7 47.6 55.5 54 57.8 49.8 61.6C49.7 69.1 50.2 69 50.1 75.4 50.1 75.4 50.2 75.7 50.2 75.7 50.6 75.7 51 75.5 51.1 75.1 53 70.1 58 66.3 63.4 62.2 70.9 56.5 78.6 50.7 79.2 41.1 79.4 36.4 77.9 32 74.8 28.8 73.5 27.4 72 26.3 70.4 25.5 68.4 24.5 66.1 24 63.9 24z">
          <animateTransform  id="break"
            attributeName="transform"
            type="rotate"
            begin="heart.click"
            dur="1s"
            repeatCount="1"
            values="0 50 75.7;7 50 75.7"
            fill="freeze"
            restart="whenNotActive"/>
          <animateTransform
            attributeName="transform"
            type="rotate"
            begin="break.end+1.5s"
            dur="1s" repeatCount="1"
            values="7 50 75.7;0 50 75.7"
            fill="freeze"
            restart="whenNotActive"/>
        </path>
      </g>
      <g>
        <path  id="right-half" d="m50.1 75.4c0 0 0.1 0.3 0.1 0.3-0.4 0-0.8-0.3-0.9-0.7-1.9-5.1-7-9-12.4-13-7.3-5.5-14.9-11.2-15.6-20.9-0.3-4.5 1.1-8.8 4.2-12 3-3.2 7.2-5.1 11.5-5.1 5.5 0 10.3 3.1 13.4 8.5-0.4 2.9 0.3 8.1 0.3 8.1l-1.7 4.6 5 4.5-6.2 5.8 6.4 2.4-4.2 3.8c0 7.4 0.4 7.4 0.3 13.7z" >
          <animateTransform
            attributeName="transform"
            type="rotate"
            begin="heart.click"
            dur="1s"
            repeatCount="1"
            values="0 50 75.7;-7 50 75.7"
            fill="freeze"
            restart="whenNotActive"/>
          <animateTransform
            attributeName="transform"
            type="rotate"
            begin="break.end+1.5s"
            dur="1s"
            repeatCount="1"
            values="-7 50 75.7;0 50 75.7"
            fill="freeze"
            restart="whenNotActive"/>
        </path>
      </g>
    </svg>

    • 13
  2. Best Answer
    Sevastopol'
    2022-05-01T17:07:26Z2022-05-01T17:07:26Z

    css

    实现如下:

    1. 使用属性绘制两颗心border-radius
    2. 将心放在彼此之上
    3. 使用属性clip-path: polygon(),指定断层线应该通过的必要坐标,我们将两半截断
    4. 当悬停在一个普通容器上时,使用属性rotate,我们应用旋转动画,属性translateX将元素水平移动到不同的方向

    悬停动画:

    body {display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0;}
    
    .container {position: relative; width: 200px; height: 165px;}
    
    .heart__one, .heart__two {
      position: absolute; top: 0; left: 0; width: 200px; height: 165px; transition: all 2s 1s;
    }
    
    .heart__one {
      clip-path: polygon( 0 0, 100px 0, 100px 40px, 90px 63px, 110px 80px, 90px 100px, 110px 120px, 100px 140px, 100px 100%, 0 100%);
    }
    .heart__two {
      clip-path: polygon( 100px 0, 100px 40px, 90px 63px, 110px 80px, 90px 100px, 110px 120px, 100px 140px, 100px 100%, 100% 100%, 100% 0);
    }
    
    .heart__one::before, .heart__one::after,
    .heart__two::before, .heart__two::after {
      content: "";
      position: absolute; top: 4px; left: 100px; width: 100px; height: 160px;
      background: #dc143c; border-radius: 100px 100px 0 0;
      transform: rotate(-45deg); transform-origin: 0 100%;
    }
    
    .heart__one::after, .heart__two::after {
      left: 0; transform: rotate(45deg); transform-origin: 100% 100%;
    }
    
    .container:hover .heart__one {
      transform: rotate(-5deg) translateX(-7px); transition: all 1s;
    }
    .container:hover .heart__two {
      transform: rotate(5deg) translateX(7px); transition: all 1s;
    }
    <div class="container">
      <div class="heart__one"></div>
      <div class="heart__two"></div>
    </div>

    点击动画:

    let heart = document.querySelector('.container');
    heart.onclick = function(){
    document.querySelector('.heart__one').classList.add("heart__one__active");
    document.querySelector('.heart__two').classList.add("heart__two__active");
    setTimeout(function() {
    document.querySelector('.heart__one').classList.remove("heart__one__active");
    document.querySelector('.heart__two').classList.remove("heart__two__active");
    }, 1000);
    }
    body {display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0;}
    
    .container {position: relative; width: 200px; height: 165px;}
    
    .heart__one, .heart__two {
      position: absolute; top: 0; left: 0; width: 200px; height: 165px; transition: all 2s 1s;
    }
    
    .heart__one {
      clip-path: polygon( 0 0, 100px 0, 100px 40px, 90px 63px, 110px 80px, 90px 100px, 110px 120px, 100px 140px, 100px 100%, 0 100%);
    }
    .heart__two {
      clip-path: polygon( 100px 0, 100px 40px, 90px 63px, 110px 80px, 90px 100px, 110px 120px, 100px 140px, 100px 100%, 100% 100%, 100% 0);
    }
    
    .heart__one::before, .heart__one::after,
    .heart__two::before, .heart__two::after {
      content: ""; cursor: pointer;
      position: absolute; top: 4px; left: 100px; width: 100px; height: 160px;
      background: #dc143c; border-radius: 100px 100px 0 0;
      transform: rotate(-45deg); transform-origin: 0 100%;
    }
    
    .heart__one::after, .heart__two::after {
      left: 0; transform: rotate(45deg); transform-origin: 100% 100%;
    }
    
    .heart__one__active {
      transform: rotate(-5deg) translateX(-7px); transition: all 1s;
    }
    .heart__two__active {
      transform: rotate(5deg) translateX(7px); transition: all 1s;
    }
    <div class="container">
      <div class="heart__one"></div>
      <div class="heart__two"></div>
    </div>

    让我们稍微复杂一点动画并添加灯光效果:

    let heart = document.querySelector('.container');
    heart.onclick = function(){
    document.querySelector('.heart__one').classList.add("heart__one__active");
    document.querySelector('.heart__two').classList.add("heart__two__active");
    document.querySelector('body').classList.add("body__black");
    setTimeout(function() {
    document.querySelector('.heart__one').classList.remove("heart__one__active");
    document.querySelector('.heart__two').classList.remove("heart__two__active");
    document.querySelector('body').classList.remove("body__black");
    }, 4600);
    }
    body {display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: pink;}
    
    .container {position: relative; width: 200px; height: 165px;}
    
    .heart__one, .heart__two {
      position: absolute; top: 0; left: 0; width: 200px; height: 165px;
    }
    
    .heart__one {
      clip-path: polygon( 0 0, 100px 0, 100px 40px, 90px 63px, 110px 80px, 90px 100px, 110px 120px, 100px 140px, 100px 100%, 0 100%);
    }
    .heart__two {
      clip-path: polygon( 100px 0, 100px 40px, 90px 63px, 110px 80px, 90px 100px, 110px 120px, 100px 140px, 100px 100%, 100% 100%, 100% 0);
    }
    
    .heart__one::before, .heart__one::after,
    .heart__two::before, .heart__two::after {
      content: ""; cursor: pointer;
      position: absolute; top: 4px; left: 100px; width: 100px; height: 160px;
      background: #dc143c; border-radius: 100px 100px 0 0;
      transform: rotate(-45deg); transform-origin: 0 100%;
    }
    
    .heart__one::after, .heart__two::after {
      left: 0; transform: rotate(45deg); transform-origin: 100% 100%;
    }
    
    .heart__one__active {animation: ani1 2s forwards 2.5s;}
    .heart__two__active {animation: ani2 2s forwards 2.5s;}
    
    @keyframes ani1 {
      0% {transform: rotate(-8deg) translateX(-11px);}
      2% {transform: rotate(-2deg) translateX(-3px);}
      8% {transform: rotate(-7deg) translateX(-10px);}
      13% {transform: rotate(-3deg) translateX(-4px);}
      18% {transform: rotate(-6deg) translateX(-8px);}
      22% {transform: rotate(-4deg) translateX(-5px);}
      25% {transform: rotate(-5deg) translateX(-7px);}
      60% {transform: rotate(-5deg) translateX(-7px);}
      100% {transform: rotate(0deg) translateX(0);}
    }
    @keyframes ani2 {
      0% {transform: rotate(8deg) translateX(11px);}
      2% {transform: rotate(2deg) translateX(3px);}
      8% {transform: rotate(7deg) translateX(10px);}
      13% {transform: rotate(3deg) translateX(4px);}
      18% {transform: rotate(6deg) translateX(8px);}
      22% {transform: rotate(4deg) translateX(5px);}
      25% {transform: rotate(5deg) translateX(7px);}
      60% {transform: rotate(5deg) translateX(7px);}
      100% {transform: rotate(0deg) translateX(0);}
    }
    
    .body__black {width: 100%; animation: ani 2s forwards 0.1s;}
    
    @keyframes ani {
      0% {background: pink;}
      100% {background: black;}
    }
    <div class="container">
      <div class="heart__one"></div>
      <div class="heart__two"></div>
    </div>

    结果很好。但一颗破碎的心并不总是好的,真的不可能把它粘在一起。因此,我希望大家永远只有这个:

    body {display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: pink;}
    
    .heart {
      position: relative; width: 200px; height: 165px;
      animation: ani1 1.5s infinite 0.5s;
    }
    
    .heart::before, .heart::after {
      content: "";
      position: absolute; top: 4px; left: 100px; width: 100px; height: 160px;
      background: #dc143c; border-radius: 100px 100px 0 0;
      transform: rotate(-45deg); transform-origin: 0 100%;
      animation: ani2 1.5s infinite 0.5s;
    }
    .heart::after {
      left: 0; transform: rotate(45deg); transform-origin: 100% 100%;
    }
    
    @keyframes ani1 {
      10% {transform: scale(1.1);}
      20% {transform: scale(1);}
      30% {transform: scale(1.1);}
      40% {transform: scale(1);}
    }
    @keyframes ani2 {
      30% {background: red;}
      50% {background: #dc143c;}
    }
    <div class="heart"></div>

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5