Я использую jCrop , чтобы определить область обрезки для видеоэлемента. Я хочу, чтобы часть видео, определяемая областью кадрирования, заполняла контейнер, который имеет те же пропорции, что и область кадрирования, но у меня проблемы с математикой.
Размеры видео и области обрезки различаются, а размеры элементов быстро меняются, поэтому мне нужно рассчитать положение на основе координат.
Я использую CSS transform:scale()
, чтобы увеличить видео и расположить его, чтобы показать область кадрирования, используя CSS transform:translate()
.
Вот схема того, что я хочу:
![enter image description here](https://i.stack.imgur.com/4b6cm.jpg)
Ниже я смоделировал видео (зеленый) и область обрезки (красный). Когда пропорции видео и области кадрирования совпадают, это работает. Нажмите кнопку «зум», чтобы увеличить область обрезки.
let $container = $('#container');
let $videoWrap = $('#videoWrap');
let $videoSrc = $('#videoSrc');
let $videoCrop = $('#videoCrop');
let videoWidth = 1280;
let videoHeight = 720;
let cropArea = {
'x': 500,
'y': 80,
'w': 640,
'h': 360
};
$container.css({
'padding-bottom': (cropArea.h / cropArea.w) * 100 + '%'
});
$videoSrc.css({
'padding-bottom': videoHeight / videoWidth * 100 + '%'
});
$videoCrop.css({
'width': (cropArea.w / videoWidth) * 100 + '%',
'height': (cropArea.h / videoHeight) * 100 + '%',
'left': (cropArea.x / videoWidth) * 100 + '%',
'top': (cropArea.y / videoHeight) * 100 + '%'
});
let scale = videoWidth / cropArea.w;
let tx = 0 - (cropArea.x / videoWidth * 100);
let ty = 0 - (cropArea.y / videoHeight * 100);
let css = {
'transform-origin': '0 0',
'transform': 'scale(' + scale + ') translate(' + tx + '%,' + ty + '%)'
};
$('#zoom').on('click', function() {
$videoWrap.css(css);
});
body {
margin: 5px;
width: 200px;
}
#container {
position: relative;
overflow: hidden;
outline: 5px solid blue;
}
#videoWrap {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
transition: all 1s;
}
#videoSrc {
position: absolute;
width: 100%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: green;
}
#videoCrop {
position: absolute;
background-color: red;
border: 1px solid yellow;
box-sizing: border-box;
}
#zoom {
margin: 2em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="videoWrap">
<div id="videoSrc">
<div id="videoCrop"></div>
</div>
</div>
</div>
<button id="zoom">Zoom</button>
Но когда область обрезки имеет размеры, отличные от видео, видео дополняется (например, почтовый ящик), что смещает масштаб.
let $container = $('#container');
let $videoWrap = $('#videoWrap');
let $videoSrc = $('#videoSrc');
let $videoCrop = $('#videoCrop');
let videoWidth = 1280;
let videoHeight = 720;
let cropArea = {
'x': 500,
'y': 80,
'w': 440,
'h': 500
};
$container.css({
'padding-bottom': (cropArea.h / cropArea.w) * 100 + '%'
});
$videoSrc.css({
'padding-bottom': videoHeight / videoWidth * 100 + '%'
});
$videoCrop.css({
'width': (cropArea.w / videoWidth) * 100 + '%',
'height': (cropArea.h / videoHeight) * 100 + '%',
'left': (cropArea.x / videoWidth) * 100 + '%',
'top': (cropArea.y / videoHeight) * 100 + '%'
});
let scale = videoWidth / cropArea.w;
let tx = 0 - (cropArea.x / videoWidth * 100);
let ty = 0 - (cropArea.y / videoHeight * 100);
let css = {
'transform-origin': '0 0',
'transform': 'scale(' + scale + ') translate(' + tx + '%,' + ty + '%)'
};
$('#zoom').on('click', function() {
$videoWrap.css(css);
});
body {
margin: 5px;
width: 100px;
}
#container {
position: relative;
overflow: hidden;
outline: 5px solid blue;
}
#videoWrap {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
transition: all 1s;
}
#videoSrc {
position: absolute;
width: 100%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: green;
}
#videoCrop {
position: absolute;
background-color: red;
border: 1px solid yellow;
box-sizing: border-box;
}
#zoom {
margin: 2em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="videoWrap">
<div id="videoSrc">
<div id="videoCrop"></div>
</div>
</div>
</div>
<button id="zoom">Zoom</button>
Я пытался подсчитать количество добавляемого видео и добавить его в CSS для перевода, чтобы переместить видео вверх, но я не должен рассчитывать его правильно.
let $container = $('#container');
let $videoWrap = $('#videoWrap');
let $videoSrc = $('#videoSrc');
let $videoCrop = $('#videoCrop');
let videoWidth = 1280;
let videoHeight = 720;
let cropArea = {
'x': 500,
'y': 80,
'w': 440,
'h': 500
};
$container.css({
'padding-bottom': (cropArea.h / cropArea.w) * 100 + '%'
});
$videoSrc.css({
'padding-bottom': videoHeight / videoWidth * 100 + '%'
});
$videoCrop.css({
'width': (cropArea.w / videoWidth) * 100 + '%',
'height': (cropArea.h / videoHeight) * 100 + '%',
'left': (cropArea.x / videoWidth) * 100 + '%',
'top': (cropArea.y / videoHeight) * 100 + '%'
});
let scale = videoWidth / cropArea.w;
let tx = 0 - (cropArea.x / videoWidth * 100);
let ty = 0 - (cropArea.y / videoHeight * 100);
let offsetY = ((cropArea.h / cropArea.w) - (videoHeight / videoWidth)) / 2 * 100;
ty -= offsetY;
let css = {
'transform-origin': '0 0',
'transform': 'scale(' + scale + ') translate(' + tx + '%,' + ty + '%)'
};
$('#zoom').on('click', function() {
$videoWrap.css(css);
});
body {
margin: 5px;
width: 100px;
}
#container {
position: relative;
overflow: hidden;
outline: 5px solid blue;
}
#videoWrap {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
transition: all 1s;
}
#videoSrc {
position: absolute;
width: 100%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: green;
}
#videoCrop {
position: absolute;
background-color: red;
border: 1px solid yellow;
box-sizing: border-box;
}
#zoom {
margin: 2em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="videoWrap">
<div id="videoSrc">
<div id="videoCrop"></div>
</div>
</div>
</div>
<button id="zoom">Zoom</button>
Что не так?
Я предполагаю, что я пропускаю что-то с вычислением или с тем, как работают проценты.
Я определенно открыт для предложений, если есть другой способ справиться с этим.