gpt4 book ai didi

javascript - Canvas 中的链接 (HTML5)

转载 作者:行者123 更新时间:2023-11-28 16:54:37 26 4
gpt4 key购买 nike

我已经知道如何实现用户界面,我已经做到了。但是在某些时刻我的 FPS 较低。通过使用 Firefox 进行性能测试,我注意到那些时刻是浏览器重新计算 CSS 的时候。

它必须重新计算 CSS,因为我通过插入 css 规则“cursor:pointer”修改了属性“style”。我这样做是因为在我的 Canvas 中有一些链接需要不同的光标。但我想优化该功能以避免卡住。关于如何做到这一点有什么想法吗?

我的代码是这样做的:addEventHandler 到 canvas (mousemove),每次触发事件时它都会检查光标坐标,如果我的光标坐标在链接上它会将光标更改为“指针”,它还会将一个名为 hoverIndex 的变量设置为链接在数组中的位置。

var sky = new Image();
var logotype = new Image();
var back_btn = new Image();
var next_btn = new Image();
var upgrades_btn = new Image();

var coin_five = new Image();
var coin_ten = new Image();
var coin_fifty = new Image();
var cash_hundred = new Image();

var currentArea = "main_menu";
var cvn, ctx;

var linkAreas = [];
var hoverIndex = -1;

var gameVersion = "1.2.2a";

var coinFiveReset = 1500;
var coinTenReset = 5000;
var coinFiftyReset = 10000;
var coinHundredReset = 10000;

var coinFiveRemaining = 1500;
var coinTenRemaining = -1;
var coinFiftyRemaining = -1;
var coinHundredRemaining = -1;

var playingInterval;

//{type: "five", x: 0, y: 0}
var coinsPlaying = [];

function initialization(){
cvn = document.getElementById("kg_coinfactory");
ctx = cvn.getContext("2d");

cvn.addEventListener("mousemove", function(ev){
var pos = getMousePosition(ev);
for(var x = 0; x<linkAreas.length; x++)
if(currentArea == linkAreas[x].area && pos.x >= linkAreas[x].x && pos.y >= linkAreas[x].y && pos.x <= linkAreas[x].x + linkAreas[x].width && pos.y <= linkAreas[x].y + linkAreas[x].height)
{
hoverIndex = x;
cvn.style = "cursor: pointer";
break;
}
else
{
cvn.style = "";
hoverIndex = -1;
}
});

cvn.addEventListener("mouseup", function(){
if(hoverIndex != -1)
linkAreas[hoverIndex].onClickFunc();
});
}

function getMousePosition(ev){
var rect = cvn.getBoundingClientRect();
return {x: ev.clientX - rect.left, y: ev.clientY - rect.top};
}

function registerLink(x, y, text, area, ctx, onClickFunc)
{
var s = ctx.measureText(text);
linkAreas.push({x: x, y: y - 24, width: s.width, height: 24, area: area, onClickFunc: onClickFunc});
}

最佳答案

FPS 真的下降那么多值得担心吗?

无论如何,您可以保存光标的现有状态,并且仅当光标移入或移出悬停区域时才更改它。

或者,如果您不需要 Canvas 响应悬停区域下的鼠标事件,您可以在 Canvas 上position:absolute 一个 DOM 元素并让该元素响应悬停和点击事件.

或者,您可以在 Canvas 上关闭指针并绘制您自己的指针。

或者,在极端情况下,您甚至可以在现有 Canvas 上覆盖第二个 Canvas ,并仅在第二个 Canvas 上绘制图像指针。在第二个 Canvas 上设置 pointer-events:none,这样您的鼠标事件就会传递到现有的底层 Canvas 。

顺便说一句,您的鼠标位置计算可以更有效率。

您的 getMousePosition 会为每个 mousemove 事件调用 getBoundingClientRect。相反,保存 rect.leftrect.top 并使用那些保存的 offsetX & offsetY 值而不是使用更昂贵的 getBoundingClientRect()。如果窗口调整大小或滚动,您必须重新计算边界框。以下是如何执行此操作的示例:

var offsetX,offsetY;
reOffset();

function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}

window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

调用外部函数(getMousePosition)确实会导致一些额外的处理,因此您可以直接在鼠标事件处理程序中计算鼠标位置。

此外,由于您自己处理 mousemove 事件,您可以通过告诉浏览器它不需要将此事件冒泡到其他元素来节省处理:

// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();

因此,更高效的鼠标事件处理程序可能如下所示:

cvn.addEventListener("mousemove", function(ev){    

// tell the browser we're handling this event
ev.preventDefault();
ev.stopPropagation();

// calc the mouse position directly in the handler
// and use cached offset values
mouseX=parseInt(ev.clientX-offsetX);
mouseY=parseInt(ev.clientY-offsetY);

... and now do stuff ...

}

关于javascript - Canvas 中的链接 (HTML5),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32358021/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com