转换复杂SVG组中嵌套元素的原点

时间:2017-08-09 19:35:09

标签: css css3 animation svg transform

我有一段时间让我的变换原点在嵌套的SVG元素上正确,并且想知道我是否可以借用某人的眼睛来发现我的愚蠢行为?

我尝试了很多不同的组合,到目前为止,当我倾向于在一个浏览器中接近我想要的东西时,它在另一个浏览器中非常接近。

对于PoC示例,我们正在看着我的小家伙的螺旋桨。为了一个简单的开始,我将这个例子的变换原点设置在中心(就像我说的,我尝试了许多变化而没有运气)。任何人都可以告诉我是什么导致了浏览器之间的差异(是的,我尝试在各种浏览器限定符中指定变换,如-webkit- *以及以各种方式击中X / Y)但是你会注意到在Chrome中它更接近到了元素的中心,而在Firefox中它看起来是绝对父SVG本身的中心......

所以,有人想教我一些关于SVG动画中嵌套元素转换起源的新内容,并帮助我的小家伙用他的螺旋桨飞行它需要的地方吗? :)

  

CODEPEN to tinker with

PS - 垂直绿色中心线只是一个视觉尺寸参考占位符,我的小伙伴飞行它是真实的代码,因为我只能在SO片段中添加这么多字符...

body {text-align:center}


@keyframes adventure {
  
  10% {
    transform: translateX(5%) rotate(2deg);
  } 25% {
    transform: translateX(13%) rotate(15deg);
  } 50% {
    transform: translateX(-13%) rotate(-5deg);
  } 75% {
    transform: translateX(13%) rotate(15deg);
  } 90% {
    transform: translateX(-5%) rotate(-2deg);
  }
  
}

@keyframes navigate {
  10% {
    transform: rotate(2deg);
  } 25% {
    transform: rotate(10deg);
  } 50% {
    transform: rotate(-5deg);
  } 75% {
    transform: rotate(10deg);
  } 90% {
    transform: rotate(-2deg);
  }
}

@keyframes propel { 
  100% {transform: rotate(360deg)}
}

#fullcharacter {
  transform-origin: 50%;
  animation: adventure 5s infinite;
  -webkit-transition-timing-function: step-start;
  transition-timing-function: step-start;
}


#steering {
  transform-origin: center;
  animation: navigate 5s infinite;
}

