html - 在图像顶部对齐 SVG 剪辑路径
问题描述
编辑 1:我当前问题的快速代码笔: https ://codepen.io/zuffdaddy/pen/QWGewKr 看看剪辑路径如何大而图像小?这两者如何对齐?
原来的:
简介: 我正在为潜艇模拟器游戏制作 Attack Disc。
圆盘有多个可以旋转的圆环,到目前为止,我已经完成了该部分,但是有一些重叠的透明塑料部件位于圆环顶部并旋转。
问题: 问题是在顶部旋转的塑料件是复杂的形状(这里是形状的图像)。用户需要能够在它们周围单击以操纵它们下方的环,但也能够单击它们来旋转它们。
SVG 剪辑路径似乎是要走的路,但我无法让 svg 剪辑路径与图像对齐。
请忽略 JS,这是我从另一个问题中提取的临时轮换脚本,将被重写以完成最终确定。
///////////////////////////////
// ------- rotate -------- //
///////////////////////////////
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('attack_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('course_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('aob_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('bearing_lead_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
html {
height: 100%;
overflow: hidden;
}
body {
background: #1c1c1c;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.wrapper {
height: 100%;
max-height: 960px;
width: 100%;
max-width: 960px;
position: relative;
margin: auto;
}
#attack_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/1.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 30vw;
max-width: 1124px;
height: 30vw;
max-height: 1124px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform-origin: 50% 50%;
border-radius: 50%;
}
#course_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/2.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 23vw;
max-width: 868px;
height: 23vw;
max-height: 868px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform-origin: 50% 50%;
border-radius: 50%;
}
#aob_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/3.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 15.5vw;
max-width: 592px;
height: 15.5vw;
max-height: 592px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform-origin: 50% 50%;
border-radius: 50%;
}
#bearing_lead_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/4.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
width: 23.5vw;
max-width: 884px;
height: 23.5vw;
max-height: 884px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
clip-path: url('#my-clip-path');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="attack_disc"></div>
<div id="course_disc"></div>
<div id="aob_disc"></div>
<div id="bearing_lead_disc">
<svg class="svg">
<clipPath id="my-clip-path" clipPathUnits="objectBoundingBox"><path d="M0.501,0 C0.556,0,0.555,0.04,0.555,0.04 C0.555,0.099,0.984,0.229,0.994,0.232 S1,0.243,0.999,0.251 C0.976,0.284,0.874,0.421,0.656,0.469 C0.656,0.469,0.648,0.47,0.647,0.474 C0.646,0.48,0.572,0.984,0.57,0.992 C0.569,0.996,0.569,0.999,0.561,0.999 C0.522,1,0.516,1,0.502,1 C0.487,1,0.482,1,0.443,0.999 C0.434,0.999,0.434,0.996,0.433,0.992 C0.432,0.984,0.358,0.48,0.357,0.474 C0.356,0.47,0.347,0.469,0.347,0.469 H0.347 C0.129,0.421,0.027,0.284,0.005,0.251 C0,0.243,0,0.236,0.01,0.232 S0.449,0.099,0.449,0.04 C0.449,0.04,0.447,0,0.502,0"></path></clipPath>
</svg>
</div>
</div>
解决方案
问题似乎是您提取了形状并将其转换为objectBoundingBox
相对于自身的坐标。因此 objectBoundingBox 坐标不再与您的攻击盘图像相关。
您可以做的是对剪辑路径应用变换以将其缩小到应有的位置。通过反复试验,我制定了适当的缩放比例,使其与应该剪辑的形状相匹配。
transform="translate(0.5,1) scale(0.415,0.52) translate(-0.5,-1)"
.svg {
position: absolute;
width: 0;
height: 0;
}
.clipped {
width: 884px;
height: 884px;
background: turquoise url(https://zuffdaddy.github.io/uboat-attack-disc/images/4.png);
background-size: cover;
-webkit-clip-path: url(#my-clip-path);
clip-path: url(#my-clip-path);
}
<svg class="svg">
<clipPath id="my-clip-path" clipPathUnits="objectBoundingBox"><path d="M0.501,0 C0.556,0,0.555,0.04,0.555,0.04 C0.555,0.099,0.984,0.229,0.994,0.232 S1,0.243,0.999,0.251 C0.976,0.284,0.874,0.421,0.656,0.469 C0.656,0.469,0.648,0.47,0.647,0.474 C0.646,0.48,0.572,0.984,0.57,0.992 C0.569,0.996,0.569,0.999,0.561,0.999 C0.522,1,0.516,1,0.502,1 C0.487,1,0.482,1,0.443,0.999 C0.434,0.999,0.434,0.996,0.433,0.992 C0.432,0.984,0.358,0.48,0.357,0.474 C0.356,0.47,0.347,0.469,0.347,0.469 H0.347 C0.129,0.421,0.027,0.284,0.005,0.251 C0,0.243,0,0.236,0.01,0.232 S0.449,0.099,0.449,0.04 C0.449,0.04,0.447,0,0.502,0" transform="translate(0.5,1) scale(0.415,0.52) translate(-0.5,-1)"></path></clipPath>
</svg>
<div class="clipped"></div>
推荐阅读
- android - android - 从@Bindable POJO 属性更新组件元素 - 数据绑定
- r - 如果样本出现在另一个数据集的行中,如何有条件地计数和记录?
- amazon-product-api - 我想使用 AWS API 从关键字中获取产品或 asins
- flutter - 我的颤振项目中的依赖不兼容
- android - Vimeo 和 Tus:上传卡在几秒钟后在 Android 上没有显示错误
- javascript - 如何在信用卡表格中验证到期日期?
- node.js - node.js“使用不推荐使用的字段:'series'”同时使用c3图表制作器
- html - 多次点击 Bootstrap 下拉菜单
- java - Java中jsp显示列表的问题
- javascript - 以编程方式从 iCloud 提取备份消息和/或已安装的应用程序列表