Search code examples
javascriptcsssvghtml5-canvassvg-animate

Animation of cutting boards with a circular saw


I found a topic that implements an animation of the rotation and movement of the circular saw

html {
  background-color: #337ab7;
}

.cutline {
  stroke: #222;
  stroke-width: .1%;
  stroke-width: .5%;
  stroke-dasharray: 1% 2%;
  stroke-linecap: round;
  fill: none;
}

.sawblade {
  fill: #eee;
  width: 200px;
  height: auto;
  margin: 30px;
}
<svg viewBox="0 0 3387 1270">
  <path id="cutline" class="cutline" d="M 2700 1000 L 100 1000 " />
<g class="sawblade" >
  <path id="sawblade" d="M779.9,413.8s15.26,-47.61,-89.24,-73.22c-1.24,-0.3,-2.45,-0.58,-3.65,-0.84c20.57,-19,50.83,-37.45,85.5,-28.49c0,0,2.29,-50,-105.27,-47.38c-1.2,0,-2.36,0.08,-3.51,0.13c14.95,-23.6,39.28,-49.18,74.95,-49.6c0,0,-10.8,-48.82,-114,-18.32l-1.63,0.49c8.62,-26.2,25.66,-55.9,59.27,-65.14c0,0,-22.88,-44.46,-114.87,11.33c-1.1,0.66,-2.15,1.32,-3.18,2c1.12,-28,9.45,-62.41,40.3,-80.6c0,0,-33.69,-36.94,-107.93,40.94c-0.82,0.87,-1.62,1.72,-2.39,2.57c-6.15,-27.25,-7,-62.55,18,-88.07c0,0,-42.16,-26.89,-93.55,67.63c-0.27,0.51,-0.53,1,-0.8,1.5c-12.43,-24.62,-21.38,-57.66,-4.15,-88c0,0,-47.61,-15.25,-73.22,89.24c-0.3,1.24,-0.58,2.46,-0.84,3.65c-19,-20.57,-37.45,-50.82,-28.49,-85.49c0,0,-50,-2.3,-47.38,105.26c0,1.2,0.08,2.37,0.13,3.52c-23.62,-14.93,-49.18,-39.29,-49.56,-75c0,0,-48.82,10.79,-18.32,114c0.16,0.55,0.32,1.09,0.49,1.62c-26.2,-8.61,-55.9,-25.66,-65.14,-59.27c0,0,-44.46,22.88,11.33,114.88q1,1.64,2,3.18c-28,-1.12,-62.42,-9.46,-80.6,-40.31c0,0,-36.94,33.7,40.94,107.93c0.86,0.83,1.72,1.62,2.57,2.4c-27.25,6.15,-62.55,7,-88.07,-18c0,0,-26.89,42.15,67.63,93.54l1.5,0.8c-24.62,12.44,-57.66,21.38,-88,4.15c0,0,-15.26,47.62,89.24,73.22c1.24,0.31,2.46,0.58,3.65,0.85c-20.57,19,-50.82,37.44,-85.49,28.49c0,0,-2.3,49.94,105.26,47.37c1.2,0,2.37,-0.07,3.52,-0.13c-14.93,23.63,-39.29,49.19,-75,49.57c0,0,10.79,48.82,114,18.32l1.62,-0.5c-8.61,26.21,-25.66,55.9,-59.27,65.14c0,0,22.88,44.46,114.88,-11.32c1.09,-0.67,2.15,-1.33,3.18,-2c-1.12,28,-9.46,62.42,-40.31,80.6c0,0,33.7,36.94,107.93,-40.93c0.83,-0.87,1.62,-1.73,2.4,-2.58c6.15,27.26,7,62.56,-18,88.07c0,0,42.15,26.89,93.54,-67.63c0.28,-0.51,0.54,-1,0.8,-1.5c12.44,24.62,21.38,57.67,4.15,88c0,0,47.62,15.26,73.22,-89.24c0.31,-1.24,0.58,-2.45,0.85,-3.65c19,20.57,37.44,50.83,28.49,85.5c0,0,49.94,2.29,47.37,-105.27c0,-1.2,-0.07,-2.36,-0.13,-3.51c23.63,14.92,49.18,39.28,49.57,75c0,0,48.82,-10.8,18.32,-114c-0.16,-0.55,-0.33,-1.09,-0.5,-1.63c26.21,8.62,55.9,25.66,65.14,59.27c0,0,44.46,-22.88,-11.32,-114.87c-0.67,-1.1,-1.33,-2.15,-2,-3.18c28,1.12,62.42,9.46,80.6,40.31c0,0,36.94,-33.7,-40.93,-107.94c-0.87,-0.82,-1.73,-1.62,-2.58,-2.39c27.26,-6.15,62.56,-7,88.07,18c0,0,26.89,-42.16,-67.63,-93.55l-1.5,-0.8c24.69,-12.4,57.74,-21.35,88.04,-4.12zm-442.7,-23.46a53.14,53.14,0,1,1,53.14,53.14a53.15,53.15,0,0,1,-53.14,-53.14z" >
    <animateTransform attributeType="xml" attributeName="transform" type="rotate" values="360 390.35 390.35; 0 390.35 390.35" dur="5s" repeatCount="indefinite"></animateTransform>
    <animateMotion dur="5s" repeatCount="indefinite" rotate="auto" >
    <mpath xlink:href="#cutline" />
    </animateMotion> 
  </path>
  </g>
