Начало перемещения объекта из случайно выбранной точки path SVG

111
25 декабря 2021, 05:10

Я пытаюсь получить некоторое представление о SVG. Есть ли способ перемещения круга по path SVG, где круг начинает двигаться из определенной точки, определяемой длиной пути?

Например, когда объект достигает конца, он начинается снова с самого начала.

Какие атрибуты использовать, чтобы заставить круг перемещаться из случайной точки, например, начиная с 20, а не с 0 до 100?

В SVG есть прямой способ - from и to, но я не уверен, как правильно его использовать. Кроме того, я обнаружил, что в некоторых случаях использование keytimes может быть полезным, но оно не дало желаемого результата.

Здесь можете увидеть HTML-код SVG, движущийся по пути, где он начинается с начала:

		<div id="pathContainer4"> 
			<svg height="160" width="360"> 
  <g fill="none" stroke="black" stroke-width="1"> 
    <path stroke-dasharray="3" id="motionpath2" 
					d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" /> 
  </g> 
  			         <circle class="circle2" r=8 fill=red ;z-index=55> 
  			          
             <animateMotion dur="2s" repeatCount="indefinite" 
					rotate="auto"  from="20" to="100"> 
                 <mpath href="#motionpath2" /> 
             </animateMotion> 
         </circle> 
		</svg> 
		</div>

Answer 1

В SVG есть прямой способ from и to, но я не уверен, как правильно его использовать. Кроме того, я обнаружил, что в некоторых случаях использование keytimes может быть полезным, но оно не дало желаемого результата.

Возможно запустить анимацию SVG, не используя JS, из любой точки траектории , но её положение должно быть определено заранее в коде .

Для этого используется пара атрибутов

keyPoints="0;1" - движение от начала  пути до конца
keyTimes="0;1"   
keyPoints="0.5;1" - движение с середины пути до конца
keyTimes="0;1"   
keyPoints="1;0" - движение от конца пути до начала
keyTimes="0;1"   

Так можно управлять положением начальной точки анимации, но теоретически невозможно создать анимацию из рандомно выбранной точки, поскольку в SVG нет переменных, нет массивов, нет инструкций для хранения и выполнения математических функций.

В примере ниже JS используется только для обработки события нажатия кнопок управления:

<div id="pathContainer4"> 
		<button id="btn1" onclick="forwardSVG()">forward</button /> 
		<button id="btn2" onclick="middleSVG()">Middle</button /> 
		<button id="btn3" onclick="backSVG()">Back</button /> 
</div>	 
<svg  xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" height="160" width="360" > 
  <g fill="none" stroke="black" stroke-width="1"> 
    <path stroke-dasharray="3" id="motionpath2" 
					d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" /> 
  </g> 
   <circle class="circle2" r=8 fill=red ;z-index=55> 
  			          
	 <animateMotion 
	   id="forward" 
	   dur="2s" 
	   begin="indefinite" 
	   repeatCount="1" 
	   keyPoints="0;1" 
	   keyTimes="0;1" 
       calcMode="linear"	   > 
		 <mpath href="#motionpath2" /> 
	 </animateMotion>  
		<animateMotion 
		   id="middle" 
		   dur="2s" 
		   begin="indefinite" 
		   repeatCount="1" 
		   keyPoints="0.5;1" 
		   keyTimes="0;1" 
		   calcMode="linear"					> 
		 <mpath href="#motionpath2" /> 
	    </animateMotion>  
		   <animateMotion 
		   id="back" 
		   dur="2s" 
		   begin="indefinite" 
		   repeatCount="1" 
		   keyPoints="1;0" 
		   keyTimes="0;1" 
		   calcMode="linear"					> 
		 <mpath href="#motionpath2" /> 
	    </animateMotion> 
         </circle> 
		</svg> 
		 
<script> 
var animation1 = document.getElementById("forward") 
function forwardSVG(){ 
     animation1.beginElement(); 
}  
var animation2 = document.getElementById("middle") 
function middleSVG(){ 
     animation2.beginElement(); 
}   
 
var animation3 = document.getElementById("back") 
function backSVG(){ 
     animation3.beginElement(); 
} 
</script>

Вы также можете создать иллюзию случайного движения.

Пример с иллюзией случайного движения бильярдных шаров

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"   
xmlns:xlink="http://www.w3.org/1999/xlink" height="100vh" viewBox="0 0 400 400"> 
 
<rect width="100%" height="100%" rx="25"  fill="green" stroke="#9D8500" stroke-width="15"/> 
<circle cx="50%" cy="20%" r="3%" fill="url(#gradB)" > 
 
 <animate attributeName="cx" dur="3" values="3%;97%;3%"   
   repeatCount="indefinite" />  
 <animate attributeName="cy" dur="2.8" values="3%;97%;3%"   
   repeatCount="indefinite" /> 