#propeller {
  transform-origin: center;
  animation: propel 4s infinite linear;
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="525px" height="250px" viewBox="0 0 525 250" enable-background="new 0 0 525 250" xml:space="preserve">
<rect fill="#81BFE9" width="525" height="250"/>
<g id="fullcharacter">
	<g id="steering">
		<path fill="#BE1E2D" d="M242.271,125.417c0,0.552-0.479,1-1.069,1h-3.03c-0.589,0-1.068-0.448-1.068-1l0,0
			c0-0.552,0.479-1,1.068-1h3.03C241.792,124.417,242.271,124.865,242.271,125.417L242.271,125.417z"/>
		<path fill="#BE1E2D" d="M286.358,125.417c0,0.551-0.479,1-1.068,1h-3.029c-0.59,0-1.068-0.449-1.068-1l0,0
			c0-0.552,0.479-0.999,1.068-0.999h3.029C285.88,124.417,286.358,124.865,286.358,125.417L286.358,125.417z"/>
		<g>
			<path fill="#DDAC85" stroke="#BA9168" stroke-width="0.5" stroke-miterlimit="10" d="M239.87,127.589c0,0,3.407-2.738,4.75-2.583
				c1.664,0.192,5.234,2.8,5,4.458c-0.225,1.591-5.795,2.781-5.795,2.781L239.87,127.589z"/>
			<path fill="#DDAC85" stroke="#BA9168" stroke-width="0.5" stroke-miterlimit="10" d="M284.354,127.589
				c0,0-3.407-2.738-4.75-2.583c-1.664,0.192-5.234,2.8-5,4.458c0.225,1.591,5.795,2.781,5.795,2.781L284.354,127.589z"/>
		</g>
		<path fill="#D6A685" stroke="#BA9168" stroke-width="0.25" stroke-miterlimit="10" d="M290.434,134.938
			c0,0,4.426,6.422,4.673,9.203c0.171,1.925-0.751,6.394-2.025,7.245c-1.815,1.214-7.728-3.23-7.728-3.23L290.434,134.938z"/>
		<path fill="#424142" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="M287.158,126.417h-0.908v-0.833h-5v0.833
			h-0.993c0.003,0.117,0.015,0.229,0.015,0.348v15.422c0,4.61-2.687,8.349-6,8.349h-25c-3.313,0-6-3.738-6-8.349v-15.422
			c0-0.118,0.011-0.23,0.015-0.348h-1.119v-0.833h-5v0.833h-1.199c-0.124,0.669-0.197,1.365-0.197,2.087v22.147
			c0,4.61,2.687,8.349,6,8.349h39.583c3.313,0,6-3.738,6-8.349v-22.147C287.354,127.782,287.281,127.086,287.158,126.417z"/>
		<path fill="#D6A685" stroke="#BA9168" stroke-width="0.25" stroke-miterlimit="10" d="M232.42,134.938
			c0,0-4.425,6.422-4.673,9.203c-0.171,1.925,0.751,6.394,2.025,7.245c1.815,1.214,7.727-3.23,7.727-3.23L232.42,134.938z"/>
		<g>
			<path fill="#EBB789" stroke="#C3996B" stroke-width="0.25" stroke-miterlimit="10" d="M232.876,145.963
				c0,0,0.137,0.129-0.119,0.128c-0.902-0.003,0.79,2.842,1.599,3.242c2.943,1.456,11.196,0.29,12.908-2.524
				c0.376-0.617,0.248-3.348-0.285-2.873c-1.528,1.364-4.473,0.662-4.473,0.662s2.94,0.374,4.415-0.846
				c0.787-0.65,1.082-4.528,0.128-4.141c-2.34,0.95-5.744,0.766-5.744,0.766s3.64-0.21,5.679-0.978
				c1.147-0.433,1.245-5.443,0.125-4.928c-2.998,1.379-6.156,1.212-6.156,1.212s3.492,0.042,6.086-1.379
				c1.555-0.851,0.382-7.08-1.396-6.944c-7.403,0.563-11.077,0.177-12.742,1.556c-0.732,0.605-2.092,4.076-1.278,4.599
				c0.773,0.496,1.112,0.793,1.112,0.793s-0.139,0.041-1.157-0.6c-1.301-0.816-1.986,5.729-0.506,6.143
				c0.524,0.146,0.222,0.063,0.222,0.063s0.467,0.146-0.268,0.129c-1.533-0.036,0.135,5.875,1.669,5.911
				C232.958,145.96,232.876,145.963,232.876,145.963z"/>
			<path fill="#DDA885" d="M234.458,148.958c0,0,3.333,1.917,10.792-0.958c2.289-0.882,2.256-3.986,1.541-3.312
				c-0.75,0.708-2.539,0.791-3.416,0.479c-1.875-0.667,2.438,2.127,1.75,2.416C239.068,150.126,234.458,148.958,234.458,148.958z"/>
			<path fill="#DDA885" d="M241.688,140.75c0,0,2.303,0.095,3.063,0c0.632-0.079,2.472-0.625,2.472-0.625s-0.08,1.388-0.159,1.844
				c-0.063,0.358-0.375,1.406-0.375,1.406s-0.953-1.477-1.438-1.781C244.476,141.105,241.688,140.75,241.688,140.75z"/>
			<path fill="#DDA885" d="M241.094,136.094c0,0,2.758-0.124,3.656-0.313c0.639-0.134,2.472-0.844,2.472-0.844
				s0.249,1.736,0.185,2.313c-0.049,0.447-0.531,1.719-0.531,1.719s-0.391-1.796-0.844-2.156
				C245.054,136.037,241.094,136.094,241.094,136.094z"/>
			<path fill="#DDA885" d="M239.068,128.156c0,0,2.998-0.086,3.995-0.156c0.697-0.049,2.781-0.281,2.781-0.281
				s0.877,1.128,1.063,1.563c0.238,0.559,0.5,2.375,0.5,2.375s-1.416-2.35-2.188-2.781
				C243.868,128.119,239.068,128.156,239.068,128.156z"/>
			<path fill="#EBB789" stroke="#C3996B" stroke-width="0.25" stroke-miterlimit="10" d="M291.052,145.963
				c0,0-0.138,0.129,0.119,0.128c0.901-0.003-0.79,2.842-1.599,3.242c-2.943,1.456-11.196,0.29-12.908-2.524
				c-0.376-0.617-0.248-3.348,0.285-2.873c1.527,1.364,4.473,0.662,4.473,0.662s-2.94,0.374-4.415-0.846
				c-0.786-0.65-1.082-4.528-0.128-4.141c2.34,0.95,5.743,0.766,5.743,0.766s-3.64-0.21-5.679-0.978
				c-1.148-0.433-1.246-5.443-0.126-4.928c2.997,1.379,6.155,1.212,6.155,1.212s-3.492,0.042-6.086-1.379
				c-1.555-0.851-0.381-7.08,1.396-6.944c7.403,0.563,11.077,0.177,12.742,1.556c0.732,0.605,2.092,4.076,1.279,4.599
				c-0.773,0.496-1.112,0.793-1.112,0.793s0.14,0.041,1.157-0.6c1.301-0.816,1.986,5.729,0.506,6.143
				c-0.523,0.146-0.222,0.063-0.222,0.063s-0.468,0.146,0.269,0.129c1.532-0.036-0.136,5.875-1.67,5.911
				C290.971,145.96,291.052,145.963,291.052,145.963z"/>
			<path fill="#DDA885" d="M289.469,148.958c0,0-3.332,1.917-10.791-0.958c-2.289-0.882-2.256-3.986-1.541-3.312
				c0.75,0.708,2.539,0.791,3.416,0.479c1.875-0.667-2.438,2.127-1.75,2.416C284.859,150.126,289.469,148.958,289.469,148.958z"/>
			<path fill="#DDA885" d="M282.24,140.75c0,0-2.303,0.095-3.063,0c-0.633-0.079-2.472-0.625-2.472-0.625s0.079,1.388,0.159,1.844
				c0.063,0.358,0.375,1.406,0.375,1.406s0.953-1.477,1.438-1.781C279.452,141.105,282.24,140.75,282.24,140.75z"/>
			<path fill="#DDA885" d="M282.834,136.094c0,0-2.758-0.124-3.656-0.313c-0.639-0.134-2.472-0.844-2.472-0.844
				s-0.249,1.736-0.185,2.313c0.049,0.447,0.531,1.719,0.531,1.719s0.391-1.796,0.844-2.156
				C278.873,136.037,282.834,136.094,282.834,136.094z"/>
			<path fill="#DDA885" d="M284.859,128.156c0,0-2.997-0.086-3.994-0.156c-0.697-0.049-2.781-0.281-2.781-0.281
				s-0.877,1.128-1.063,1.563c-0.238,0.559-0.5,2.375-0.5,2.375s1.416-2.35,2.188-2.781
				C280.06,128.119,284.859,128.156,284.859,128.156z"/>
		</g>
	</g>
	<g id="plane">
		<path fill="#CE3232" stroke="#931C24" stroke-miterlimit="10" d="M297.126,174.5c0,0,55.101,6.274,72.374,12.5
			c0.949,0.342,3.408,1.002,3.5,2.006c0.192,2.118-4.514,4.733-6.5,5.494c-15.415,5.906-66.001,2-66.001,2L297.126,174.5z"/>
		<path fill="#CE3232" stroke="#931C24" stroke-miterlimit="10" d="M225.507,174.5c0,0-55.101,6.274-72.374,12.5
			c-0.949,0.342-3.408,1.002-3.5,2.006c-0.192,2.118,4.514,4.733,6.5,5.494c15.415,5.906,66.001,2,66.001,2L225.507,174.5z"/>
		
			<ellipse fill="#CE3232" stroke="#931C24" stroke-width="0.75" stroke-miterlimit="10" cx="260.962" cy="189.006" rx="49.754" ry="42.661"/>
		<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="246.625" y1="149.8066" x2="276.7061" y2="149.8066">
			<stop  offset="0" style="stop-color:#5BCBF1"/>
			<stop  offset="0.0017" style="stop-color:#5BCAF1"/>
			<stop  offset="0.1744" style="stop-color:#4197D1"/>
			<stop  offset="0.3181" style="stop-color:#2F78BC"/>
			<stop  offset="0.4256" style="stop-color:#2467B1"/>
			<stop  offset="0.4848" style="stop-color:#2061AE"/>
			<stop  offset="0.6679" style="stop-color:#2C66B1"/>
			<stop  offset="1" style="stop-color:#3B6EB6"/>
		</linearGradient>
		<path fill="url(#SVGID_1_)" stroke="#004C6D" stroke-width="0.25" stroke-miterlimit="10" d="M246.625,151.596
			c0,0,2.098,2.086,3.006,2.404c5.572,1.955,17.985,1.766,23.619,0c1.004-0.314,3.456-2.404,3.456-2.404s-3.442-6.027-5.433-7.002
			c-2.223-1.089-7.133,0.531-9.608,0.531c-2.313,0-7.461-1.542-9.541-0.531C250.123,145.567,246.625,151.596,246.625,151.596z"/>
		<path fill="#BF312F" d="M261.375,219.229c-25.047,0-45.655-16.281-48.226-37.173c-0.444,2.261-0.688,4.581-0.688,6.95
			c0,22.967,21.714,41.585,48.5,41.585c26.787,0,48.5-18.618,48.5-41.585c0-1.491-0.096-2.963-0.274-4.413
			C305.328,204.249,285.398,219.229,261.375,219.229z"/>
		<ellipse fill="#969696" stroke="#BCBEC0" stroke-width="7" stroke-miterlimit="10" cx="260.962" cy="189.006" rx="27.5" ry="25"/>
		<radialGradient id="propeller_1_" cx="261.3926" cy="188.5" r="50.9983" gradientUnits="userSpaceOnUse">
			<stop  offset="0.3011" style="stop-color:#BCBEC0"/>
			<stop  offset="0.4531" style="stop-color:#E6E7E8"/>
			<stop  offset="0.9899" style="stop-color:#F1F2F2"/>
			<stop  offset="0.9936" style="stop-color:#F9ED32"/>
		</radialGradient>
		<path id="propeller" fill="url(#propeller_1_)" stroke="#6D6E71" stroke-width="0.5" stroke-miterlimit="10" d="M291.618,198.024
			l-25.939-12.274l2.33-28.48c0,0-0.02-31.189-6.862-31.182c-6.844,0.009-7.013,31.18-7.013,31.18l2.598,28.423l-26.065,12.334
			c0,0-27.001,15.611-23.572,21.534c3.429,5.923,30.507-9.517,30.507-9.517l23.541-16.62l23.541,16.62
			c0,0,27.079,15.439,30.507,9.517C318.62,213.636,291.618,198.024,291.618,198.024z M261.155,188.442l-0.013,0.022l-0.013-0.022
			H261.155z"/>
		<radialGradient id="SVGID_2_" cx="261.1426" cy="189.0049" r="11.9452" gradientUnits="userSpaceOnUse">
			<stop  offset="0" style="stop-color:#D1D3D4"/>
			<stop  offset="1" style="stop-color:#A7A9AC"/>
		</radialGradient>
		
			<ellipse fill="url(#SVGID_2_)" stroke="#6D6E71" stroke-width="2" stroke-miterlimit="10" cx="261.143" cy="189.005" rx="12.5" ry="11.363"/>
		<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="155.7402" y1="175.625" x2="177.2904" y2="150.7379">
			<stop  offset="0.01" style="stop-color:#BCBEC0"/>
			<stop  offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
		</linearGradient>
		<polygon fill="url(#SVGID_3_)" points="149.627,187.171 180.5,140.842 152,186.134 		"/>
		
			<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="59.2358" y1="175.626" x2="80.786" y2="150.7389" gradientTransform="matrix(-1 0 0 1 426.1279 0)">
			<stop  offset="0.01" style="stop-color:#BCBEC0"/>
			<stop  offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
		</linearGradient>
		<polygon fill="url(#SVGID_4_)" points="373.006,187.171 342.133,140.842 370.633,186.134 		"/>
	</g>
	<rect x="260.5" y="13.75" fill="#6CBE45" width="0.462" height="217.917"/>