</svg>

In this matter, the problem of simultaneous double animation was solved: rotation and movement of a circular saw.
There was an idea to apply this solution on a realistic example, for example cutting a board

enter image description here

But it turned out to be not so simple. Either the board obscured the saw, or the saw was in the foreground, blocking the board.
It is necessary that the saw cut into the board, the cut line was visible, and after passing the saw, two halves of the board would be obtained.
I tried all sorts of solutions using clip-path, mask, etc., to hide unnecessary parts of the image.

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 3387 1270" version="1.1">
 <defs>  
  <mask id="msk1" >
    <rect width="100%" height="100%" fill="white" />
    <circle cx="390" cy="390" r="390" fill="red" />
  </mask>
 </defs>

 <g id="sawblade"  transform="translate(1000,126)">
    <path d="m779.9 413.8c0 0 15.3-47.6-89.2-73.2-1.2-0.3-2.4-0.6-3.6-0.8 20.6-19 50.8-37.4 85.5-28.5 0 0 2.3-50-105.3-47.4-1.2 0-2.4 0.1-3.5 0.1 15-23.6 39.3-49.2 75-49.6 0 0-10.8-48.8-114-18.3l-1.6 0.5c8.6-26.2 25.7-55.9 59.3-65.1 0 0-22.9-44.5-114.9 11.3-1.1 0.7-2.1 1.3-3.2 2 1.1-28 9.5-62.4 40.3-80.6 0 0-33.7-36.9-107.9 40.9-0.8 0.9-1.6 1.7-2.4 2.6-6.1-27.2-7-62.5 18-88.1 0 0-42.2-26.9-93.5 67.6-0.3 0.5-0.5 1-0.8 1.5-12.4-24.6-21.4-57.7-4.1-88 0 0-47.6-15.2-73.2 89.2-0.3 1.2-0.6 2.5-0.8 3.7-19-20.6-37.4-50.8-28.5-85.5 0 0-50-2.3-47.4 105.3 0 1.2 0.1 2.4 0.1 3.5-23.6-14.9-49.2-39.3-49.6-75 0 0-48.8 10.8-18.3 114 0.2 0.6 0.3 1.1 0.5 1.6-26.2-8.6-55.9-25.7-65.1-59.3 0 0-44.5 22.9 11.3 114.9q1 1.6 2 3.2c-28-1.1-62.4-9.5-80.6-40.3 0 0-36.9 33.7 40.9 107.9 0.9 0.8 1.7 1.6 2.6 2.4-27.2 6.2-62.5 7-88.1-18 0 0-26.9 42.2 67.6 93.5l1.5 0.8c-24.6 12.4-57.7 21.4-88 4.2 0 0-15.3 47.6 89.2 73.2 1.2 0.3 2.5 0.6 3.7 0.9-20.6 19-50.8 37.4-85.5 28.5 0 0-2.3 49.9 105.3 47.4 1.2 0 2.4-0.1 3.5-0.1-14.9 23.6-39.3 49.2-75 49.6 0 0 10.8 48.8 114 18.3l1.6-0.5c-8.6 26.2-25.7 55.9-59.3 65.1 0 0 22.9 44.5 114.9-11.3 1.1-0.7 2.2-1.3 3.2-2-1.1 28-9.5 62.4-40.3 80.6 0 0 33.7 36.9 107.9-40.9 0.8-0.9 1.6-1.7 2.4-2.6 6.2 27.3 7 62.6-18 88.1 0 0 42.2 26.9 93.5-67.6 0.3-0.5 0.5-1 0.8-1.5 12.4 24.6 21.4 57.7 4.2 88 0 0 47.6 15.3 73.2-89.2 0.3-1.2 0.6-2.4 0.9-3.6 19 20.6 37.4 50.8 28.5 85.5 0 0 49.9 2.3 47.4-105.3 0-1.2-0.1-2.4-0.1-3.5 23.6 14.9 49.2 39.3 49.6 75 0 0 48.8-10.8 18.3-114-0.2-0.5-0.3-1.1-0.5-1.6 26.2 8.6 55.9 25.7 65.1 59.3 0 0 44.5-22.9-11.3-114.9-0.7-1.1-1.3-2.1-2-3.2 28 1.1 62.4 9.5 80.6 40.3 0 0 36.9-33.7-40.9-107.9-0.9-0.8-1.7-1.6-2.6-2.4 27.3-6.1 62.6-7 88.1 18 0 0 26.9-42.2-67.6-93.5l-1.5-0.8c24.7-12.4 57.7-21.3 88-4.1zM337.2 390.3a53.1 53.1 0 1 1 53.1 53.1 53.2 53.2 0 0 1-53.1-53.1z">
     <animateTransform attributeType="xml" attributeName="transform" type="rotate" values="0 390.35 390.35; 360 390.35 390.35" dur="5s" repeatCount="indefinite"></animateTransform>
    </path>
  </g>
   <g mask="url(#msk1)">
 <path d="M514.5 288.7H3267.7L3035.1 698.6H281.6Z" style="fill:#e4c000;stroke-width:2;stroke:#500"/>
  <path d="m3267.7 288.7 3.3 67.7-236 404.4H281.6v-62.1h2753.5z" style="fill:#e4c000;stroke-width:2;stroke:#000"/>
  <path d="m3035.1 698.6 0 62.1" style="fill:none;stroke:#000"/> 
   <animateTransform attributeType="xml" attributeName="transform" type="translate" values="-1600, 0;1700, 0" dur="5s" repeatCount="1" fill="freeze"></animateTransform>
 </g> 
 