</circle> 
 
<circle cx="30%" cy="70%" r="3%" fill="url(#gradR)" > 
 
 <animate attributeName="cx" dur="2.7" values="97%;3%;97%"   
   repeatCount="indefinite" />  
 <animate attributeName="cy" dur="3.1" values="3%;97%;3%"   
   repeatCount="indefinite" /> 
</circle> 
 
 <radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%"> 
   <stop stop-color="white" offset="0"/> 
   <stop stop-color="blue" offset="25%"/> 
   <stop stop-color="rgb(0,0,192)" offset="50%"/> 
   <stop stop-color="rgb(0,0,127)" offset="70%"/> 
   <stop stop-color="rgb(0,0,64)" offset="85%"/> 
   <stop stop-color="rgb(0,0,0)" offset="100%"/> 
 </radialGradient> 
 
 <radialGradient id="gradR" cx="20%" cy="20%" r="100%" fx="30%" fy="30%"> 
   <stop stop-color="white" offset="0"/> 
   <stop stop-color="red" offset="25%"/> 
   <stop stop-color="rgb(192,0,0)" offset="50%"/> 
   <stop stop-color="rgb(127,0,0)" offset="70%"/> 
   <stop stop-color="rgb(64,0,0)" offset="85%"/> 
   <stop stop-color="rgb(0,0,0)" offset="100%"/> 
 </radialGradient> 
 
</svg>

Ещё несколько примеров иллюзии хаотического движения букв без JS

</style> 
<svg width="50%" height="50%" viewBox="0 0 1000 1000"  
  xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny" 
  xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet"> 
  
	<title>Animation of text x and y attributes</title>  
	 
 
<defs> 
<linearGradient id="grad" 
    x1="0" y1="0" x2="0" y2="100%" 
    gradientUnits="userSpaceOnUse"> 
        <stop offset="2%" stop-color="steelblue" /> 
        <stop offset="45%" stop-color="hsla(180, 100%, 50%, 0)" /> 
        <stop offset="45%" stop-color="hsla(80, 100%, 50%, 0)" /> 
        <stop offset="95%" stop-color="yellowgreen" /> 
    </linearGradient> 
</defs>  
 <rect width="100%" height="100%" fill="url(#grad)" /> 
<text  x="200 " y="500"  
font-size="90" fill="#E4E4E4" stroke-width="4" stroke="#E4E4E4">Stackoverflow</text>  
<text id="text1" x="200" y="500" 
font-size="90">Stackoverflow</text>  
 
<animate xlink:href="#text1"  
	attributeName="x"  
	attributeType="XML" 
        values="200 233 266 299 332 365 400 431 464 497 530 563 596; 
	100 600 200 365 700 465 465 563 530 398 431 850 900;  
	200 500 900 950 150 531 300 620 150 266 365 650 900; 
	332 233 820 300 800 633 200 670 300 850 800 530 266; 
	464 900 900 900 820 670 430 900 530 600 233 365 100; 
	332 100 100 100 500 100 800 563 900 700 900 100 100; 
  200	233 266 299 332 365 400 431 464 497 530 563 596" 
	dur="4s" 
	begin="0s" 
	repeatCount="2" /> 
<animate xlink:href="#text1" 
	attributeName="y"  
	attributeType="XML" 
        values="500 500 500 500 500 500 500 500 500 500 500 500 500; 
	100 200 850 100 250 175 750 100 750 720 850 500 50;  
	100 600 600 250 200 450 50 200 520 550 300 300 750; 
	500 100 650 650 600 150 550 50 150 550 200 550 400;  
	800 300 100 750 150 650 75 350 550 700 755 120 800; 
	800 600 300 150 750 350 700 650 200 250 500 650 100; 
	500 500 500 500 500 500 500 500 500 500 500 500 500" 
	dur="4s" 
	begin="0s" 
	repeatCount="2" /> 
 
 
</svg>

Вертикальная парковка букв

<style> 
 #text1 { 
 
fill:#B2000C; 
} 
  
</style> 
<svg width="70%" height="70%" viewBox="0 0 1000 1000"  
  xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny" 
  xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet"> 
  
	<title>Animation of text x and y attributes</title>  
	 
 
<defs> 
<linearGradient id="grad" 
    x1="0" y1="0" x2="0" y2="100%" 
    gradientUnits="userSpaceOnUse"> 
        <stop offset="2%" stop-color="steelblue" /> 
        <stop offset="45%" stop-color="hsla(180, 100%, 50%, 0)" /> 
        <stop offset="45%" stop-color="hsla(80, 100%, 50%, 0)" /> 
        <stop offset="95%" stop-color="yellowgreen" /> 
    </linearGradient> 
</defs>  
 <rect width="100%" height="100%" fill="url(#grad)" /> 
