Видео как фон с рамкой - PullRequest
0 голосов
/ 25 июня 2019

Я использую jCrop , чтобы определить область обрезки для видеоэлемента. Я хочу, чтобы часть видео, определяемая областью кадрирования, заполняла контейнер, который имеет те же пропорции, что и область кадрирования, но у меня проблемы с математикой.

Размеры видео и области обрезки различаются, а размеры элементов быстро меняются, поэтому мне нужно рассчитать положение на основе координат.

Я использую CSS transform:scale(), чтобы увеличить видео и расположить его, чтобы показать область кадрирования, используя CSS transform:translate().

Вот схема того, что я хочу:

enter image description here

Ниже я смоделировал видео (зеленый) и область обрезки (красный). Когда пропорции видео и области кадрирования совпадают, это работает. Нажмите кнопку «зум», чтобы увеличить область обрезки.

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>

Что не так?
Я предполагаю, что я пропускаю что-то с вычислением или с тем, как работают проценты.
Я определенно открыт для предложений, если есть другой способ справиться с этим.

1 Ответ

0 голосов
/ 25 июня 2019

Это простая проблема выравнивания, измените top:50% на top:59%

#videoSrc {
  position: absolute;
  width: 100%;
  left: 50%;
  top: 59%;
  transform: translate(-50%, -50%);
  background-color: green;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...