使特定div在画布上的一点上居中



我有一个游戏,其中画布用于制作游戏的大部分动画,但游戏的计时器没有在画布上渲染,而是在一个单独的div中。我一直在试图找到一种方法,将计时器集中在画布上的正方形(均显示在下面的片段中)所集中的同一点上,这种方法也是被动的,适用于任何平台/屏幕大小。到目前为止,我所尝试的一切要么适用于移动设备,要么不适用于浏览器,反之亦然。你知道如何将计时器集中在与任何屏幕大小的画布对象相同的点上吗?

function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
async function timer(){
timeleft = 15;
var downloadTimer = setInterval(function(){
if(timeleft <= 0){
clearInterval(downloadTimer);
document.getElementById("timer").innerHTML = "0";
gameOverText.innerHTML = "Your Score: " + score;
gameOverModal.style.display = "block";
DoExampleLoginWithCustomID()
console.log(score);
} else {
document.getElementById("timer").innerHTML = timeleft;
}
timeleft -= 1;
}, 1000);
}
function initTimer(top, left){
var timer = document.getElementById("timer");
timer.innerHTML = "15";
timer.style.textAlign = "center";
timer.style.position = "absolute";
timer.style.top = top;
timer.style.left = left;
timer.style.transform = "translate(-50%, 0%)";
timer.style.fontSize = "4vw";
timer.style.letterSpacing = "0.1em";
timer.style.webkitTextStrokeWidth = "0px";
timer.style.webkitTextFillColor = "transparent";
//timer.style.webkitTextStrokeColor = "white";
timer.style.textShadow = "2px 2px " + textColor + ", 4px 4px " + shadowColor + "";
}
class rectButton {
constructor(padx, pady, height, width, r, g, b, target) {
this.padx = padx;
this.pady = pady;
this.height = height;
this.width = width;
this.r = r;
this.g = g;
this.b = b;
this.fillColor = "rgb(" + [r,g,b].join() + ")";
this.strokeColor = "rgb(" + [r*(0.5),g*(0.5),b*(0.5)].join() + ")";
this.target = target;
}
setChosen(percent){
if (first = true){
this.r = Math.floor(parseFloat(this.r) * parseFloat(percent));
this.g = Math.floor(parseFloat(this.g) * parseFloat(percent));
this.b = Math.floor(parseFloat(this.b) * parseFloat(percent));
this.fillColor = "rgb(" + [this.r,this.g,this.b].join() + ")";
}
}
}
//Initialize Canvas
var canvas = document.getElementsByClassName("game");
var parent = document.getElementsByClassName("gameCont");
canvas[0].width = parent[0].offsetWidth;
canvas[0].height = document.body.clientHeight;
let gameActive = true;
let first = true;
let correct = false;
let custId = getRandomInt(1000000000000000000).toString();
let backgroundColor = "rgb(" + [getRandomInt(255),getRandomInt(255),getRandomInt(255)].join() + ")";
let r = getRandomInt(255);
let g = getRandomInt(255);
let b = getRandomInt(255);
let populatelb = true;
let score = 0;
let timeleft = 15;
let exes  = [];
let textColor = "rgb(" + [r,g,b].join() + ")";
let shadowColor = "rgb(" + [r*(0.8),g*(0.8),b*(0.8)].join() + ")";
let rects = [];
let left = "";
const context = document.querySelector("canvas").getContext("2d");
context.width = document.body.clientWidth;
context.height = document.body.clientHeight;
if(context.width > context.height){
var basis = context.height;
} else {
var basis = context.width;
}
let midx = context.width/2-(basis/8);
let midy = context.height/2-(context.height/8)-50;
let targets = []
let tmp = getRandomInt(4);
for(var i = 0; i < 4; i++){
if(tmp == i){
targets[i] = true;
} else{
targets[i] = false;
}
}
rects[0] = new rectButton((midx-(basis/6)), (midy-(basis/6)), basis/4, basis/4, r, g, b, targets[0]);
rects[1] = new rectButton((midx+(basis/6)), (midy-(basis/6)), basis/4, basis/4, r, g, b, targets[1]);
rects[2] = new rectButton((midx+(basis/6)), (midy+(basis/6)), basis/4, basis/4, r, g, b, targets[2]);
rects[3] = new rectButton((midx-(basis/6)), (midy+(basis/6)), basis/4, basis/4, r, g, b, targets[3]);
//timer size and location
var head = document.getElementById("header");
let toptmp = (((head.offsetHeight + parent[0].offsetHeight)/2)) + "px";
left = "50vw";

