使用 jQuery UI 滑块移动和缩放 svg 元素时遇到问题?
Having trouble with moving and scaling svg elements with jQuery UI sliders?
我有一个带有已定义文本和路径的 SVG 元素。请参阅我的示例代码。
文本按需要工作,从中心缩放并且可以准确定位,但我在 路径 上遇到了严重的问题。
当我触摸滑块移动 x 或 y 时,比例尺会被甩掉,它总是从左上角开始缩放。我在网上尝试了很多例子,但我没有运气,所以我清理了示例代码。
我希望能够从它的中心缩放路径,并且当我改变它的位置时它不会影响缩放。
$( ".slider-x" ).slider({
min: -530,
max: 530,
value: 165,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-size').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-y" ).slider({
min: -250,
max: 250,
value: -50,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-size').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-scale" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
var scale = $( ".slider-scale" ).slider( "value" );
$('.svg-size ').attr("transform","translate("+x+","+y+") scale(" + scale/100 + ")");
}
});
$( ".slider-scale-title-text" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var scale = $( ".slider-scale-title-text" ).slider( "value" );
$('.svg-business-title').css("font-size", scale+ "px");
}
});
$( ".slider-text-x" ).slider({
min: -100,
max: 635,
value: 250,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("x",x);
}
});
$( ".slider-text-y" ).slider({
min: 0,
max: 210,
value: 150,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("y",y);
}
});
h3 {
font-family: verdana;
}
.svg-business-title {
fill: brown;
stroke-width: 4;
}
.svg-strap-line {
fill: red;
stroke-width: 4;
}
.svg-custom-logo-wrapper {
fill: #94d31b;
position:absolute;
left:0; top:0; width:100%; height:100%;
}
.svg-wrapper {
width: 100%;
position:relative;
height:180px;
}
.svg-container {
max-width: 535px;
margin: 0 auto;
}
.accent-colour-1 {
fill: red;
}
.accent-colour-2 {
fill: green;
}
.svg-size{
/* transform: scale(0.2);
-ms-transform: scale(0.2);
-webkit-transform: scale(0.2); */
/* transform-origin: 270px 5px; */
}
.slider-controls, .slider-scale-title-text {
max-width: 540px;
}
.slider, input {
margin: 10px 0 10px 10px;
}
button {
margin: 5px 0 0 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="svg-container">
<div class="svg-wrapper">
<svg data-logoid="123" width="535" height="180" viewBox="0 0 535 180" class="svg-custom-logo-wrapper" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect width="535" height="180" style="fill:none;stroke-width:1;stroke:rgb(0,0,0)"/>
<g class="svg-size" transform="translate (165,-50) scale(0.4)"><path class="accent-colour-1 path-1" d="m 255,108 -97,97 -27,-27 -73,72 19,21 54,-54 106,107 -25,25 66,-26 105,-106 46,46 29,-11 -75,-74 -29,29 z m 0,40 79,79 -77,77 -79,-79 z m -16,63 h 14 v 14 h -14 z m 22,-22 h 14 v 14 h -14 z m 109,80 h 11 v 11 h -11 z m 18,-18 h 11 v 11 h -11 z m -278,43 h 16 v 15 h -16 z m 25,-25 h 16 v 15 h -16 z"></path></g>
<g class="svg-size" transform="translate (165,-50) scale(0.4)"><path class="accent-colour-2 path-2" d="M 164,381 48,259 27,281 160,404 485,254 Z M 388,269 h 11 v 11 h -11 z m -18,-18 h 11 v 11 h -11 z m -235,43 h 16 v 15 h -16 z m -25,-25 h 16 v 15 h -16 z m 151,-58 h 14 v 14 h -14 z m -22,-22 h 14 v 14 h -14 z"></path></g>
<text text-anchor="middle" class="title-text svg-business-title" transform="scale(1)" x="250" y="150" font-size="40">Title Text Here</text>
</svg>
</div>
</div>
<div class="slider-controls">
<p>LOGO</p>
X<div class="slider slider-x"></div>
Y<div class="slider slider-y"></div>
Scale<div class="slider slider-scale"></div>
</div>
<div class="slider-controls">
<p>Text</p>
X<div class="slider slider-text-x"></div>
Y<div class="slider slider-text-y"></div>
Scale<div class="slider slider-scale-title-text">
</div>
</div>
您将一个转换属性用于三个独立的操作,实际上覆盖了您需要维护的值。此外,transform="scale()" 始终围绕局部坐标系的原点进行缩放。因此,要原地缩放路径,它们必须以 x = y = 0 为中心。
以可维护的方式纠正情况的步骤:
将路径的平移和缩放分布到两个封闭组,外层是平移(.svg-position
),内层是缩放(.svg-size
)。
确定路径的中心:
document.querySelector('.svg-size').getBBox()
// returns { x: 27, y: 108, width: 458, height: 296 }
// => center at 256, 256
引入一个将路径移动到原点的内部组:translate(-256, -256)
将 256 * 0.4 = 102(四舍五入)添加到起始翻译以使路径回到其初始位置。
相应地调整比例值。
$( ".slider-x" ).slider({
min: -430,
max: 630,
value: 267,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-position').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-y" ).slider({
min: -150,
max: 350,
value: 52,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-position').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-scale" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
var scale = $( ".slider-scale" ).slider( "value" );
$('.svg-size ').attr("transform","scale(" + scale/100 + ")");
}
});
$( ".slider-scale-title-text" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var scale = $( ".slider-scale-title-text" ).slider( "value" );
$('.svg-business-title').css("font-size", scale+ "px");
}
});
$( ".slider-text-x" ).slider({
min: -100,
max: 635,
value: 250,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("x",x);
}
});
$( ".slider-text-y" ).slider({
min: 0,
max: 210,
value: 150,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("y",y);
}
});
h3 {
font-family: verdana;
}
.svg-business-title {
fill: brown;
stroke-width: 4;
}
.svg-strap-line {
fill: red;
stroke-width: 4;
}
.svg-custom-logo-wrapper {
fill: #94d31b;
position:absolute;
left:0; top:0; width:100%; height:100%;
}
.svg-wrapper {
width: 100%;
position:relative;
height:180px;
}
.svg-container {
max-width: 535px;
margin: 0 auto;
}
.accent-colour-1 {
fill: red;
}
.accent-colour-2 {
fill: green;
}
.svg-size{
/* transform: scale(0.2);
-ms-transform: scale(0.2);
-webkit-transform: scale(0.2); */
/* transform-origin: 270px 5px; */
}
.slider-controls, .slider-scale-title-text {
max-width: 540px;
}
.slider, input {
margin: 10px 0 10px 10px;
}
button {
margin: 5px 0 0 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="svg-container">
<div class="svg-wrapper">
<svg data-logoid="123" width="535" height="180" viewBox="0 0 535 180" class="svg-custom-logo-wrapper" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect width="535" height="180" style="fill:none;stroke-width:1;stroke:rgb(0,0,0)"/>
<g class="svg-position" transform="translate(267,52)">
<g class="svg-size" transform="scale(0.4)">
<g transform="translate(-256 -256)">
<path class="accent-colour-1 path-1" d="m 255,108 -97,97 -27,-27 -73,72 19,21 54,-54 106,107 -25,25 66,-26 105,-106 46,46 29,-11 -75,-74 -29,29 z m 0,40 79,79 -77,77 -79,-79 z m -16,63 h 14 v 14 h -14 z m 22,-22 h 14 v 14 h -14 z m 109,80 h 11 v 11 h -11 z m 18,-18 h 11 v 11 h -11 z m -278,43 h 16 v 15 h -16 z m 25,-25 h 16 v 15 h -16 z"></path>
<path class="accent-colour-2 path-2" d="M 164,381 48,259 27,281 160,404 485,254 Z M 388,269 h 11 v 11 h -11 z m -18,-18 h 11 v 11 h -11 z m -235,43 h 16 v 15 h -16 z m -25,-25 h 16 v 15 h -16 z m 151,-58 h 14 v 14 h -14 z m -22,-22 h 14 v 14 h -14 z"></path>
</g>
</g>
</g>
<text text-anchor="middle" class="title-text svg-business-title" transform="scale(1)" x="250" y="150" font-size="40">Title Text Here</text>
</svg>
</div>
</div>
<div class="slider-controls">
<p>LOGO</p>
X<div class="slider slider-x"></div>
Y<div class="slider slider-y"></div>
Scale<div class="slider slider-scale"></div>
</div>
<div class="slider-controls">
<p>Text</p>
X<div class="slider slider-text-x"></div>
Y<div class="slider slider-text-y"></div>
Scale<div class="slider slider-scale-title-text">
</div>
</div>
我有一个带有已定义文本和路径的 SVG 元素。请参阅我的示例代码。
文本按需要工作,从中心缩放并且可以准确定位,但我在 路径 上遇到了严重的问题。
当我触摸滑块移动 x 或 y 时,比例尺会被甩掉,它总是从左上角开始缩放。我在网上尝试了很多例子,但我没有运气,所以我清理了示例代码。
我希望能够从它的中心缩放路径,并且当我改变它的位置时它不会影响缩放。
$( ".slider-x" ).slider({
min: -530,
max: 530,
value: 165,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-size').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-y" ).slider({
min: -250,
max: 250,
value: -50,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-size').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-scale" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
var scale = $( ".slider-scale" ).slider( "value" );
$('.svg-size ').attr("transform","translate("+x+","+y+") scale(" + scale/100 + ")");
}
});
$( ".slider-scale-title-text" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var scale = $( ".slider-scale-title-text" ).slider( "value" );
$('.svg-business-title').css("font-size", scale+ "px");
}
});
$( ".slider-text-x" ).slider({
min: -100,
max: 635,
value: 250,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("x",x);
}
});
$( ".slider-text-y" ).slider({
min: 0,
max: 210,
value: 150,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("y",y);
}
});
h3 {
font-family: verdana;
}
.svg-business-title {
fill: brown;
stroke-width: 4;
}
.svg-strap-line {
fill: red;
stroke-width: 4;
}
.svg-custom-logo-wrapper {
fill: #94d31b;
position:absolute;
left:0; top:0; width:100%; height:100%;
}
.svg-wrapper {
width: 100%;
position:relative;
height:180px;
}
.svg-container {
max-width: 535px;
margin: 0 auto;
}
.accent-colour-1 {
fill: red;
}
.accent-colour-2 {
fill: green;
}
.svg-size{
/* transform: scale(0.2);
-ms-transform: scale(0.2);
-webkit-transform: scale(0.2); */
/* transform-origin: 270px 5px; */
}
.slider-controls, .slider-scale-title-text {
max-width: 540px;
}
.slider, input {
margin: 10px 0 10px 10px;
}
button {
margin: 5px 0 0 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="svg-container">
<div class="svg-wrapper">
<svg data-logoid="123" width="535" height="180" viewBox="0 0 535 180" class="svg-custom-logo-wrapper" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect width="535" height="180" style="fill:none;stroke-width:1;stroke:rgb(0,0,0)"/>
<g class="svg-size" transform="translate (165,-50) scale(0.4)"><path class="accent-colour-1 path-1" d="m 255,108 -97,97 -27,-27 -73,72 19,21 54,-54 106,107 -25,25 66,-26 105,-106 46,46 29,-11 -75,-74 -29,29 z m 0,40 79,79 -77,77 -79,-79 z m -16,63 h 14 v 14 h -14 z m 22,-22 h 14 v 14 h -14 z m 109,80 h 11 v 11 h -11 z m 18,-18 h 11 v 11 h -11 z m -278,43 h 16 v 15 h -16 z m 25,-25 h 16 v 15 h -16 z"></path></g>
<g class="svg-size" transform="translate (165,-50) scale(0.4)"><path class="accent-colour-2 path-2" d="M 164,381 48,259 27,281 160,404 485,254 Z M 388,269 h 11 v 11 h -11 z m -18,-18 h 11 v 11 h -11 z m -235,43 h 16 v 15 h -16 z m -25,-25 h 16 v 15 h -16 z m 151,-58 h 14 v 14 h -14 z m -22,-22 h 14 v 14 h -14 z"></path></g>
<text text-anchor="middle" class="title-text svg-business-title" transform="scale(1)" x="250" y="150" font-size="40">Title Text Here</text>
</svg>
</div>
</div>
<div class="slider-controls">
<p>LOGO</p>
X<div class="slider slider-x"></div>
Y<div class="slider slider-y"></div>
Scale<div class="slider slider-scale"></div>
</div>
<div class="slider-controls">
<p>Text</p>
X<div class="slider slider-text-x"></div>
Y<div class="slider slider-text-y"></div>
Scale<div class="slider slider-scale-title-text">
</div>
</div>
您将一个转换属性用于三个独立的操作,实际上覆盖了您需要维护的值。此外,transform="scale()" 始终围绕局部坐标系的原点进行缩放。因此,要原地缩放路径,它们必须以 x = y = 0 为中心。
以可维护的方式纠正情况的步骤:
将路径的平移和缩放分布到两个封闭组,外层是平移(
.svg-position
),内层是缩放(.svg-size
)。确定路径的中心:
document.querySelector('.svg-size').getBBox() // returns { x: 27, y: 108, width: 458, height: 296 } // => center at 256, 256
引入一个将路径移动到原点的内部组:
translate(-256, -256)
将 256 * 0.4 = 102(四舍五入)添加到起始翻译以使路径回到其初始位置。
相应地调整比例值。
$( ".slider-x" ).slider({
min: -430,
max: 630,
value: 267,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-position').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-y" ).slider({
min: -150,
max: 350,
value: 52,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
$('.svg-position').attr("transform","translate("+x+","+y+")");
}
});
$( ".slider-scale" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var x = $( ".slider-x" ).slider( "value" ),
y = $( ".slider-y" ).slider( "value" );
var scale = $( ".slider-scale" ).slider( "value" );
$('.svg-size ').attr("transform","scale(" + scale/100 + ")");
}
});
$( ".slider-scale-title-text" ).slider({
min: 1,
max: 100,
value: 40,
slide: function(){
var scale = $( ".slider-scale-title-text" ).slider( "value" );
$('.svg-business-title').css("font-size", scale+ "px");
}
});
$( ".slider-text-x" ).slider({
min: -100,
max: 635,
value: 250,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("x",x);
}
});
$( ".slider-text-y" ).slider({
min: 0,
max: 210,
value: 150,
slide: function(){
var x = $( ".slider-text-x" ).slider( "value" ),
y = $( ".slider-text-y" ).slider( "value" );
$('.title-text').attr("y",y);
}
});
h3 {
font-family: verdana;
}
.svg-business-title {
fill: brown;
stroke-width: 4;
}
.svg-strap-line {
fill: red;
stroke-width: 4;
}
.svg-custom-logo-wrapper {
fill: #94d31b;
position:absolute;
left:0; top:0; width:100%; height:100%;
}
.svg-wrapper {
width: 100%;
position:relative;
height:180px;
}
.svg-container {
max-width: 535px;
margin: 0 auto;
}
.accent-colour-1 {
fill: red;
}
.accent-colour-2 {
fill: green;
}
.svg-size{
/* transform: scale(0.2);
-ms-transform: scale(0.2);
-webkit-transform: scale(0.2); */
/* transform-origin: 270px 5px; */
}
.slider-controls, .slider-scale-title-text {
max-width: 540px;
}
.slider, input {
margin: 10px 0 10px 10px;
}
button {
margin: 5px 0 0 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="svg-container">
<div class="svg-wrapper">
<svg data-logoid="123" width="535" height="180" viewBox="0 0 535 180" class="svg-custom-logo-wrapper" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect width="535" height="180" style="fill:none;stroke-width:1;stroke:rgb(0,0,0)"/>
<g class="svg-position" transform="translate(267,52)">
<g class="svg-size" transform="scale(0.4)">
<g transform="translate(-256 -256)">
<path class="accent-colour-1 path-1" d="m 255,108 -97,97 -27,-27 -73,72 19,21 54,-54 106,107 -25,25 66,-26 105,-106 46,46 29,-11 -75,-74 -29,29 z m 0,40 79,79 -77,77 -79,-79 z m -16,63 h 14 v 14 h -14 z m 22,-22 h 14 v 14 h -14 z m 109,80 h 11 v 11 h -11 z m 18,-18 h 11 v 11 h -11 z m -278,43 h 16 v 15 h -16 z m 25,-25 h 16 v 15 h -16 z"></path>
<path class="accent-colour-2 path-2" d="M 164,381 48,259 27,281 160,404 485,254 Z M 388,269 h 11 v 11 h -11 z m -18,-18 h 11 v 11 h -11 z m -235,43 h 16 v 15 h -16 z m -25,-25 h 16 v 15 h -16 z m 151,-58 h 14 v 14 h -14 z m -22,-22 h 14 v 14 h -14 z"></path>
</g>
</g>
</g>
<text text-anchor="middle" class="title-text svg-business-title" transform="scale(1)" x="250" y="150" font-size="40">Title Text Here</text>
</svg>
</div>
</div>
<div class="slider-controls">
<p>LOGO</p>
X<div class="slider slider-x"></div>
Y<div class="slider slider-y"></div>
Scale<div class="slider slider-scale"></div>
</div>
<div class="slider-controls">
<p>Text</p>
X<div class="slider slider-text-x"></div>
Y<div class="slider slider-text-y"></div>
Scale<div class="slider slider-scale-title-text">
</div>
</div>