<text  x="200 " y="500"  
font-size="90" fill="#E4E4E4" stroke-width="4" stroke="#E4E4E4">Stackoverflow</text>  
<text id="text1" x="200" y="500" 
font-size="90">Stackoverflow</text>  
 
<animate xlink:href="#text1"  
	attributeName="x"  
	attributeType="XML" 
        values="200 233 266 299 332 365 400 431 464 497 530 563 596; 
	100 600 200 365 700 465 465 563 530 398 431 850 900;  
	200 500 900 950 150 531 300 620 150 266 365 650 900; 
	332 233 820 300 800 633 200 670 300 850 800 530 266; 
	464 900 900 900 820 670 430 900 530 600 233 365 100; 
	332 100 100 100 500 100 800 563 900 700 900 100 100; 
    200	233 266 299 332 365 400 431 464 497 530 563 596" 
	dur="3s" 
	begin="0s" 
	repeatCount="2" /> 
<animate xlink:href="#text1" 
	attributeName="y"  
	attributeType="XML" 
        values="500 500 500 500 500 500 500 500 500 500 500 500 500; 
	100 200 850 100 250 175 750 100 750 720 850 500 50;  
	100 600 600 250 200 450 50 200 520 550 300 300 750; 
	500 100 650 650 600 150 550 50 150 550 200 550 400;  
	800 300 100 750 150 650 75 350 550 700 755 120 800; 
	800 600 300 150 750 350 700 650 200 250 500 650 100; 
	500 500 500 500 500 500 500 500 500 500 500 500 500" 
	dur="4s" 
	begin="0s" 
	repeatCount="2" /> 
 
 
</svg>

Горизонтальная парковка букв

<style> 
 #text1 { 
 
fill:#B2000C; 
} 
  
</style> 
<svg width="50%" height="50%" viewBox="0 0 1000 1000"  
  xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny" 
  xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet"> 
  
	<title>Animation of text x and y attributes</title>  
	 
 
<defs> 
<linearGradient id="grad" 
    x1="0" y1="0" x2="0" y2="100%" 
    gradientUnits="userSpaceOnUse"> 
        <stop offset="2%" stop-color="steelblue" /> 
        <stop offset="45%" stop-color="hsla(180, 100%, 50%, 0)" /> 
        <stop offset="45%" stop-color="hsla(80, 100%, 50%, 0)" /> 
        <stop offset="95%" stop-color="yellowgreen" /> 
    </linearGradient> 
</defs>  
 <rect width="100%" height="100%" fill="url(#grad)" /> 
<text  x="200 " y="500"  
font-size="90" fill="#E4E4E4" stroke-width="4" stroke="#E4E4E4">Stackoverflow</text>  
<text id="text1" x="200" y="500" 
font-size="90">Stackoverflow</text>  
 
<animate xlink:href="#text1"  
	  attributeName="x"  
	  attributeType="XML" 
    values="200 233 266 299 332 365 400 431 464 497 530 563 596; 
	100 600 200 365 700 465 465 563 530 398 431 850 900;  
	200 500 900 950 150 531 300 620 150 266 365 650 900; 
	332 233 820 300 800 633 200 670 300 850 800 530 266; 
	464 900 900 900 820 670 430 900 530 600 233 365 100; 
	332 100 100 100 500 100 800 563 900 700 900 100 100; 
    200	233 266 299 332 365 400 431 464 497 530 563 596" 
	dur="4s" 
	begin="0s" 
	repeatCount="2" /> 
<animate xlink:href="#text1" 
	  attributeName="y"  
	  attributeType="XML" 
    values="500 500 500 500 500 500 500 500 500 500 500 500 500; 
	100 200 850 100 250 175 750 100 750 720 850 500 50;  
	100 600 600 250 200 450 50 200 520 550 300 300 750; 
	500 100 650 650 600 150 550 50 150 550 200 550 400;  
	800 300 100 750 150 650 75 350 550 700 755 120 800; 
	800 600 300 150 750 350 700 650 200 250 500 650 100; 
	500 500 500 500 500 500 500 500 500 500 500 500 500" 
    	dur="3s" 
	  begin="0s" 
    	repeatCount="2" /> 
 
 
</svg>

Источник: @Alexandr_TT

READ ALSO
Консоль NodeJS не реагирует на ввод команд

Консоль NodeJS не реагирует на ввод команд

После npm start и запуска учебного примера я не могу ничего ввести в консолиПриходится просто её закрывать, но когда запускаю по новой через npm start выдаёт...

133
Как запретить прокрутку контенту, а оверлею разрешить [закрыт]

Как запретить прокрутку контенту, а оверлею разрешить [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

93
Чем put отличается от patch?

Чем put отличается от patch?

Изучаю REST APIНе понимаю отличия метода PUT от PATCH: они же оба используются для обновления данных

106