剪辑路径动态转换以填充容器
clip-path dynamic transformations to fill container
我正在开发一个 React 组件,我希望能够传递任何图像及其尺寸,根据矩形区域的 x、y 宽度和高度计算的剪辑路径。这部分我工作得很好。然后我想缩放这个剪裁区域以填充 div,目前我只有原始图像尺寸 div 以保持简单。我有正确计算的缩放部分,但无法计算出平移缩放的剪辑路径区域的数学。这是我的组件(在 Typescript 中):
interface RootProps {
links: Link[];
}
interface RootState {
}
class Root extends React.Component<RootProps, RootState> {
constructor(props) {
super(props);
this.state = {
}
}
pp = (x: number, y: number): string => {
return x + "% " + y + "%"
}
renderClippedImage = (name: string, x: number, y: number, width: number, height: number) => {
let iWidth = 600;
let iHeight = 360;
let p1 = {
x: (x / iWidth) * 100,
y: (y / iHeight) * 100
}
let p2 = {
x: (x / iWidth) * 100,
y: ((y + height) / iHeight) * 100
}
let p3 = {
x: ((x + width) / iWidth) * 100,
y: ((y + height) / iHeight) * 100
}
let p4 = {
x: ((x + width) / iWidth) * 100,
y: (y / iHeight) * 100
}
let clipPathString = 'polygon(' +
this.pp(p1.x, p1.y) + ', ' +
this.pp(p2.x, p2.y) + ', ' +
this.pp(p3.x, p3.y) + ', ' +
this.pp(p4.x, p4.y) + ')';
let pX = (x) / iWidth;
let pY = (y) / iHeight;
let portionCoverageX = (width) / iWidth;
let portionCoverageY = (height) / iHeight;
let scaleX = 1;
let scaleY = 1;
if (portionCoverageX > 0) {
scaleX = 1 / portionCoverageX;
}
if (portionCoverageY > 0) {
scaleY = 1 / portionCoverageY;
}
let translateX = -(((pX * scaleX) / 2) * 100); //this doesn't work
let translateY = 0; //similar issues getting this to work
let pathClipping = {
WebkitClipPath: clipPathString,
clipPath: clipPathString,
transform: 'translateX(' + translateX + '%) translateY(' + translateY + '%) scaleX(' + scaleX + ') scaleY(' + scaleY + ')'
}
console.log({
name: name,
pX: pX,
pY: pY,
portionCoverageX: portionCoverageX,
portionCoverageY: portionCoverageY,
scaleX: scaleX,
scaleY: scaleY,
translateX: translateX,
translateY: translateY
})
return (
<div style={{ textAlign: 'center', width: '100%', backgroundColor: 'lightseagreen' }}>
<b>{name}</b><br />
<div style={{ display: 'inline-block', width: 640, height: 360, backgroundColor: 'darkslateblue' }}>
<img width="640" height="360" src="https://placekitten.com/640/360" style={pathClipping} />
</div>
</div>
)
}
render() {
return (
<div style={{textAlign: 'center'}}>
<b>Original</b><br />
<img width="640" height="360" src="https://placekitten.com/640/360" />
<br />
{this.renderClippedImage("one", 80, 100, 200, 100)}
<br />
{this.renderClippedImage("two", 50, 50, 150, 100)}
<br />
{this.renderClippedImage("three", 300, 10, 300, 340)}
</div>
)
}
}
ReactDOM.render(<Root />, document.getElementById('mount-node'));
这是一个代码笔,您可以在其中看到,我当前的数学实际上适用于场景 3,但它也需要适用于 1、2 和任何其他合法区域组合。
https://codepen.io/anon/pen/xMWGRO
我认为我正在努力的具体行是:
let translateX = (((pX * iWidth) / 2)); //this doesn't work for all examples
translateY 是一个类似的问题,任何帮助将不胜感激。
我认为您可以将 transform-origin
设置为 top left
,这样您可以更简单地计算变换位置和比例。
let scaleX = iWidth / width;
let scaleY = iHeight / height;
let pX = x / iWidth;
let pY = y / iHeight;
let translateX = -pX * 100 * scaleX;
let translateY = -pY * 100 * scaleY;
let pathClipping = {
WebkitClipPath: clipPathString,
clipPath: clipPathString,
transformOrigin: `top left`,
transform: `
translate(${translateX}%, ${translateY}%)
scale(${scaleX}, ${scaleY})
`
};
请在此处查看 codesandbox
我正在开发一个 React 组件,我希望能够传递任何图像及其尺寸,根据矩形区域的 x、y 宽度和高度计算的剪辑路径。这部分我工作得很好。然后我想缩放这个剪裁区域以填充 div,目前我只有原始图像尺寸 div 以保持简单。我有正确计算的缩放部分,但无法计算出平移缩放的剪辑路径区域的数学。这是我的组件(在 Typescript 中):
interface RootProps {
links: Link[];
}
interface RootState {
}
class Root extends React.Component<RootProps, RootState> {
constructor(props) {
super(props);
this.state = {
}
}
pp = (x: number, y: number): string => {
return x + "% " + y + "%"
}
renderClippedImage = (name: string, x: number, y: number, width: number, height: number) => {
let iWidth = 600;
let iHeight = 360;
let p1 = {
x: (x / iWidth) * 100,
y: (y / iHeight) * 100
}
let p2 = {
x: (x / iWidth) * 100,
y: ((y + height) / iHeight) * 100
}
let p3 = {
x: ((x + width) / iWidth) * 100,
y: ((y + height) / iHeight) * 100
}
let p4 = {
x: ((x + width) / iWidth) * 100,
y: (y / iHeight) * 100
}
let clipPathString = 'polygon(' +
this.pp(p1.x, p1.y) + ', ' +
this.pp(p2.x, p2.y) + ', ' +
this.pp(p3.x, p3.y) + ', ' +
this.pp(p4.x, p4.y) + ')';
let pX = (x) / iWidth;
let pY = (y) / iHeight;
let portionCoverageX = (width) / iWidth;
let portionCoverageY = (height) / iHeight;
let scaleX = 1;
let scaleY = 1;
if (portionCoverageX > 0) {
scaleX = 1 / portionCoverageX;
}
if (portionCoverageY > 0) {
scaleY = 1 / portionCoverageY;
}
let translateX = -(((pX * scaleX) / 2) * 100); //this doesn't work
let translateY = 0; //similar issues getting this to work
let pathClipping = {
WebkitClipPath: clipPathString,
clipPath: clipPathString,
transform: 'translateX(' + translateX + '%) translateY(' + translateY + '%) scaleX(' + scaleX + ') scaleY(' + scaleY + ')'
}
console.log({
name: name,
pX: pX,
pY: pY,
portionCoverageX: portionCoverageX,
portionCoverageY: portionCoverageY,
scaleX: scaleX,
scaleY: scaleY,
translateX: translateX,
translateY: translateY
})
return (
<div style={{ textAlign: 'center', width: '100%', backgroundColor: 'lightseagreen' }}>
<b>{name}</b><br />
<div style={{ display: 'inline-block', width: 640, height: 360, backgroundColor: 'darkslateblue' }}>
<img width="640" height="360" src="https://placekitten.com/640/360" style={pathClipping} />
</div>
</div>
)
}
render() {
return (
<div style={{textAlign: 'center'}}>
<b>Original</b><br />
<img width="640" height="360" src="https://placekitten.com/640/360" />
<br />
{this.renderClippedImage("one", 80, 100, 200, 100)}
<br />
{this.renderClippedImage("two", 50, 50, 150, 100)}
<br />
{this.renderClippedImage("three", 300, 10, 300, 340)}
</div>
)
}
}
ReactDOM.render(<Root />, document.getElementById('mount-node'));
这是一个代码笔,您可以在其中看到,我当前的数学实际上适用于场景 3,但它也需要适用于 1、2 和任何其他合法区域组合。
https://codepen.io/anon/pen/xMWGRO
我认为我正在努力的具体行是:
let translateX = (((pX * iWidth) / 2)); //this doesn't work for all examples
translateY 是一个类似的问题,任何帮助将不胜感激。
我认为您可以将 transform-origin
设置为 top left
,这样您可以更简单地计算变换位置和比例。
let scaleX = iWidth / width;
let scaleY = iHeight / height;
let pX = x / iWidth;
let pY = y / iHeight;
let translateX = -pX * 100 * scaleX;
let translateY = -pY * 100 * scaleY;
let pathClipping = {
WebkitClipPath: clipPathString,
clipPath: clipPathString,
transformOrigin: `top left`,
transform: `
translate(${translateX}%, ${translateY}%)
scale(${scaleX}, ${scaleY})
`
};
请在此处查看 codesandbox