在视频元素上获得准确的鼠标坐标

时间:2016-03-13 17:25:52

标签: javascript html video coordinates

我遇到一些涉及视频元素全面放映的问题:

当鼠标在视频元素上移动时,我有一个跟踪X和Y线的代码:

<video id="video" preload=auto autoplay controls>
<source src = "http://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv">
</video>

function getElementCSSSize(el) {
    var cs = getComputedStyle(el);
    var w = parseInt(cs.getPropertyValue("width"), 10);
    var h = parseInt(cs.getPropertyValue("height"), 10);
    return {width: w, height: h}
}

function mouseHandler(event) {
    var size = getElementCSSSize(this);
    var scaleX = this.videoWidth / size.width;
    var scaleY = this.videoHeight / size.height;

    var rect = this.getBoundingClientRect();  // absolute position of element
    var x = ((event.clientX - rect.left) * scaleX + 0.5)|0; // round to integer
    var y = ((event.clientY - rect.top ) * scaleY + 0.5)|0;
    console.log("x " + x);
    console.log("y " + y);


}

video.addEventListener("mousemove", mouseHandler);

现在,在正常模式下观看视频时效果非常好; 如果例如视频是237x132, 那么最大左边是0x,最大顶部是0。

问题出现在完整模式下; 如您所见,顶部和底部有黑色边框: https://i.imgsafe.org/452a426.jpg

现在,我检查的每个视频都是如此。  因此,在我上面的脚本中,出于某种原因它会计算  黑色边框作为视频的一部分; x是好的,但是 y不是; y开头于  视频,在黑色边框上。

我需要在这里非常精确,并且完全忽略黑色边框 - y应该从真实像素开始并以真实像素结束。 因此,在完全模式下播放的每种类型的电影都应该忽略黑色边框。

非常感谢您的时间。

1 个答案:

答案 0 :(得分:0)

function mouseHandler(event) {
    var rect = this.getBoundingClientRect();
    if (!('height' in rect)) {//for IE8
        rect.height = rect.bottom - rect.top;
        rect.width = rect.right - rect.left;
    }
    var actualVideoHeight = rect.height;
    var actualVideoWidth = rect.width;
    var borderTop = 0;
    var borderLeft = 0;
    var onBottomBorder = false;
    var onRightBorder = false;
    var videoRatio = this.videoWidth / this.videoHeight;
    var elementRatio = rect.width / rect.height;
    if (videoRatio > elementRatio) {//video is wider than element
        actualVideoHeight = this.videoHeight * rect.width / this.videoWidth;//actual height of video without borders
        borderTop = (rect.height - actualVideoHeight) / 2;//calculate size of top border
        if (event.clientY > actualVideoHeight + borderTop) {//check if mouse in on bottom border
            onBottomBorder = true;
        }
    } else if (videoRatio < elementRatio) {//element is wider than video
        actualVideoWidth = this.videoWidth * rect.height / this.videoHeight;//actual width of video without borders
        borderLeft = (rect.width - actualVideoWidth) / 2;//calculate size of left border
        if (event.clientX > Math.round(actualVideoWidth + borderLeft)) {//check if mouse in on right border
            //onRightBorder = true;
        }
    }
    var x = Math.round((event.clientX - rect.left - borderLeft) * (this.videoWidth / actualVideoWidth)); //scale and round to integer
    var y = Math.round((event.clientY - rect.top - borderTop) * this.videoHeight / actualVideoHeight);
    /*
    x will be negative if mouse is on left border
    y will be negative if mouse is on top border
    onRightBorder will be true if mouse is on right border
    onBottomBorder will be true if mouse is on bottom border
    */
    if (y > 0 && x > 0 && !onRightBorder && !onBottomBorder) {
        console.log('x ' + x);
        console.log('y ' + y);
    }
}
相关问题