</svg>  

How to get a solution so that when cutting the board, the saw is in the body of the board


Solution

  • Quick example

    You need to have 3 layers. As SVG gives no support for depth apart from element order (or maybe a filter can create a z buffer) you need the elements in the correct order.

    I don't have a SVG authoring tool on hand so used some code to slice the plank. The plank is duplicated, one behind and one in front of the saw. As a used code you will find some additional element ids in the example I forgot to remove. They are not needed.

    To hide the cut to the left of the blade you need to cover the cut. I did this using a clip-path for the left and right sides. To avoid holes between clip paths you need to overlap them by at least a pixel.

    Example

    The right cut plank is a little thicker than it should be (my bad) but then this is how to solve the problem, not the complete end product.

    I also removed the mask, you will have to add that as well (one for the top and one for the bottom.

    As stackOverflow does not count SVG as an image i can not insert the example without putting it in a snippet.

    <svg id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 3387 1270" version="1.1">
     <defs>  
      <clipPath id="clipLeft">
    <rect x="-100" y="0" width="1102" height="100%"/>
      </clipPath>
      <clipPath id="clipRight">
    <rect x="1000" y="0" width="2100" height="100%"/>
      </clipPath>
        
     </defs>
    
        <!-- RIGHT SIDE of ANIMATION -->
    
       <g  clip-path="url(#clipRight)">
    
       <!-- BACK of ANIMATION -->
    
       <g   transform="translate(1700 0)">
          <path id="boardTop" d="M 514.5 288.1 H 3267.7 L 3151.4 493.4 H 398.2Z" style="fill:#e4c000;stroke-width:2;stroke:#500"></path>
          <path id="boardTopEdge" d="M 3267.7 288.1 L 3267.7 355.8 L 3151.4 561.1 L 3151.4 493.4z" style="fill:#e4c000;stroke-width:2;stroke:#000"></path>
           <path id="boardTopEdge3" d="M 3151.4 493.4 L 3151.4 561.1 L 398.2 561.1 L 398.2 493.4z" style="fill:#e4c000;stroke-width:2;stroke:#000"></path> 
    
          <path id="boardTopEdge1" d="M 3267.7 288.1 L 3267.7 355.8 L 3151.4 561.1 L 3151.4 493.4z" style="fill:none;stroke:#000"></path> 
           <path id="boardTopEdge2" d="M 3151.4 493.4 L 3151.4 561.1 L 398.2 561.1 L 398.2 493.4z" style="fill:none;stroke:#000"></path>      
          <animateTransform attributeType="xml" attributeName="transform" type="translate" values="-1600, 0;1700, 0" dur="5s" repeatCount="1" fill="freeze">   
          </animateTransform>
       </g> 
     <g id="sawblade" transform="translate(1000,126)">
        <path d="m779.9 413.8c0 0 15.3-47.6-89.2-73.2-1.2-0.3-2.4-0.6-3.6-0.8 20.6-19 50.8-37.4 85.5-28.5 0 0 2.3-50-105.3-47.4-1.2 0-2.4 0.1-3.5 0.1 15-23.6 39.3-49.2 75-49.6 0 0-10.8-48.8-114-18.3l-1.6 0.5c8.6-26.2 25.7-55.9 59.3-65.1 0 0-22.9-44.5-114.9 11.3-1.1 0.7-2.1 1.3-3.2 2 1.1-28 9.5-62.4 40.3-80.6 0 0-33.7-36.9-107.9 40.9-0.8 0.9-1.6 1.7-2.4 2.6-6.1-27.2-7-62.5 18-88.1 0 0-42.2-26.9-93.5 67.6-0.3 0.5-0.5 1-0.8 1.5-12.4-24.6-21.4-57.7-4.1-88 0 0-47.6-15.2-73.2 89.2-0.3 1.2-0.6 2.5-0.8 3.7-19-20.6-37.4-50.8-28.5-85.5 0 0-50-2.3-47.4 105.3 0 1.2 0.1 2.4 0.1 3.5-23.6-14.9-49.2-39.3-49.6-75 0 0-48.8 10.8-18.3 114 0.2 0.6 0.3 1.1 0.5 1.6-26.2-8.6-55.9-25.7-65.1-59.3 0 0-44.5 22.9 11.3 114.9q1 1.6 2 3.2c-28-1.1-62.4-9.5-80.6-40.3 0 0-36.9 33.7 40.9 107.9 0.9 0.8 1.7 1.6 2.6 2.4-27.2 6.2-62.5 7-88.1-18 0 0-26.9 42.2 67.6 93.5l1.5 0.8c-24.6 12.4-57.7 21.4-88 4.2 0 0-15.3 47.6 89.2 73.2 1.2 0.3 2.5 0.6 3.7 0.9-20.6 19-50.8 37.4-85.5 28.5 0 0-2.3 49.9 105.3 47.4 1.2 0 2.4-0.1 3.5-0.1-14.9 23.6-39.3 49.2-75 49.6 0 0 10.8 48.8 114 18.3l1.6-0.5c-8.6 26.2-25.7 55.9-59.3 65.1 0 0 22.9 44.5 114.9-11.3 1.1-0.7 2.2-1.3 3.2-2-1.1 28-9.5 62.4-40.3 80.6 0 0 33.7 36.9 107.9-40.9 0.8-0.9 1.6-1.7 2.4-2.6 6.2 27.3 7 62.6-18 88.1 0 0 42.2 26.9 93.5-67.6 0.3-0.5 0.5-1 0.8-1.5 12.4 24.6 21.4 57.7 4.2 88 0 0 47.6 15.3 73.2-89.2 0.3-1.2 0.6-2.4 0.9-3.6 19 20.6 37.4 50.8 28.5 85.5 0 0 49.9 2.3 47.4-105.3 0-1.2-0.1-2.4-0.1-3.5 23.6 14.9 49.2 39.3 49.6 75 0 0 48.8-10.8 18.3-114-0.2-0.5-0.3-1.1-0.5-1.6 26.2 8.6 55.9 25.7 65.1 59.3 0 0 44.5-22.9-11.3-114.9-0.7-1.1-1.3-2.1-2-3.2 28 1.1 62.4 9.5 80.6 40.3 0 0 36.9-33.7-40.9-107.9-0.9-0.8-1.7-1.6-2.6-2.4 27.3-6.1 62.6-7 88.1 18 0 0 26.9-42.2-67.6-93.5l-1.5-0.8c24.7-12.4 57.7-21.3 88-4.1zM337.2 390.3a53.1 53.1 0 1 1 53.1 53.1 53.2 53.2 0 0 1-53.1-53.1z" transform="rotate(303.501 390.35 390.35)">
           <animateTransform attributeType="xml" attributeName="transform" type="rotate" values="0 390.35 390.35; 360 390.35 390.35" dur="2.5s" repeatCount="indefinite"></animateTransform>
         </path>
       </g>
    
       <!-- FRONT of ANIMATION -->
       <g   transform="translate(1700 0)">
    
          <path id="boardBotEdge" d="M 3128.1 534.4 L 3128.1 602.1 L 3035.1 766.3 L 3035.1 698.6z" style="fill:#e4c000;stroke-width:2;stroke:#000"></path>
          <path id="boardBot" d="M 374.9 534.4 H 3128.1 L 3035.1 698.6 H 281.6Z" style="fill:#e4c000;stroke-width:2;stroke:#500"></path>
           <path id="boardBotEdge3" d="M 3035.1 698.6 L 3035.1 766.3 L 281.6 766.3 L 281.6 698.6z" style="fill:#e4c000;stroke-width:2;stroke:#500"></path>
           
          <path id="boardBotEdge1" d="M 3128.1 534.4 L 3128.1 602.1 L 3035.1 766.3 L 3035.1 698.6z" style="fill:none;stroke:#000"></path> 
           <path id="boardBotEdge2" d="M 3035.1 698.6 L 3035.1 766.3 L 281.6 766.3 L 281.6 698.6z" style="fill:none;stroke:#000"></path>
          <animateTransform attributeType="xml" attributeName="transform" type="translate" values="-1600, 0;1700, 0" dur="5s" repeatCount="1" fill="freeze">   
          </animateTransform>
       </g> 
        <g>
        <rect width="0" height="200" y="450" x="800" style="fill:#e4c000;">
        <animate attributeName="width" values="1750;0" dur="3s" repeatCount="1"></animate>
        <animate attributeName="x" values="-850;800" dur="3s" repeatCount="1"></animate>
        </rect>
    
        </g>
    </g>
    
    <!-- LEFT SIDE of ANIMATION -->
    
       <g clip-path="url(#clipLeft)">
       <g>
     <path d="M514.5 288.7H3267.7L3035.1 698.6H281.6Z" style="fill:#e4c000;stroke-width:2;stroke:#500"/>
      <path d="m3267.7 288.7 3.3 67.7-236 404.4H281.6v-62.1h2753.5z" style="fill:#e4c000;stroke-width:2;stroke:#000"/>
      <path d="m3035.1 698.6 0 62.1" style="fill:none;stroke:#000"/> 
       <animateTransform attributeType="xml" attributeName="transform" type="translate" values="-1600, 0;1700, 0" dur="5s" repeatCount="1" fill="freeze"></animateTransform>
     </g> 
     </g>
     
    </svg>