JavaScript:是否可以在没有 "stretching" 坐标系的情况下创建多个画布(变化 size/using 绝对坐标)?
JavaScript: Is it possible to create multiple canvases (varying size/using absolute coordinates) without "stretching" the coordinate system?
目前,我正尝试使用在多个 canvas 上绘制的矩形遮挡除特定元素以外的所有屏幕。除了非阴影元素外,我想阻止对 window 的点击。为此,我尝试创建四个 canvases,每个占据屏幕的不同部分,使所需元素畅通无阻。为了获得元素的大小,我使用 getBoundingClientRect() 并将我的阴影矩形基于此和 scrollwidth/height。第一个 canvas+rectangle 绘制完美,之后尽管设置了 position: absolute,但其余的不会绘制到我想要的位置(它们出现在页面底部)。我想知道这是否与我设置每个 canvas.
的高度和宽度时坐标系被拉伸有关
这是我尝试使用 JavaScript 创建四个 canvases。我传递了一个从 getBoundingClientRect() 生成的对象,该对象具有属性 top、left、right、bottom、height、width,每个属性对应于要保持无阴影的元素。以下代码来自文件 focusClick.js
function shadowOutScreen(boundingRect){
var pageWidth = document.body.scrollWidth;
var pageHeight = document.body.scrollHeight;
//create four quadrants to cover all of screen except spotlight
//quadrant1: top strip
var dynamicQuadrant1 = document.createElement("canvas");
var body = document.getElementById("body");
body.appendChild(dynamicQuadrant1);
dynamicQuadrant1.setAttribute("width",pageWidth);
dynamicQuadrant1.setAttribute("height",boundingRect.top);
dynamicQuadrant1.style.pointerEvents = "auto";
dynamicQuadrant1.style.zIndex = "1";
dynamicQuadrant1.style.position = "absolute";
dynamicQuadrant1.style.left = 0;
dynamicQuadrant1.style.top = 0;
dynamicQuadrant1.style.pointerEvents = "auto";
var context = dynamicQuadrant1.getContext("2d");
context.fillStyle = "rgba(38,38,38,.8)";
context.fillRect(0,0,dynamicQuadrant1.width,dynamicQuadrant1.height);
//quadrant2: bottom strip
var dynamicQuadrant2 = document.createElement("canvas");
body.appendChild(dynamicQuadrant2);
dynamicQuadrant2.setAttribute("width",pageWidth);
dynamicQuadrant2.setAttribute("height",(pageHeight-boundingRect.bottom));
dynamicQuadrant2.style.pointerEvents = "auto";
dynamicQuadrant2.style.zIndex = "2";
dynamicQuadrant2.style.position = "absolute";
dynamicQuadrant2.style.left = 0;
dynamicQuadrant2.style.top = boundingRect.bottom;
dynamicQuadrant2.style.pointerEvents = "auto";
var context2 = dynamicQuadrant2.getContext("2d");
context2.fillStyle = "rgba(38,38,38,.8)";
context2.fillRect(0,0,dynamicQuadrant2.width,dynamicQuadrant2.height);
//quadrant3: left side strip
var dynamicQuadrant3 = document.createElement("canvas");
body.appendChild(dynamicQuadrant3);
dynamicQuadrant3.setAttribute("width",boundingRect.left);
dynamicQuadrant3.setAttribute("height",boundingRect.height);
dynamicQuadrant3.style.pointerEvents = "auto";
dynamicQuadrant3.style.position = "absolute";
dynamicQuadrant3.style.left = 0;
dynamicQuadrant3.style.top = boundingRect.top;
dynamicQuadrant3.style.pointerEvents = "auto";
var context3 = dynamicQuadrant3.getContext("2d");
context3.fillStyle = "rgba(38,38,38,.8)";
context3.fillRect(0,0,dynamicQuadrant3.width,dynamicQuadrant3.height);
//quadrant4: right side strip
var dynamicQuadrant4 = document.createElement("canvas");
body.appendChild(dynamicQuadrant4);
dynamicQuadrant4.setAttribute("width",pageWidth-boundingRect.right+9);
dynamicQuadrant4.setAttribute("height",boundingRect.height);
dynamicQuadrant4.style.pointerEvents = "auto";
dynamicQuadrant4.style.position = "absolute";
dynamicQuadrant4.style.left = boundingRect.right;
dynamicQuadrant4.style.top = boundingRect.top;
dynamicQuadrant4.style.pointerEvents = "auto";
var context4 = dynamicQuadrant4.getContext("2d");
context4.fillStyle = "rgba(38,38,38,.8)";
context4.fillRect(0,0,dynamicQuadrant4.width,dynamicQuadrant4.height);
}
一些基本的HTML,这个可以运行上。包含在文件 focusClick.html
中
<!DOCTYPE html>
<!-- HTML designed to create page to practice scrolling with -->
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8" />
<link rel="stylesheet" href=pageStyle2.css>
</head>
<body id="body">
<style>="position:absolute" </style>
<!-- <canvas id="canvas"></canvas> -->
<!-- <canvas id="canvas2"></canvas> -->
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for page class -->
<!-- ************************************* -->
<div class="page">
<header>
<h1>Page Navigation Demo: Jump to ID</h1>
</header>
<nav>
<ul>
<li><a href="javascript:spotlightLondon();">London</a></li>
<li><a href="javascript:spotlightParis();">Paris</a></li>
<li><a href="javascript:spotlightTokyo();">Tokyo</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article>
<h1>Three Cities</h1>
<p>This page is a demonstration of how a guided page tour could be integrated into a Opti Pod Format.</p>
<p>This is just a proof of concept and does not represent pod compatability. This is the simple scrolling version, future versions will integrated selective highlightening and designated ghosting protocols.</p>
</article>
<footer></footer>
</div>
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for containerLond class -->
<!-- ************************************* -->
<div class="containerLond" id="London">
<nav>
<ul>
<li><a href="javascript:goToParis();">Paris</a></li>
<li><a href="javascript:goToTokyo();">Tokyo</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article id="LondonArticle">
<h1>London</h1>
<p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
<p>Standing on the River Thames, London has been a major settlement for two millennia, its history going back to its founding by the Romans, who named it Londinium.</p>
</article>
<footer></footer>
</div>
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for containerParis class -->
<!-- ************************************* -->
<div class="containerParis" id="Paris">
<nav>
<ul>
<li><a href="javascript:goToLondon();">London</a></li>
<li><a href="javascript:goToTokyo();">Tokyo</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article>
<h1>Paris</h1>
<p>Paris is the capital city of France. It is a historic center of art and inovation in Europe with 2.24 million inhabitants.</p>
<p>Paris is located in the north-bending arc of the river Seine. Paris was founded around the end of the 3rd century BC by the Gauls who were called Parisii. In 52 BC Julius Caesar's legions conquered the territory, founding the Roman city, Lutetia on the earlier settlement. </p>
</article>
<footer></footer>
</div>
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for containerTokyo class -->
<!-- ************************************* -->
<div class="containerTokyo" id="Tokyo">
<nav>
<ul>
<li><a href="javascript:goToLondon();">London</a></li>
<li><a href="javascript:goToParis();">Paris</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article>
<h1>Tokyo</h1>
<p>Tokyo is the capital city of Japan. It is the largest city on the island and has a population of 9.273 million.</p>
<p>. History tells that on February 11th 660 BC the first emperor of Japan (Jinmu) founded the nation. </p>
</article>
<footer></footer>
</div>
<!-- Item To Be added to bottom -->
<img src="Three_horizontal_stripes.svg.png" alt="Stripes" width=100%>
<div class="bottomOfPage" id="bottom">
<nav>
<ul>
<li><a href="javascript:goToLondon();">London</a></li>
<li><a href="javascript:goToParis();">Paris</a></li>
<li><a href="javascript:goToTokyo();">Tokyo</a></li>
</ul>
</nav>
<article>
<h1>Welcome To Rock Bottom</h1>
<p>Rock bottom is located just south of bikini bottom, home to some odd language variants that are nearly impossible for outsiders to understand.</p>
</article>
</div>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="focusClick.js"></script>
</body>
</html>
和一些附带的 css 将放入 styleSheet2.css 文件
/*Just added the body padding-bottom so scrolling is possible*/
body {
padding-bottom: 2px;
background-color: gray;
}
/*************************
page Section of Style Code
**************************/
.page {
width: 100%;
border: 1px solid slategray;
background-color: gray;
}
header, footer {
padding: 1em;
color: white;
background-color: black;
clear: left;
text-align: center;
}
nav {
float: left;
max-width: 160px;
margin: 0;
padding: 1eml
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul a {
text-decoration: none;
}
.page > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
/****************************
London Section of Style Code
***************************/
.containerLond {
width: 100%;
border: 1px solid slategray;
background-color: #7FBF3F;
}
.containerLond > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
/***************************
Paris Section of Style Code
***************************/
.containerParis {
width: 100%;
border: 1px solid slategray;
background-color: #3F7FBF;
}
.containerParis > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
/*Tokyo Section of Style Code*/
.containerTokyo {
width: 100%;
border: 1px solid slategray;
background-color: #BF3F3F;
}
.containerTokyo > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
.bottomOfPage {
width: 100%;
border: 1px solid slategray;
background-color: #444444;
}
.bottomOfPage > article {
margin-left: 200px;
border-left: 1px solid black;
color: black;
padding: 1em;
overflow: hidden;
}
.expose {
position:relative;
}
#overlay {
background:rgba(0,0,0,0.5);
display:none;
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
z-index:99998;
}
CSS 样式属性需要单位。由于 getBoundingClientRect
位置属性是数字(像素),因此在设置样式属性时需要向它们附加 "px"。
例如(只是其中之一),改变
dynamicQuadrant2.style.top = boundingRect.bottom;
到
dynamicQuadrant2.style.top = boundingRect.bottom; + "px";
定位文章底部底部阴影元素的顶部。
(顶部象限着色器起作用是因为,至少有效地,零值不需要单位)。
解决阴影元素位置问题后,考虑在 Codereview 上发帖,以获得有关改进工作代码的方法的进一步反馈。例如,使用 canvas
元素而不是 div
元素是有问题的(如评论中所述)。
为避免将来投反对票,请查看此 help center article on How to create a Minimal, Complete, and Verifiable example, and this introductory article,其中介绍了如何在帖子中添加可以 运行 的代码片段。尝试 运行 上面在编辑器中提供的问题代码会发现缺少 spotlightLondon
的代码。
目前,我正尝试使用在多个 canvas 上绘制的矩形遮挡除特定元素以外的所有屏幕。除了非阴影元素外,我想阻止对 window 的点击。为此,我尝试创建四个 canvases,每个占据屏幕的不同部分,使所需元素畅通无阻。为了获得元素的大小,我使用 getBoundingClientRect() 并将我的阴影矩形基于此和 scrollwidth/height。第一个 canvas+rectangle 绘制完美,之后尽管设置了 position: absolute,但其余的不会绘制到我想要的位置(它们出现在页面底部)。我想知道这是否与我设置每个 canvas.
的高度和宽度时坐标系被拉伸有关function shadowOutScreen(boundingRect){
var pageWidth = document.body.scrollWidth;
var pageHeight = document.body.scrollHeight;
//create four quadrants to cover all of screen except spotlight
//quadrant1: top strip
var dynamicQuadrant1 = document.createElement("canvas");
var body = document.getElementById("body");
body.appendChild(dynamicQuadrant1);
dynamicQuadrant1.setAttribute("width",pageWidth);
dynamicQuadrant1.setAttribute("height",boundingRect.top);
dynamicQuadrant1.style.pointerEvents = "auto";
dynamicQuadrant1.style.zIndex = "1";
dynamicQuadrant1.style.position = "absolute";
dynamicQuadrant1.style.left = 0;
dynamicQuadrant1.style.top = 0;
dynamicQuadrant1.style.pointerEvents = "auto";
var context = dynamicQuadrant1.getContext("2d");
context.fillStyle = "rgba(38,38,38,.8)";
context.fillRect(0,0,dynamicQuadrant1.width,dynamicQuadrant1.height);
//quadrant2: bottom strip
var dynamicQuadrant2 = document.createElement("canvas");
body.appendChild(dynamicQuadrant2);
dynamicQuadrant2.setAttribute("width",pageWidth);
dynamicQuadrant2.setAttribute("height",(pageHeight-boundingRect.bottom));
dynamicQuadrant2.style.pointerEvents = "auto";
dynamicQuadrant2.style.zIndex = "2";
dynamicQuadrant2.style.position = "absolute";
dynamicQuadrant2.style.left = 0;
dynamicQuadrant2.style.top = boundingRect.bottom;
dynamicQuadrant2.style.pointerEvents = "auto";
var context2 = dynamicQuadrant2.getContext("2d");
context2.fillStyle = "rgba(38,38,38,.8)";
context2.fillRect(0,0,dynamicQuadrant2.width,dynamicQuadrant2.height);
//quadrant3: left side strip
var dynamicQuadrant3 = document.createElement("canvas");
body.appendChild(dynamicQuadrant3);
dynamicQuadrant3.setAttribute("width",boundingRect.left);
dynamicQuadrant3.setAttribute("height",boundingRect.height);
dynamicQuadrant3.style.pointerEvents = "auto";
dynamicQuadrant3.style.position = "absolute";
dynamicQuadrant3.style.left = 0;
dynamicQuadrant3.style.top = boundingRect.top;
dynamicQuadrant3.style.pointerEvents = "auto";
var context3 = dynamicQuadrant3.getContext("2d");
context3.fillStyle = "rgba(38,38,38,.8)";
context3.fillRect(0,0,dynamicQuadrant3.width,dynamicQuadrant3.height);
//quadrant4: right side strip
var dynamicQuadrant4 = document.createElement("canvas");
body.appendChild(dynamicQuadrant4);
dynamicQuadrant4.setAttribute("width",pageWidth-boundingRect.right+9);
dynamicQuadrant4.setAttribute("height",boundingRect.height);
dynamicQuadrant4.style.pointerEvents = "auto";
dynamicQuadrant4.style.position = "absolute";
dynamicQuadrant4.style.left = boundingRect.right;
dynamicQuadrant4.style.top = boundingRect.top;
dynamicQuadrant4.style.pointerEvents = "auto";
var context4 = dynamicQuadrant4.getContext("2d");
context4.fillStyle = "rgba(38,38,38,.8)";
context4.fillRect(0,0,dynamicQuadrant4.width,dynamicQuadrant4.height);
}
一些基本的HTML,这个可以运行上。包含在文件 focusClick.html
中<!DOCTYPE html>
<!-- HTML designed to create page to practice scrolling with -->
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8" />
<link rel="stylesheet" href=pageStyle2.css>
</head>
<body id="body">
<style>="position:absolute" </style>
<!-- <canvas id="canvas"></canvas> -->
<!-- <canvas id="canvas2"></canvas> -->
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for page class -->
<!-- ************************************* -->
<div class="page">
<header>
<h1>Page Navigation Demo: Jump to ID</h1>
</header>
<nav>
<ul>
<li><a href="javascript:spotlightLondon();">London</a></li>
<li><a href="javascript:spotlightParis();">Paris</a></li>
<li><a href="javascript:spotlightTokyo();">Tokyo</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article>
<h1>Three Cities</h1>
<p>This page is a demonstration of how a guided page tour could be integrated into a Opti Pod Format.</p>
<p>This is just a proof of concept and does not represent pod compatability. This is the simple scrolling version, future versions will integrated selective highlightening and designated ghosting protocols.</p>
</article>
<footer></footer>
</div>
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for containerLond class -->
<!-- ************************************* -->
<div class="containerLond" id="London">
<nav>
<ul>
<li><a href="javascript:goToParis();">Paris</a></li>
<li><a href="javascript:goToTokyo();">Tokyo</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article id="LondonArticle">
<h1>London</h1>
<p>London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
<p>Standing on the River Thames, London has been a major settlement for two millennia, its history going back to its founding by the Romans, who named it Londinium.</p>
</article>
<footer></footer>
</div>
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for containerParis class -->
<!-- ************************************* -->
<div class="containerParis" id="Paris">
<nav>
<ul>
<li><a href="javascript:goToLondon();">London</a></li>
<li><a href="javascript:goToTokyo();">Tokyo</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article>
<h1>Paris</h1>
<p>Paris is the capital city of France. It is a historic center of art and inovation in Europe with 2.24 million inhabitants.</p>
<p>Paris is located in the north-bending arc of the river Seine. Paris was founded around the end of the 3rd century BC by the Gauls who were called Parisii. In 52 BC Julius Caesar's legions conquered the territory, founding the Roman city, Lutetia on the earlier settlement. </p>
</article>
<footer></footer>
</div>
<!-- ************************************* -->
<!-- ************************************* -->
<!-- Div for containerTokyo class -->
<!-- ************************************* -->
<div class="containerTokyo" id="Tokyo">
<nav>
<ul>
<li><a href="javascript:goToLondon();">London</a></li>
<li><a href="javascript:goToParis();">Paris</a></li>
<li><a href="javascript:goToBottom();">Rock Bottom</a></li>
</ul>
</nav>
<article>
<h1>Tokyo</h1>
<p>Tokyo is the capital city of Japan. It is the largest city on the island and has a population of 9.273 million.</p>
<p>. History tells that on February 11th 660 BC the first emperor of Japan (Jinmu) founded the nation. </p>
</article>
<footer></footer>
</div>
<!-- Item To Be added to bottom -->
<img src="Three_horizontal_stripes.svg.png" alt="Stripes" width=100%>
<div class="bottomOfPage" id="bottom">
<nav>
<ul>
<li><a href="javascript:goToLondon();">London</a></li>
<li><a href="javascript:goToParis();">Paris</a></li>
<li><a href="javascript:goToTokyo();">Tokyo</a></li>
</ul>
</nav>
<article>
<h1>Welcome To Rock Bottom</h1>
<p>Rock bottom is located just south of bikini bottom, home to some odd language variants that are nearly impossible for outsiders to understand.</p>
</article>
</div>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="focusClick.js"></script>
</body>
</html>
和一些附带的 css 将放入 styleSheet2.css 文件
/*Just added the body padding-bottom so scrolling is possible*/
body {
padding-bottom: 2px;
background-color: gray;
}
/*************************
page Section of Style Code
**************************/
.page {
width: 100%;
border: 1px solid slategray;
background-color: gray;
}
header, footer {
padding: 1em;
color: white;
background-color: black;
clear: left;
text-align: center;
}
nav {
float: left;
max-width: 160px;
margin: 0;
padding: 1eml
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul a {
text-decoration: none;
}
.page > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
/****************************
London Section of Style Code
***************************/
.containerLond {
width: 100%;
border: 1px solid slategray;
background-color: #7FBF3F;
}
.containerLond > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
/***************************
Paris Section of Style Code
***************************/
.containerParis {
width: 100%;
border: 1px solid slategray;
background-color: #3F7FBF;
}
.containerParis > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
/*Tokyo Section of Style Code*/
.containerTokyo {
width: 100%;
border: 1px solid slategray;
background-color: #BF3F3F;
}
.containerTokyo > article {
margin-left: 200px;
border-left: 1px solid black;
padding: 1em;
overflow: hidden;
}
.bottomOfPage {
width: 100%;
border: 1px solid slategray;
background-color: #444444;
}
.bottomOfPage > article {
margin-left: 200px;
border-left: 1px solid black;
color: black;
padding: 1em;
overflow: hidden;
}
.expose {
position:relative;
}
#overlay {
background:rgba(0,0,0,0.5);
display:none;
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
z-index:99998;
}
CSS 样式属性需要单位。由于 getBoundingClientRect
位置属性是数字(像素),因此在设置样式属性时需要向它们附加 "px"。
例如(只是其中之一),改变
dynamicQuadrant2.style.top = boundingRect.bottom;
到
dynamicQuadrant2.style.top = boundingRect.bottom; + "px";
定位文章底部底部阴影元素的顶部。
(顶部象限着色器起作用是因为,至少有效地,零值不需要单位)。
解决阴影元素位置问题后,考虑在 Codereview 上发帖,以获得有关改进工作代码的方法的进一步反馈。例如,使用
canvas
元素而不是 div
元素是有问题的(如评论中所述)。
为避免将来投反对票,请查看此 help center article on How to create a Minimal, Complete, and Verifiable example, and this introductory article,其中介绍了如何在帖子中添加可以 运行 的代码片段。尝试 运行 上面在编辑器中提供的问题代码会发现缺少 spotlightLondon
的代码。