当元素的所有像素都是透明时触发事件
Trigger event when ALL of an element's pixels are transparent
我有一个网页,其中有两个 canvas 元素堆叠在一起。这是某些功能的基础,让我可以“擦除”顶部 canvas 以显示加载到底部 canvas 的图像。该功能运行良好。
我现在要做的是在顶部 canvas 被完全“擦除”后触发一个事件,即顶部上下文的所有像素都是透明的。我在 SO 上找到了通过 getImageData 检查特定像素的 alpha 值的方法,但我正在尝试找出一种方法来确定最后一个像素的 alpha 值何时 = 0。
我已经包含了我的代码以及使用 for 和 if 循环执行此操作的未完成尝试(但这似乎不是最佳方法)。我发现的另一个问题是,当我使用 getImageData 时,我的 canvas.
的两个边缘周围出现了一个灰色细边框。
提前感谢您的帮助!
window.onload = function() {
//Move speaker image across page
var speaker = document.getElementById('speaker');
speaker.onload = MoveElement(speaker, "right", 1000);
//Create canvases & contexts
var canvas = document.getElementById('canvas');
var ctxB = canvas.getContext('2d');
var canvas2 = document.getElementById('canvas2');
var ctxT = canvas2.getContext('2d');
//Get waterfall image object
var waterfall = document.getElementById('waterfall');
//Set canvas w&h properties
canvas.width = canvas2.width = .3*waterfall.width;
canvas.height = canvas2.height = .3*waterfall.height;
//Populate Bottom canvas with waterfall image
ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height);
//Populate Top canvas with white rectangle
ctxT.fillStyle = "white";
ctxT.fillRect(0, 0, canvas2.width, canvas2.height);
//Make Top canvas "erasable"
canvas2.addEventListener('mousemove', event => {
var x = event.offsetX;
var y = event.offsetY;
const eraseSize = 125;
ctxT.clearRect(x-eraseSize/2, y-eraseSize/2, eraseSize, eraseSize);
})
//Attempt to trigger an event when all pixels of top canvas have alpha = 0
var imageDataTop = ctxT.getImageData(0, 0, canvas2.width, canvas2.height);
console.log(imageDataTop);
for (var i = 0; i < imageDataTop; i++) {
if (imageDataTop.data[i] = 0) {
//
}
}
}
function PlayAudio() {
document.getElementById('boyfriend').play();
}
//Move an element in a given direction a certain distance
function MoveElement(element, direction, totalDistance) {
//Determine horizontal or vertical direction
var LeftOrTop = (direction=="left" || direction=="right") ? "left" : "top";
//Set default frame distance
var frameDistance = 150;
//Adjust for backwards direction
if (direction=="left" || direction=="up") {
totalDistance *= -1;
frameDistance = -1;
}
//Get style data object for element
var elementStyle = window.getComputedStyle(element);
//Get Left or Top position of element
var positionValue = elementStyle.getPropertyValue(LeftOrTop).replace("px", "");
//Apply direction and distance change to element
var destination = (Number(positionValue) + totalDistance) + "px";
function MoveFrame() {
//If element reaches its destination...
if (elementStyle.getPropertyValue(LeftOrTop) == destination) {
//...stop the interval motion
clearInterval(movingFrames);
}
//Otherwise, continue the interval movement
else {
elementStyle = window.getComputedStyle(element);
positionValue = elementStyle.getPropertyValue(LeftOrTop).replace("px", "");
element.style[LeftOrTop] = (Number(positionValue) + frameDistance) + "px";
}
}
//Define time interval for movement
var movingFrames = setInterval(MoveFrame, 500);
}
#stack {
position: relative;
}
#stack canvas {
position: absolute;
display: block;
left: 50%;
transform: translateX(-50%);
margin-top: 150px;
}
#speaker {
position: absolute;
top: 20px;
animation-duration: 800ms;
animation-name: fadein;
animation-iteration-count: 10;
}
@keyframes fadein {
from {
opacity: 0.25;
}
50% {
opacity: 1;
}
to {
opacity: 0.25;
}
}
<!DOCTYPE html>
{% load static %}
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="{% static 'entrance/entrance.css' %}">
<script src="{% static 'entrance/entrance.js' %}"></script>
</head>
<body>
<p hidden>
<img src="{% static 'entrance/Waterfall.jpg' %}" alt="issue here" id="waterfall" />
</p>
<img src="{% static 'entrance/sound-icon.svg' %}" id="speaker" />
<p id="test"></p>
<audio id="boyfriend" source src="{% static 'entrance/02 30 Minute Boyfriend.mp3' %}" type="audio/mp3"></audio>
<div id="stack" onmouseenter="PlayAudio()">
<canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas>
</div>
</body>
</html>
您获得的数据图像将是一个数组,在 canvas 上每个点有 4 个字节,前 3 个字节是 RGB 颜色,第 4 个字节是 alpha。
如果颜色是透明的,这第 4 个将为 0。每次执行一些擦除操作时,您都需要检查数组中的第 4 个字节。如果你遇到一个不为零的,你就知道擦除没有完成。
这是一个非常有用的参考:https://www.w3schools.com/tags/canvas_getimagedata.asp
我有一个网页,其中有两个 canvas 元素堆叠在一起。这是某些功能的基础,让我可以“擦除”顶部 canvas 以显示加载到底部 canvas 的图像。该功能运行良好。
我现在要做的是在顶部 canvas 被完全“擦除”后触发一个事件,即顶部上下文的所有像素都是透明的。我在 SO 上找到了通过 getImageData 检查特定像素的 alpha 值的方法,但我正在尝试找出一种方法来确定最后一个像素的 alpha 值何时 = 0。
我已经包含了我的代码以及使用 for 和 if 循环执行此操作的未完成尝试(但这似乎不是最佳方法)。我发现的另一个问题是,当我使用 getImageData 时,我的 canvas.
的两个边缘周围出现了一个灰色细边框。提前感谢您的帮助!
window.onload = function() {
//Move speaker image across page
var speaker = document.getElementById('speaker');
speaker.onload = MoveElement(speaker, "right", 1000);
//Create canvases & contexts
var canvas = document.getElementById('canvas');
var ctxB = canvas.getContext('2d');
var canvas2 = document.getElementById('canvas2');
var ctxT = canvas2.getContext('2d');
//Get waterfall image object
var waterfall = document.getElementById('waterfall');
//Set canvas w&h properties
canvas.width = canvas2.width = .3*waterfall.width;
canvas.height = canvas2.height = .3*waterfall.height;
//Populate Bottom canvas with waterfall image
ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height);
//Populate Top canvas with white rectangle
ctxT.fillStyle = "white";
ctxT.fillRect(0, 0, canvas2.width, canvas2.height);
//Make Top canvas "erasable"
canvas2.addEventListener('mousemove', event => {
var x = event.offsetX;
var y = event.offsetY;
const eraseSize = 125;
ctxT.clearRect(x-eraseSize/2, y-eraseSize/2, eraseSize, eraseSize);
})
//Attempt to trigger an event when all pixels of top canvas have alpha = 0
var imageDataTop = ctxT.getImageData(0, 0, canvas2.width, canvas2.height);
console.log(imageDataTop);
for (var i = 0; i < imageDataTop; i++) {
if (imageDataTop.data[i] = 0) {
//
}
}
}
function PlayAudio() {
document.getElementById('boyfriend').play();
}
//Move an element in a given direction a certain distance
function MoveElement(element, direction, totalDistance) {
//Determine horizontal or vertical direction
var LeftOrTop = (direction=="left" || direction=="right") ? "left" : "top";
//Set default frame distance
var frameDistance = 150;
//Adjust for backwards direction
if (direction=="left" || direction=="up") {
totalDistance *= -1;
frameDistance = -1;
}
//Get style data object for element
var elementStyle = window.getComputedStyle(element);
//Get Left or Top position of element
var positionValue = elementStyle.getPropertyValue(LeftOrTop).replace("px", "");
//Apply direction and distance change to element
var destination = (Number(positionValue) + totalDistance) + "px";
function MoveFrame() {
//If element reaches its destination...
if (elementStyle.getPropertyValue(LeftOrTop) == destination) {
//...stop the interval motion
clearInterval(movingFrames);
}
//Otherwise, continue the interval movement
else {
elementStyle = window.getComputedStyle(element);
positionValue = elementStyle.getPropertyValue(LeftOrTop).replace("px", "");
element.style[LeftOrTop] = (Number(positionValue) + frameDistance) + "px";
}
}
//Define time interval for movement
var movingFrames = setInterval(MoveFrame, 500);
}
#stack {
position: relative;
}
#stack canvas {
position: absolute;
display: block;
left: 50%;
transform: translateX(-50%);
margin-top: 150px;
}
#speaker {
position: absolute;
top: 20px;
animation-duration: 800ms;
animation-name: fadein;
animation-iteration-count: 10;
}
@keyframes fadein {
from {
opacity: 0.25;
}
50% {
opacity: 1;
}
to {
opacity: 0.25;
}
}
<!DOCTYPE html>
{% load static %}
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="{% static 'entrance/entrance.css' %}">
<script src="{% static 'entrance/entrance.js' %}"></script>
</head>
<body>
<p hidden>
<img src="{% static 'entrance/Waterfall.jpg' %}" alt="issue here" id="waterfall" />
</p>
<img src="{% static 'entrance/sound-icon.svg' %}" id="speaker" />
<p id="test"></p>
<audio id="boyfriend" source src="{% static 'entrance/02 30 Minute Boyfriend.mp3' %}" type="audio/mp3"></audio>
<div id="stack" onmouseenter="PlayAudio()">
<canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas>
</div>
</body>
</html>
您获得的数据图像将是一个数组,在 canvas 上每个点有 4 个字节,前 3 个字节是 RGB 颜色,第 4 个字节是 alpha。
如果颜色是透明的,这第 4 个将为 0。每次执行一些擦除操作时,您都需要检查数组中的第 4 个字节。如果你遇到一个不为零的,你就知道擦除没有完成。
这是一个非常有用的参考:https://www.w3schools.com/tags/canvas_getimagedata.asp