gpt4 book ai didi

javascript - 使用 Canvas 作为多个范围输入的垫

转载 作者:行者123 更新时间:2023-12-03 04:21:00 26 4
gpt4 key购买 nike

我正在尝试构建一个 html Canvas 垫,它允许用户在垫上拖放一个点,然后返回两个值(一个用于 Y 轴,一个用于 Y 轴),我可以用于使用网络音频 API 触发效果。

我已经解决了问题的网络音频 API 部分。

用户:

  • 单击点并将其拖动到 X/Y 网格上的任意位置
  • 在 Drop 时,我们将有一个 X 和 Y 值(可能在隐藏范围输入中),该值会触发事件监听器。
  • X值eventListener影响延迟效果的湿/干
  • Y值eventListener影响延迟效果的delay_time

enter image description here

到目前为止,我已经能够创建和渲染 Canvas 和圆圈,并在 svg 元素和窗口上添加事件监听器。我的想法是,我可以检测 Canvas 内何时发生事件以及该单击事件何时离开 Canvas 。

// Draw SVG pad
function drawDelayPad() {
var canvas = document.getElementById('delayPad');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var rectangle = new Path2D();
rectangle.rect(1, 1, 200, 200);

var circle = new Path2D();
circle.moveTo(150, 150);
circle.arc(100, 35, 10, 0 , 2 * Math.PI);
ctx.stroke(rectangle);
ctx.fill(circle);
}
}

// Listener on canvas
var canvas = document.getElementById('delayPad');

canvas.addEventListener("mousedown", function(){
console.log("click inside our canvas")
})

// Listener on document to check if we're outside the canvas
window.addEventListener("mouseup", function(){
console.log("outside our canvas")
});

所以我认为我现在需要确定的是,当 Canvas 内部发生点击事件时,它距离圆有多远,如果它确实落在圆的边界内,我应该将其重绘为只要 mousedown 事件处于事件状态。

任何帮助将不胜感激。

最佳答案

我找到了一个不错的小解决方案,这证实了我对点击计数器的怀疑!所有功劳确实归于 rectangleWorld因为我在很大程度上只能修改他们提供的示例。

Here's a codepen

// Draw SVG pad
function canvasApp(canvasID) {
var theCanvas = document.getElementById(canvasID);
var context = theCanvas.getContext("2d");

init();

var numShapes;
var shapes;
var dragIndex;
var dragging;
var mouseX;
var mouseY;
var dragHoldX;
var dragHoldY;

function init() {
numShapes = 1;
shapes = [];

makeShapes();

drawScreen();

theCanvas.addEventListener("mousedown", mouseDownListener, false);
}

function makeShapes() {
var i;
var tempX;
var tempY;
var tempRad;
var tempR;
var tempG;
var tempB;
var tempColor;
var tempShape;
for (i = 0; i < numShapes; i++) {
// My canvas element is 240x240
tempRad = 10;
tempX = 0 + tempRad;
tempY = 240 - tempRad;
tempR = Math.floor(Math.random() * 255);
tempG = Math.floor(Math.random() * 255);
tempB = Math.floor(Math.random() * 255);
tempColor = "rgb(" + tempR + "," + tempG + "," + tempB + ")";
tempShape = {
x: tempX,
y: tempY,
rad: tempRad,
color: tempColor
};
shapes.push(tempShape);
}
}

function mouseDownListener(evt) {
var i;
//We are going to pay attention to the layering order of the objects so that if a mouse down occurs over more than object,
//only the topmost one will be dragged.
var highestIndex = -1;

//getting mouse position correctly, being mindful of resizing that may have occured in the browser:
var bRect = theCanvas.getBoundingClientRect();
mouseX = (evt.clientX - bRect.left) * (theCanvas.width / bRect.width);
mouseY = (evt.clientY - bRect.top) * (theCanvas.height / bRect.height);

//find which shape was clicked
for (i = 0; i < numShapes; i++) {
if (hitTest(shapes[i], mouseX, mouseY)) {
dragging = true;
if (i > highestIndex) {
//We will pay attention to the point on the object where the mouse is "holding" the object:
dragHoldX = mouseX - shapes[i].x;
dragHoldY = mouseY - shapes[i].y;
highestIndex = i;
dragIndex = i;
}
}
}

if (dragging) {
window.addEventListener("mousemove", mouseMoveListener, false);
}
theCanvas.removeEventListener("mousedown", mouseDownListener, false);
window.addEventListener("mouseup", mouseUpListener, false);

//code below prevents the mouse down from having an effect on the main browser window:
if (evt.preventDefault) {
evt.preventDefault();
} //standard
else if (evt.returnValue) {
evt.returnValue = false;
} //older IE
return false;
}

function mouseUpListener(evt) {
theCanvas.addEventListener("mousedown", mouseDownListener, false);
window.removeEventListener("mouseup", mouseUpListener, false);
if (dragging) {
dragging = false;
window.removeEventListener("mousemove", mouseMoveListener, false);
}
}

function mouseMoveListener(evt) {
var posX;
var posY;
var shapeRad = shapes[dragIndex].rad;
var minX = shapeRad;
var maxX = theCanvas.width - shapeRad;
var minY = shapeRad;
var maxY = theCanvas.height - shapeRad;
//getting mouse position correctly
var bRect = theCanvas.getBoundingClientRect();
mouseX = (evt.clientX - bRect.left) * (theCanvas.width / bRect.width);
mouseY = (evt.clientY - bRect.top) * (theCanvas.height / bRect.height);

// Divide by width of canvas and multiply to get percentage out of 100
var DelayTime = ((mouseX / 240) * 100);
// Invert returned value to get percentage out of 100
var DelayFeedback = (100 - (mouseY / 240) * 100);

// Set delay time as a portion of 2seconds
delayEffect.delayTime.value = DelayTime / 100 * 2.0;
// set delay feedback gain as value of random number
delayFeedback.gain.value = (DelayFeedback / 100 * 1.0);

//clamp x and y positions to prevent object from dragging outside of canvas
posX = mouseX - dragHoldX;
posX = (posX < minX) ? minX : ((posX > maxX) ? maxX : posX);
posY = mouseY - dragHoldY;
posY = (posY < minY) ? minY : ((posY > maxY) ? maxY : posY);

shapes[dragIndex].x = posX;
shapes[dragIndex].y = posY;

drawScreen();
}

function hitTest(shape, mx, my) {

var dx;
var dy;
dx = mx - shape.x;
dy = my - shape.y;

//a "hit" will be registered if the distance away from the center is less than the radius of the circular object
return (dx * dx + dy * dy < shape.rad * shape.rad);
}

function drawShapes() {
var i;
for (i = 0; i < numShapes; i++) {
context.fillStyle = shapes[i].color;
context.beginPath();
context.arc(shapes[i].x, shapes[i].y, shapes[i].rad, 0, 2 * Math.PI, false);
context.closePath();
context.fill();
}
}

function drawScreen() {
context.fillStyle = "#000000";
context.fillRect(0, 0, theCanvas.width, theCanvas.height);

drawShapes();
}

}

window.addEventListener("load", windowLoadHandler, false);

function windowLoadHandler() {
canvasApp('delayPad');
}

还有一些缺点,例如 mouseMoveListener,虽然限制了圆的移动,但会继续增加你的 x 和 y 值。这意味着您必须使用现有的监听器来检查拖动事件何时退出圆圈,或者更简单地,您可以设置 X 和 Y 值的上限。

关于javascript - 使用 Canvas 作为多个范围输入的垫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43948602/

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