Я использую transform: scale(); transform-origin: 0 0; для увеличения содержимого страницы. Я изменяю масштаб, когда пользователь прокручивает страницу и устанавливает transform-origin в зависимости от расположения указателя. Это работает, но есть одна проблема. Если пользователь перемещает указатель мыши и выполняет прокрутку, содержимое переходит к указателю и масштабируется там. Что я делаю не так и как мне это исправить? Мне нужно, чтобы мой источник преобразования был указателем на таблицу. Вот мой код и рабочая скрипка:

https://jsfiddle.net/vaxobasilidze/v0pLwqd8/1/

Наведите указатель мыши на стол и прокрутите. Это будет увеличено. Затем переместите указатель мыши в другое место на столе и снова прокрутите. Контент начинает прыгать. Мне нужно получить эффект масштабирования, похожий на карты Google. В чем проблема в моем коде?

var zX = 1;
document.getElementById("mainDiv").addEventListener("wheel", function(e){
    e.preventDefault();
    var x = e.pageX;
    var y = e.pageY;
    var pageWidth = $('#mainDiv').width();
    var pageHeight = $('#mainDiv').height();
    var dir;
    if (e.deltaY > 0){
        dir = -0.05;
    }
    else{
        dir = 0.05;
    }
    if((zX + dir) >= 0.05){
        zX += dir;
    }
    //Math.floor(x/pageWidth*100)+'% '+Math.floor(y/pageHeight*100)+'%'
    $('#mainDiv').css({'transform': 'scale('+zX+')', 'transform-origin': Math.floor(x/pageWidth*100)+'% '+Math.floor(y/pageHeight*100)+'%'});
    return;
});


function showAudioDb(){
  var dbInterval = setInterval(function(){
    var dbLeft = Math.floor(Math.random() * 60) + 1;
    var dbRight = Math.floor(Math.random() * 60) + 1;
    var leftCover = Math.round(dbLeft/60*100);
    var rightCover = Math.round(dbRight/60*100);
    $('.audioLeft audioCover').animate({height: leftCover+'%'}, "slow")
    $('.audioRight audioCover').animate({height: rightCover+'%'}, "slow")
  }, 500);
}

showAudioDb();
.channels {
  /*border-collapse: collapse;*/
  border-spacing: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  font-weight: bold;
  border: 1px solid rgba(30, 30, 30, 1);
  border-radius: 4px;
  overflow: hidden;
  background: url(images/comment-bg3.png) repeat;
  resize: both;
}

.channels td {
  border-left: 1px solid rgba(30, 30, 30, 1);
}

.channels td:first-child {
  border-left: none;
}

.channelHeader {
  height: 7%;
  text-align: center;
  background: url(images/comment-bg2.png) repeat;
  box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -webkit-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -moz-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
}

.audioVideo {
  height: 79%;
}

.channelInfo {
  height: 7%;
  max-height: 7%;
  text-align: center;
  background: url(images/comment-bg2.png) repeat;
  border-bottom: 1px solid rgba(30, 30, 30, 1);
  border-top: 1px solid rgba(30, 30, 30, 1);
  box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -webkit-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -moz-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
}

.channelInfo td {
  border-radius: 2px 2px 0 0;
}

.channelInfoValues {
  height: 7%;
  max-height: 7%;
  text-align: center;
}