</g>
</svg>

2 个答案:

答案 0 :(得分:1)

不使用变换原点,而是使用2种不同的平移设置旋转中心。

(您将元素移动到您想要的任何位置,旋转它,然后将其移回原位)。

你的动画将是

@keyframes propel { 
    0% {transform: translate(257px, 188px) rotate(0deg) translate(-257px, -188px);}
  100% {transform: translate(257px, 188px) rotate(360deg) translate(-257px, -188px);}
}

fixed codepen

答案 1 :(得分:1)

您现在无法真正使用transform-origin的百分比值,因为在Chrome和Firefox中对百分比值的处理方式不同。这也适用于伪值,例如&#34; center&#34;被定义为相当于&#34; 50%&#34;。

您需要使用绝对像素值来实现跨浏览器兼容。

如果您更改了螺旋桨动画,要使用绝对坐标,它将修复动画:

#propeller {
  transform-origin: 261px 189px;
  animation: propel 4s infinite linear;
}

我在这里使用的坐标只是形成推进器中心的cx的{​​{1}}和cy值。

&#13;
&#13;
<ellipse>
&#13;
body {text-align:center}


@keyframes adventure {
  
  10% {
    transform: translateX(5%) rotate(2deg);
  } 25% {
    transform: translateX(13%) rotate(15deg);
  } 50% {
    transform: translateX(-13%) rotate(-5deg);
  } 75% {
    transform: translateX(13%) rotate(15deg);
  } 90% {
    transform: translateX(-5%) rotate(-2deg);
  }
  
}

@keyframes navigate {
  10% {
    transform: rotate(2deg);
  } 25% {
    transform: rotate(10deg);
  } 50% {
    transform: rotate(-5deg);
  } 75% {
    transform: rotate(10deg);
  } 90% {
    transform: rotate(-2deg);
  }
}

@keyframes propel { 
  100% {transform: rotate(360deg)}
}

#fullcharacter {
  transform-origin: 50%;
  animation: adventure 5s infinite;
  -webkit-transition-timing-function: step-start;
  transition-timing-function: step-start;
}


#steering {
  transform-origin: center;
  animation: navigate 5s infinite;
}

#propeller {
  transform-origin: 261px 189px;
  animation: propel 4s infinite linear;
}
&#13;
&#13;
&#13;