//Main game loop logic
const loop = function () {
// Creates the backdrop for each frame
context.fillStyle = backgroundColor;
context.fillRect(0, 0, context.width, context.height); // x, y, width, height
for (var i = 0; i < rects.length; i++){
context.beginPath();
if ((rects[i].target == true) && (first == true)){
rects[i].setChosen(0.8);
first = false;
}
context.closePath();
context.fillStyle = rects[i].fillColor;
context.strokeStyle = rects[i].strokeColor;
context.lineWidth = 3;
context.rect(rects[i].padx, rects[i].pady, rects[i].width, rects[i].height);
context.fill();
context.stroke();
}
window.requestAnimationFrame(loop);
};
initTimer(toptmp, left);
timer()
// Start animation loop
window.requestAnimationFrame(loop);
@import url('https://fonts.googleapis.com/css?family=Montserrat:900i&display=swap');
h1 {
text-align: center;
}
h2 {
text-align: center;
font-family: 'Montserrat', sans-serif;
font-size: 5vw;
letter-spacing:0.1em;
-webkit-text-fill-color: transparent;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: white;
color: white;
text-shadow:
1px 1px #4EB1D9,
2px 2px #000000;
}
footer {
position: static;
right: 0;
bottom: 0;
left: 0;
padding: 1rem;
background-color: transparent;
text-align: center;
height: 2.5rem;
/*position: absolute;
bottom: 0;
width: 100%;
height: 2.5rem;   */         /* Footer height */
}
p {
text-align: center;
}
body {
height: 100%;
block-size: 100%;
min-height:100vh;
font-family: 'Montserrat', sans-serif;
}
img {
float: center;
width: 30vw;
height: 25vw;
object-fit: scale-down;
}
button {
float: center;
color: black;
text-align: center;
padding: 4px;
text-decoration: none;
font-size: 16px;
line-height: 25px;
border-radius: 4px;
}
button:hover {
background-color: #ddd;
color: black;
}
/* Style the active/current link*/
button.active {
background-color: dodgerblue;
}
#gameCont{
display: flex;
float: center;
align-items: center;
flex-direction: column;
justify-content: center;
block-size: 100%;
width: 100%;
height: 100%;
}
.game{
margin-right: auto;
margin-left: auto;
display: block;
float: center;
block-size: 100%;
align-items: center;
flex-direction: column;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
outline: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
.center {
width: 50%;
}
.header {
overflow: hidden;
background-color: #f1f1f1;
padding: 20px 10px;
}
.header a {
float: left;
color: black;
text-align: center;
color: #ff1f8f;
padding: 12px;
text-decoration: none;
font-size: 45px;
line-height: 25px;
border-radius: 4px;
letter-spacing:0.1em;
-webkit-text-fill-color: transparent;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: white;
color: white;
text-shadow:
2px 2px #4EB1D9,
4px 4px #000000;
}
.header button {
float: left;
color: black;
text-align: center;
padding: 12px;
text-decoration: none;
font-size: 18px;
line-height: 25px;
border-radius: 4px;
}
/* Style the logo link (notice that we set the same value of line-height and font-size to prevent the header to increase when the font gets bigger */
.header v.logo {
font-size: 25px;
font-weight: bold;
}
/* Change the background color on mouse-over */
.header button:hover {
background-color: #ddd;
color: black;
}
/* Style the active/current link*/
.header button.active {
background-color: dodgerblue;
color: white;
}
/* Float the link section to the right */
.header-right {
float: right;
}
/* The Modal (background) */
.modal {
display: block; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #f1f1f1;
margin: 10% auto; /* 10% from the top and centered */
padding: 20px;
border: 2px solid #888;
width: 75%; /* Could be more or less, depending on screen size */
text-align: center;
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
/*LeaderBoard Table Defs */
.tableFixHeadLB {
overflow-y: auto;
height: 60vh;
}
.tableFixHeadLB thead th {
position: sticky;
top: 0;
}
/*Table Defs */
.tableFixHead {
overflow-y: auto;
height: 30vh;
}
.tableFixHead thead th {
position: sticky;
top: 0;
}
table {
border-collapse: collapse;
table-layout: fixed ;
width: 100%;
}
th,
td {
padding: 1vh 1vh;
align-items: center;
}
th {
background: #eee;
}
.tableFixHead,
.tableFixHead td {
box-shadow: inset 1px -1px #000;
}
.tableFixHead th {
box-shadow: inset 1px 1px #000, 0 1px #000;
}
.tableFixHeadLB,
.tableFixHeadLB td {
box-shadow: inset 1px -1px #000;
}
.tableFixHeadLB th {
box-shadow: inset 1px 1px #000, 0 1px #000;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Next</title>
<link rel="stylesheet" href="style.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet"/>
<link rel="stylesheet"/>

</head>
<body>
<div class="header" id="header">
<a href="#default" class="logo">Next</a>
<div class="header-right">
</div>
</div>
<h1 id="h1"></h1>
<div class="gameCont">
<h1 id="timer"></h1>
<canvas class="game"></canvas>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous">
</script>
<script src="script.js" type="module"></script>
</body>
</html>

实际上,您的问题是由一些拼写错误引起的。我会把它们作为答案发布,因为评论很简短,可以引导你通过它。如果这为你解决了问题,请考虑自愿删除这个问题,因为所说的问题完全是由拼写错误引起的。

  1. 在CSS第75行中,您使用#gameCont作为selctor。但是,不存在具有此ID的元素。在HTM1的第20行中有一个元素<div class="gameCont">。您需要将selctor修复为.gameCont

  2. 您尝试将计时器定位为绝对值,但position: relative没有父级,因此下一个相对父级将是<body>元素。您必须在CSS中添加:.gameCont { position: relative; }

  3. 在JS第26行和第27行中,您使用了element.style.top = top;element.style.left = left;,它们要么是不正确的值,要么是您从未声明的可变值。您必须将bot值更改为"50%"

  4. 然后在JS第28行中,您声明element.style.transform = "translate(-50%, 0);" which has to betranslate(-50%,-50%)`。

function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
async function timer(){
timeleft = 15;
var downloadTimer = setInterval(function(){
if(timeleft <= 0){
clearInterval(downloadTimer);
document.getElementById("timer").innerHTML = "0";
gameOverText.innerHTML = "Your Score: " + score;
gameOverModal.style.display = "block";
DoExampleLoginWithCustomID()
console.log(score);
} else {
document.getElementById("timer").innerHTML = timeleft;
}
timeleft -= 1;
}, 1000);
}
function initTimer(top, left){
var timer = document.getElementById("timer");
timer.innerHTML = "15";
timer.style.textAlign = "center";
timer.style.position = "absolute";
timer.style.top = "50%";
timer.style.left = "50%";
timer.style.transform = "translate(-50%, -50%)";
timer.style.fontSize = "4vw";
timer.style.letterSpacing = "0.1em";
timer.style.webkitTextStrokeWidth = "0px";
timer.style.webkitTextFillColor = "transparent";
//timer.style.webkitTextStrokeColor = "white";
timer.style.textShadow = "2px 2px " + textColor + ", 4px 4px " + shadowColor + "";
}
class rectButton {
constructor(padx, pady, height, width, r, g, b, target) {
this.padx = padx;
this.pady = pady;
this.height = height;
this.width = width;
this.r = r;
this.g = g;
this.b = b;
this.fillColor = "rgb(" + [r,g,b].join() + ")";
this.strokeColor = "rgb(" + [r*(0.5),g*(0.5),b*(0.5)].join() + ")";
this.target = target;
}
setChosen(percent){
if (first = true){
this.r = Math.floor(parseFloat(this.r) * parseFloat(percent));
this.g = Math.floor(parseFloat(this.g) * parseFloat(percent));
this.b = Math.floor(parseFloat(this.b) * parseFloat(percent));
this.fillColor = "rgb(" + [this.r,this.g,this.b].join() + ")";
}
}
}
//Initialize Canvas
var canvas = document.getElementsByClassName("game");
var parent = document.getElementsByClassName("gameCont");
canvas[0].width = parent[0].offsetWidth;
canvas[0].height = document.body.clientHeight;
let gameActive = true;
let first = true;
let correct = false;
let custId = getRandomInt(1000000000000000000).toString();
let backgroundColor = "rgb(" + [getRandomInt(255),getRandomInt(255),getRandomInt(255)].join() + ")";
let r = getRandomInt(255);
let g = getRandomInt(255);
let b = getRandomInt(255);
let populatelb = true;
let score = 0;
let timeleft = 15;
let exes  = [];
let textColor = "rgb(" + [r,g,b].join() + ")";
let shadowColor = "rgb(" + [r*(0.8),g*(0.8),b*(0.8)].join() + ")";
let rects = [];
let left = "";
const context = document.querySelector("canvas").getContext("2d");
context.width = document.body.clientWidth;
context.height = document.body.clientHeight;
if(context.width > context.height){
var basis = context.height;
} else {
var basis = context.width;
}
let midx = context.width/2-(basis/8);
let midy = context.height/2-(context.height/8)-50;
let targets = []
let tmp = getRandomInt(4);
for(var i = 0; i < 4; i++){
if(tmp == i){
targets[i] = true;
} else{
targets[i] = false;
}
}
rects[0] = new rectButton((midx-(basis/6)), (midy-(basis/6)), basis/4, basis/4, r, g, b, targets[0]);
rects[1] = new rectButton((midx+(basis/6)), (midy-(basis/6)), basis/4, basis/4, r, g, b, targets[1]);
rects[2] = new rectButton((midx+(basis/6)), (midy+(basis/6)), basis/4, basis/4, r, g, b, targets[2]);
rects[3] = new rectButton((midx-(basis/6)), (midy+(basis/6)), basis/4, basis/4, r, g, b, targets[3]);
//timer size and location
var head = document.getElementById("header");
let toptmp = (((head.offsetHeight + parent[0].offsetHeight)/2)) + "px";
left = "50vw";

//Main game loop logic
const loop = function () {
// Creates the backdrop for each frame
context.fillStyle = backgroundColor;
context.fillRect(0, 0, context.width, context.height); // x, y, width, height
for (var i = 0; i < rects.length; i++){
context.beginPath();
if ((rects[i].target == true) && (first == true)){
rects[i].setChosen(0.8);
first = false;
}
context.closePath();
context.fillStyle = rects[i].fillColor;
context.strokeStyle = rects[i].strokeColor;
context.lineWidth = 3;
context.rect(rects[i].padx, rects[i].pady, rects[i].width, rects[i].height);
context.fill();
context.stroke();
}
window.requestAnimationFrame(loop);
};
initTimer(toptmp, left);
timer()
// Start animation loop
window.requestAnimationFrame(loop);
@import url('https://fonts.googleapis.com/css?family=Montserrat:900i&display=swap');
h1 {
text-align: center;
}
h2 {
text-align: center;
font-family: 'Montserrat', sans-serif;
font-size: 5vw;
letter-spacing:0.1em;
-webkit-text-fill-color: transparent;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: white;
color: white;
text-shadow:
1px 1px #4EB1D9,
2px 2px #000000;
}
footer {
position: static;
right: 0;
bottom: 0;
left: 0;
padding: 1rem;
background-color: transparent;
text-align: center;
height: 2.5rem;
/*position: absolute;
bottom: 0;
width: 100%;
height: 2.5rem;   */         /* Footer height */
}
p {
text-align: center;
}
body {
height: 100%;
block-size: 100%;
min-height:100vh;
font-family: 'Montserrat', sans-serif;
}
img {
float: center;
width: 30vw;
height: 25vw;
object-fit: scale-down;
}
button {
float: center;
color: black;
text-align: center;
padding: 4px;
text-decoration: none;
font-size: 16px;
line-height: 25px;
border-radius: 4px;
}
button:hover {
background-color: #ddd;
color: black;
}
/* Style the active/current link*/
button.active {
background-color: dodgerblue;
}
.gameCont{
display: flex;
float: center;
align-items: center;
flex-direction: column;
justify-content: center;
block-size: 100%;
width: 100%;
height: 100%;
position: relative;
}
.game{
margin-right: auto;
margin-left: auto;
display: block;
float: center;
block-size: 100%;
align-items: center;
flex-direction: column;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
outline: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
.center {
width: 50%;
}
.header {
overflow: hidden;
background-color: #f1f1f1;
padding: 20px 10px;
}
.header a {
float: left;
color: black;
text-align: center;
color: #ff1f8f;
padding: 12px;
text-decoration: none;
font-size: 45px;
line-height: 25px;
border-radius: 4px;
letter-spacing:0.1em;
-webkit-text-fill-color: transparent;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: white;
color: white;
text-shadow:
2px 2px #4EB1D9,
4px 4px #000000;
}
.header button {
float: left;
color: black;
text-align: center;
padding: 12px;
text-decoration: none;
font-size: 18px;
line-height: 25px;
border-radius: 4px;
}
/* Style the logo link (notice that we set the same value of line-height and font-size to prevent the header to increase when the font gets bigger */
.header v.logo {
font-size: 25px;
font-weight: bold;
}
/* Change the background color on mouse-over */
.header button:hover {
background-color: #ddd;
color: black;
}
/* Style the active/current link*/
.header button.active {
background-color: dodgerblue;
color: white;
}
/* Float the link section to the right */
.header-right {
float: right;
}
/* The Modal (background) */
.modal {
display: block; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #f1f1f1;
margin: 10% auto; /* 10% from the top and centered */
padding: 20px;
border: 2px solid #888;
width: 75%; /* Could be more or less, depending on screen size */
text-align: center;
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
/*LeaderBoard Table Defs */
.tableFixHeadLB {
overflow-y: auto;
height: 60vh;
}
.tableFixHeadLB thead th {
position: sticky;
top: 0;
}
/*Table Defs */
.tableFixHead {
overflow-y: auto;
height: 30vh;
}
.tableFixHead thead th {
position: sticky;
top: 0;
}
table {
border-collapse: collapse;
table-layout: fixed ;
width: 100%;
}
th,
td {
padding: 1vh 1vh;
align-items: center;
}
th {
background: #eee;
}
.tableFixHead,
.tableFixHead td {
box-shadow: inset 1px -1px #000;
}
.tableFixHead th {
box-shadow: inset 1px 1px #000, 0 1px #000;
}
.tableFixHeadLB,
.tableFixHeadLB td {
box-shadow: inset 1px -1px #000;
}
.tableFixHeadLB th {
box-shadow: inset 1px 1px #000, 0 1px #000;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Next</title>
<link rel="stylesheet" href="style.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet"/>
<link rel="stylesheet"/>

</head>
<body>
<div class="header" id="header">
<a href="#default" class="logo">Next</a>
<div class="header-right">
</div>
</div>
<h1 id="h1"></h1>
<div class="gameCont">
<h1 id="timer"></h1>
<canvas class="game"></canvas>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous">
</script>
<script src="script.js" type="module"></script>
</body>
</html>

相关内容

最新更新