.str0 {stroke:white;stroke-width:3.97;stroke-miterlimit:22.9256}
.str1 {stroke:#999999;stroke-width:3.97;stroke-miterlimit:22.9256}
.fil1 {fill:none}
.fil0 {fill:#333333}

.sound {
  padding: 0;
  margin: 0;
}

.audiodb {
  width: 100%;
  height: 100%;
  position: relative;
}

.levels {
  position: absolute;
  width: 80%;
  margin-left: 5%;
  top: 5%;
  height: 1px;
  left: 10%;
  background: silver;
  z-index: 300;
}

.level1 {
  top: 15%;
}

.level2 {
  top: 35%;
}

.level3 {
  top: 95%;
}

.audioBackground {
  width: 30%;
  height: 90%;
  left: 20%;
  position: absolute;
  top: 5%;
  background: #ff0000;
  background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNvbG9yPSIjZmYwMDAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMjAlIiBzdG9wLWNvbG9yPSIjZmFmZjAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzglIiBzdG9wLWNvbG9yPSIjMDBmZjJhIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwNmQxMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
  background: -moz-linear-gradient(top, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%); /* FF3.6-15 */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff0000), color-stop(7%,#ff0000), color-stop(20%,#faff00), color-stop(38%,#00ff2a), color-stop(100%,#006d10)); /* Chrome4-9,Safari4-5 */
  background: -webkit-linear-gradient(top, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* Chrome10-25,Safari5.1-6 */
  background: -o-linear-gradient(top, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* Opera 11.10-11.50 */
  background: -ms-linear-gradient(top, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* IE10 preview */
  background: linear-gradient(to bottom, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#006d10',GradientType=0 );
}

.audioRight {
  left: 60%;
}

.audioCover {
  width: 100%;
  height: 30%;
  background: grey;
}
.audioNumbers {
  width: 10%;
  height: 100%;
  text-align: center;
  position: absolute;
}
.db {
  width: 100%;
  text-align: center;
  position: absolute;
  left: 15%;
}
.db p {
  margin-top: -5px;
}
.max {
  top: 5%;
}
.high {
  top: 15%;
}
.normal {
  top: 35%;
}
.low {
  top: 95%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-element-queries/0.4.0/ResizeSensor.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-element-queries/0.4.0/ElementQueries.min.js"></script>
<table class="channels ui-draggable ui-resizable" style="width: 476px; height: 266px; position: relative;" oncontextmenu="return false;" id="mainDiv">
  <tbody>
    <tr class="channelHeader ui-draggable-handle">
      <td colspan="5" class="channelName" id="channel1" audiopid="[0x33]" audiostream1="format:mp2,type:audio,pid:[0x33],width:0,height:0" interface="192.168.222.15" method="info" multicast="239.10.20.101" port="6000" protocol="udp" resolution="1920x1080" serviceid="1" servicename="undefined" serviceprovider="provider" videopid="[0x31]" videostream="format:h264,type:video,pid:[0x31],width:1920,height:1080">undefined</td>
      <td colspan="2" class="channelNumber">1</td>
    </tr>
    <tr class="audioVideo">
      <td colspan="5" class="vid"></td>
      <td colspan="2" class="sound">
        <div class="audiodb">
            <div class="audioNumbers">
              <span class="db max"><p>0</p></span>
              <span class="db high"><p>6</p></span>
              <span class="db normal"><p>18</p></span>
              <span class="db low"><p>60</p></span>
            </div>
            <div class="audioBackground audioLeft">
              <div class="audioCover"></div>
            </div>
            <div class="audioBackground audioRight">
              <div class="audioCover"></div>
            </div>
            <span class="levels level0"></span>
            <span class="levels level1"></span>
            <span class="levels level2"></span>
            <span class="levels level3"></span>
          </div>
      </td>
    </tr>
    <tr class="channelInfo">
      <td class="resolution">Resolution</td>
      <td class="aspect">Aspect</td>
      <td class="fps">FPS</td>
      <td class="vformat">V-Format</td>
      <td class="aformat">A-Format</td>
      <td>Left</td><td>Right</td>
    </tr>
    <tr class="channelInfoValues">
      <td class="resolValue">1920x1080</td>
      <td class="aspectValue">---</td>
      <td class="fpsValue">---</td>
      <td class="vformatValue">H-264</td>
      <td class="aformatValue">MP2</td>
      <td class="leftBarValue">---</td>
      <td class="rightBarValue">---</td>
    </tr>
    </tbody>
</table>
1
Vaxo Basilidze 1 Мар 2018 в 13:02

3 ответа

Лучший ответ

Хорошо, похоже, мы должны учитывать масштаб при расчете позиций трансформации.

Взгляните на этот подход. Я использовал переходы translate и scale и вычислял координаты в соответствии с масштабированием.

var current = {x: 0, y: 0, zoom: 1};
var max = 5, min = 0.1;
document.getElementById("mainDiv").addEventListener("wheel", function(e){
    e.preventDefault();
    var x = e.pageX, //you should subtract mainDiv x offset here if any
        y = e.pageY, //you should subtract mainDiv y offset here if any
        coef = e.deltaY > 0 ? 0.7 : 1.2,
        nz = current.zoom * coef,
        // calculate new positions according to zoom 
        cx = x - (x - current.x) * coef,
        cy = y - (y - current.y) * coef;
    if (nz < max && nz > min) {
    current.zoom = nz;
    current.x = cx;
    current.y = cy;
    this.style.transform
        = 'translate('+cx+'px, '+cy+'px) '
        + 'scale('+nz+')';
        }
    return;
});


function showAudioDb(){
  var dbInterval = setInterval(function(){
    var dbLeft = Math.floor(Math.random() * 60) + 1;
    var dbRight = Math.floor(Math.random() * 60) + 1;
    var leftCover = Math.round(dbLeft/60*100);
    var rightCover = Math.round(dbRight/60*100);
    $('.audioLeft audioCover').animate({height: leftCover+'%'}, "slow")
    $('.audioRight audioCover').animate({height: rightCover+'%'}, "slow")
  }, 500);
}

showAudioDb();
body {
  margin: 0;
}

.channels {
  /*border-collapse: collapse;*/
  border-spacing: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  font-weight: bold;
  border: 1px solid rgba(30, 30, 30, 1);
  border-radius: 4px;
  overflow: hidden;
  background: url(images/comment-bg3.png) repeat;
  resize: both;
}

.channels td {
  border-left: 1px solid rgba(30, 30, 30, 1);
}

.channels td:first-child {
  border-left: none;
}

.channelHeader {
  height: 7%;
  text-align: center;
  background: url(images/comment-bg2.png) repeat;
  box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -webkit-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -moz-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
}

.audioVideo {
  height: 79%;
}

.channelInfo {
  height: 7%;
  max-height: 7%;
  text-align: center;
  background: url(images/comment-bg2.png) repeat;
  border-bottom: 1px solid rgba(30, 30, 30, 1);
  border-top: 1px solid rgba(30, 30, 30, 1);
  box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -webkit-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
  -moz-box-shadow: 0 2px 2px rgba(0,0,0,0.26);
}

.channelInfo td {
  border-radius: 2px 2px 0 0;
}

.channelInfoValues {
  height: 7%;
  max-height: 7%;
  text-align: center;
}

.str0 {stroke:white;stroke-width:3.97;stroke-miterlimit:22.9256}
.str1 {stroke:#999999;stroke-width:3.97;stroke-miterlimit:22.9256}
.fil1 {fill:none}
.fil0 {fill:#333333}

.sound {
  padding: 0;
  margin: 0;
}

.audiodb {
  width: 100%;
  height: 100%;
  position: relative;
}

.levels {
  position: absolute;
  width: 80%;
  margin-left: 5%;
  top: 5%;
  height: 1px;
  left: 10%;
  background: silver;
  z-index: 300;
}

.level1 {
  top: 15%;
}

.level2 {
  top: 35%;
}

.level3 {
  top: 95%;
}

.audioBackground {
  width: 30%;
  height: 90%;
  left: 20%;
  position: absolute;
  top: 5%;
  background: #ff0000;
  background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNvbG9yPSIjZmYwMDAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMjAlIiBzdG9wLWNvbG9yPSIjZmFmZjAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzglIiBzdG9wLWNvbG9yPSIjMDBmZjJhIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwNmQxMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
  background: -moz-linear-gradient(top, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%); /* FF3.6-15 */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff0000), color-stop(7%,#ff0000), color-stop(20%,#faff00), color-stop(38%,#00ff2a), color-stop(100%,#006d10)); /* Chrome4-9,Safari4-5 */
  background: -webkit-linear-gradient(top, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* Chrome10-25,Safari5.1-6 */
  background: -o-linear-gradient(top, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* Opera 11.10-11.50 */
  background: -ms-linear-gradient(top, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* IE10 preview */
  background: linear-gradient(to bottom, #ff0000 0%,#ff0000 7%,#faff00 20%,#00ff2a 38%,#006d10 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#006d10',GradientType=0 );
}

.audioRight {
  left: 60%;
}

.audioCover {
  width: 100%;
  height: 30%;
  background: grey;
}
.audioNumbers {
  width: 10%;
  height: 100%;
  text-align: center;
  position: absolute;
}
.db {
  width: 100%;
  text-align: center;
  position: absolute;
  left: 15%;
}
.db p {
  margin-top: -5px;
}
.max {
  top: 5%;
}
.high {
  top: 15%;
}
.normal {
  top: 35%;
}
.low {
  top: 95%;
}

#mainDiv {
  transition: all 100ms ease-in-out;
  transform-origin: 0 0 0;
  transform: translate(0,0) scale(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-element-queries/0.4.0/ResizeSensor.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-element-queries/0.4.0/ElementQueries.min.js"></script>
<table class="channels ui-draggable ui-resizable" style="width: 476px; height: 266px; position: relative;" oncontextmenu="return false;" id="mainDiv">
  <tbody>
    <tr class="channelHeader ui-draggable-handle">
      <td colspan="5" class="channelName" id="channel1" audiopid="[0x33]" audiostream1="format:mp2,type:audio,pid:[0x33],width:0,height:0" interface="192.168.222.15" method="info" multicast="239.10.20.101" port="6000" protocol="udp" resolution="1920x1080" serviceid="1" servicename="undefined" serviceprovider="provider" videopid="[0x31]" videostream="format:h264,type:video,pid:[0x31],width:1920,height:1080">undefined</td>
      <td colspan="2" class="channelNumber">1</td>
    </tr>
    <tr class="audioVideo">
      <td colspan="5" class="vid"></td>
      <td colspan="2" class="sound">
        <div class="audiodb">
            <div class="audioNumbers">
              <span class="db max"><p>0</p></span>
              <span class="db high"><p>6</p></span>
              <span class="db normal"><p>18</p></span>
              <span class="db low"><p>60</p></span>
            </div>
            <div class="audioBackground audioLeft">
              <div class="audioCover"></div>
            </div>
            <div class="audioBackground audioRight">
              <div class="audioCover"></div>
            </div>
            <span class="levels level0"></span>
            <span class="levels level1"></span>
            <span class="levels level2"></span>
            <span class="levels level3"></span>
          </div>
      </td>
    </tr>
    <tr class="channelInfo">
      <td class="resolution">Resolution</td>
      <td class="aspect">Aspect</td>
      <td class="fps">FPS</td>
      <td class="vformat">V-Format</td>
      <td class="aformat">A-Format</td>
      <td>Left</td><td>Right</td>
    </tr>
    <tr class="channelInfoValues">
      <td class="resolValue">1920x1080</td>
      <td class="aspectValue">---</td>
      <td class="fpsValue">---</td>
      <td class="vformatValue">H-264</td>
      <td class="aformatValue">MP2</td>
      <td class="leftBarValue">---</td>
      <td class="rightBarValue">---</td>
    </tr>
    </tbody>
</table>
2
Kirill Simonov 9 Мар 2018 в 08:34
var zX = 1;
document.getElementById("mainDiv").addEventListener("wheel", function (e) {
    e.preventDefault();
    var x = e.pageX;
    var y = e.pageY;
    var pageWidth = $('#mainDiv').width();
    var pageHeight = $('#mainDiv').height();
    var dir;
    if (e.deltaY > 0) {
        dir = -0.05;
    } else {
        dir = 0.05;
    }
    if ((zX + dir) >= 0.05) {
        zX += dir;
    }
    //Math.floor(x/pageWidth*100)+'% '+Math.floor(y/pageHeight*100)+'%'
    if (zX >= 1) {
      $('#mainDiv tbody').css({
          'transform': 'scale(' + zX + ')',
          'transform-origin': Math.floor(x/pageWidth*100)+'% '+Math.floor(y/pageHeight*100)+'%'
      });
    } else {
      zX = 1; 
    }

    return;
});

function showAudioDb() {
    var dbInterval = setInterval(function () {
        var dbLeft = Math.floor(Math.random() * 60) + 1;
        var dbRight = Math.floor(Math.random() * 60) + 1;
        var leftCover = Math.round(dbLeft / 60 * 100);
        var rightCover = Math.round(dbRight / 60 * 100);
        $('.audioLeft audioCover').animate({
            height: leftCover + '%'
        }, "slow")
        $('.audioRight audioCover').animate({
            height: rightCover + '%'
        }, "slow")
    }, 500);
}

showAudioDb();
.channels {
    /*border-collapse: collapse;*/
    border-spacing: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    font-weight: bold;
    border: 1px solid rgba(30, 30, 30, 1);
    border-radius: 4px;
    overflow: hidden;
    background: url(images/comment-bg3.png) repeat;
    resize: both;
}

.channels td {
    border-left: 1px solid rgba(30, 30, 30, 1);
}

.channels td:first-child {
    border-left: none;
}

.channelHeader {
    height: 7%;
    text-align: center;
    background: url(images/comment-bg2.png) repeat;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.26);
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.26);
    -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.26);
}

.audioVideo {
    height: 79%;
}

.channelInfo {
    height: 7%;
    max-height: 7%;
    text-align: center;
    background: url(images/comment-bg2.png) repeat;
    border-bottom: 1px solid rgba(30, 30, 30, 1);
    border-top: 1px solid rgba(30, 30, 30, 1);
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.26);
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.26);
    -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.26);
}

.channelInfo td {
    border-radius: 2px 2px 0 0;
}

.channelInfoValues {
    height: 7%;
    max-height: 7%;
    text-align: center;
}

.str0 {
    stroke: white;
    stroke-width: 3.97;
    stroke-miterlimit: 22.9256
}

.str1 {
    stroke: #999999;
    stroke-width: 3.97;
    stroke-miterlimit: 22.9256
}

.fil1 {
    fill: none
}

.fil0 {
    fill: #333333
}

.sound {
    padding: 0;
    margin: 0;
}

.audiodb {
    width: 100%;
    height: 100%;
    position: relative;
}

.levels {
    position: absolute;
    width: 80%;
    margin-left: 5%;
    top: 5%;
    height: 1px;
    left: 10%;
    background: silver;
    z-index: 300;
}

.level1 {
    top: 15%;
}

.level2 {
    top: 35%;
}

.level3 {
    top: 95%;
}

.audioBackground {
    width: 30%;
    height: 90%;
    left: 20%;
    position: absolute;
    top: 5%;
    background: #ff0000;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNvbG9yPSIjZmYwMDAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMjAlIiBzdG9wLWNvbG9yPSIjZmFmZjAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzglIiBzdG9wLWNvbG9yPSIjMDBmZjJhIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwNmQxMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
    background: -moz-linear-gradient(top, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%);
    /* FF3.6-15 */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ff0000), color-stop(7%, #ff0000), color-stop(20%, #faff00), color-stop(38%, #00ff2a), color-stop(100%, #006d10));
    /* Chrome4-9,Safari4-5 */
    background: -webkit-linear-gradient(top, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%);
    /* Chrome10-25,Safari5.1-6 */
    background: -o-linear-gradient(top, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%);
    /* Opera 11.10-11.50 */
    background: -ms-linear-gradient(top, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%);
    /* IE10 preview */
    background: linear-gradient(to bottom, #ff0000 0%, #ff0000 7%, #faff00 20%, #00ff2a 38%, #006d10 100%);
    /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#006d10', GradientType=0);
}

.audioRight {
    left: 60%;
}

.audioCover {
    width: 100%;
    height: 30%;
    background: grey;
}

.audioNumbers {
    width: 10%;
    height: 100%;
    text-align: center;
    position: absolute;
}

.db {
    width: 100%;
    text-align: center;
    position: absolute;
    left: 15%;
}

.db p {
    margin-top: -5px;
}

.max {
    top: 5%;
}

.high {
    top: 15%;
}

.normal {
    top: 35%;
}

.low {
    top: 95%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-element-queries/0.4.0/ResizeSensor.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-element-queries/0.4.0/ElementQueries.min.js"></script>
<table class="channels ui-draggable ui-resizable" style="width: 476px; height: 266px; position: relative;" oncontextmenu="return false;"
    id="mainDiv">
    <tbody>
        <tr class="channelHeader ui-draggable-handle">
            <td colspan="5" class="channelName" id="channel1" audiopid="[0x33]" audiostream1="format:mp2,type:audio,pid:[0x33],width:0,height:0"
                interface="192.168.222.15" method="info" multicast="239.10.20.101" port="6000" protocol="udp" resolution="1920x1080"
                serviceid="1" servicename="undefined" serviceprovider="provider" videopid="[0x31]" videostream="format:h264,type:video,pid:[0x31],width:1920,height:1080">undefined</td>
            <td colspan="2" class="channelNumber">1</td>
        </tr>
        <tr class="audioVideo">
            <td colspan="5" class="vid"></td>
            <td colspan="2" class="sound">
                <div class="audiodb">
                    <div class="audioNumbers">
                        <span class="db max">
                            <p>0</p>
                        </span>
                        <span class="db high">
                            <p>6</p>
                        </span>
                        <span class="db normal">
                            <p>18</p>
                        </span>
                        <span class="db low">
                            <p>60</p>
                        </span>
                    </div>
                    <div class="audioBackground audioLeft">
                        <div class="audioCover"></div>
                    </div>
                    <div class="audioBackground audioRight">
                        <div class="audioCover"></div>
                    </div>
                    <span class="levels level0"></span>
                    <span class="levels level1"></span>
                    <span class="levels level2"></span>
                    <span class="levels level3"></span>
                </div>
            </td>
        </tr>
        <tr class="channelInfo">
            <td class="resolution">Resolution</td>
            <td class="aspect">Aspect</td>
            <td class="fps">FPS</td>
            <td class="vformat">V-Format</td>
            <td class="aformat">A-Format</td>
            <td>Left</td>
            <td>Right</td>
        </tr>
        <tr class="channelInfoValues">
            <td class="resolValue">1920x1080</td>
            <td class="aspectValue">---</td>
            <td class="fpsValue">---</td>
            <td class="vformatValue">H-264</td>
            <td class="aformatValue">MP2</td>
            <td class="leftBarValue">---</td>
            <td class="rightBarValue">---</td>
        </tr>
    </tbody>
</table>

< Сильный > Обновление

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

1
Cata John 1 Мар 2018 в 11:40

Я бы порекомендовал вам использовать jquery panzoom. Он может делать то, что, я думаю, вы ожидаете достичь. Это также позволит вам перемещаться рядом с функцией масштабирования.

0
Paun Narcis Iulian 8 Мар 2018 в 13:02