gpt4 book ai didi

javascript - 边框半径防止可点击

转载 作者:可可西里 更新时间:2023-11-01 13:50:52 25 4
gpt4 key购买 nike

我正在使用 this color wheel ,我想让它在您点击 Canvas 外部时,当您点击边框半径时,不会发生任何事情。

我必须防止两件事发生:

  • 我必须防止光标变成指针。
  • 我必须防止颜色和拖动器不移动和改变。
    或者我可以不调用 redraw()

这是我尝试做的事情:在 redraw() 函数中,在 d > radiusSquaredif 语句 处(第 97 行),我安慰了一个随机字符串以了解 if 语句 何时被调用,因此我可以在那里插入预防措施。

这样做的问题是,如果您开始在 Canvas 中拖动拖动器,然后将其拖出 Canvas ,它仍然会控制字符串。 (我希望这很清楚。如果您有更好的方式表达我的观点,请编辑问题。)

如果光标超出 Canvas 的边界半径,无论拖动是在 Canvas 内开始还是在 Canvas 外,我如何防止发生变化?

JSFiddle

var b = document.body;
var c = document.createElement('canvas');
var a = c.getContext('2d');
var wrapper = document.getElementById('wrapper');
document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218

var colorWheelDiv = document.createElement('div');
var dragger = document.createElement('div');
dragger.id = 'dragger';

var otherDiv = document.createElement('div');
colorWheelDiv.appendChild(c);
colorWheelDiv.appendChild(dragger);
colorWheelDiv.style.position = 'relative';

wrapper.appendChild(otherDiv);
wrapper.appendChild(colorWheelDiv);

(function() {

// Declare constants and variables to help with minification
// Some of these are inlined (with comments to the side with the actual equation)
var doc = document;
doc.c = doc.createElement;
b.a = b.appendChild;

var width = c.width = c.height = 400,
label = b.a(doc.c("p")),
input = b.a(doc.c("input")),
imageData = a.createImageData(width, width),
pixels = imageData.data,
oneHundred = input.value = input.max = 100,
circleOffset = 0,
diameter = width - circleOffset * 2,
radius = diameter / 2,
radiusPlusOffset = radius + circleOffset,
radiusSquared = radius * radius,
two55 = 255,
currentY = oneHundred,
currentX = -currentY,
wheelPixel = circleOffset * 4 * width + circleOffset * 4;

// Math helpers
var math = Math,
PI = math.PI,
PI2 = PI * 2,
sqrt = math.sqrt,
atan2 = math.atan2;

// Setup DOM properties
b.style.textAlign = "center";
label.style.font = "2em courier";
input.type = "range";

// Load color wheel data into memory.
for (y = input.min = 0; y < width; y++) {
for (x = 0; x < width; x++) {
var rx = x - radius,
ry = y - radius,
d = rx * rx + ry * ry,
rgb = hsvToRgb(
(atan2(ry, rx) + PI) / PI2, // Hue
sqrt(d) / radius, // Saturation
1 // Value
);

// Print current color, but hide if outside the area of the circle
pixels[wheelPixel++] = rgb[0];
pixels[wheelPixel++] = rgb[1];
pixels[wheelPixel++] = rgb[2];
pixels[wheelPixel++] = d > radiusSquared ? 0 : two55;
}
}

// Bind Event Handlers
input.onchange = redraw;
dragger.onmousedown = c.onmousedown = doc.onmouseup = function(e) {
// Unbind mousemove if this is a mouseup event, or bind mousemove if this a mousedown event
doc.onmousemove = /p/.test(e.type) ? 0 : (redraw(e), redraw);
}

// Handle manual calls + mousemove event handler + input change event handler all in one place.
function redraw(e) {

// Only process an actual change if it is triggered by the mousemove or mousedown event.
// Otherwise e.pageX will be undefined, which will cause the result to be NaN, so it will fallback to the current value
currentX = e.pageX - $(c).offset().left - radiusPlusOffset || currentX;
currentY = e.pageY - $(c).offset().top - radiusPlusOffset || currentY;

// Scope these locally so the compiler will minify the names. Will manually remove the 'var' keyword in the minified version.
var theta = atan2(currentY, currentX),
d = currentX * currentX + currentY * currentY;

// If the x/y is not in the circle, find angle between center and mouse point:
// Draw a line at that angle from center with the distance of radius
// Use that point on the circumference as the draggable location
if (d > radiusSquared) {
console.log('outside');
currentX = radius * math.cos(theta);
currentY = radius * math.sin(theta);
theta = atan2(currentY, currentX);
d = currentX * currentX + currentY * currentY;
}

label.textContent = b.style.background = hsvToRgb(
(theta + PI) / PI2, // Current hue (how many degrees along the circle)
sqrt(d) / radius, // Current saturation (how close to the middle)
input.value / oneHundred // Current value (input type="range" slider value)
)[3];

// Reset to color wheel and draw a spot on the current location.
a.putImageData(imageData, 0, 0);

// Draw the current spot.
// I have tried a rectangle, circle, and heart shape.
/*
// Rectangle:
a.fillStyle = '#000';
a.fillRect(currentX+radiusPlusOffset,currentY+radiusPlusOffset, 6, 6);
*/
/*
// Circle:
a.beginPath();
a.strokeStyle = '#000';
a.arc(~~currentX+radiusPlusOffset,~~currentY+radiusPlusOffset, 4, 0, PI2);
a.stroke();
*/

// Heart:
/*a.font = "1em arial";
a.fillText("♥", currentX + radiusPlusOffset - 4, currentY + radiusPlusOffset + 4);*/

dragger.style.left = (~~currentX + radiusPlusOffset) + 'px';
dragger.style.top = (~~currentY + radiusPlusOffset) + 'px';

}

// Created a shorter version of the HSV to RGB conversion function in TinyColor
// https://github.com/bgrins/TinyColor/blob/master/tinycolor.js
function hsvToRgb(h, s, v) {
h *= 6;
var i = ~~h,
f = h - i,
p = v * (1 - s),
q = v * (1 - f * s),
t = v * (1 - (1 - f) * s),
mod = i % 6,
r = [v, q, p, p, t, v][mod] * two55,
g = [t, v, v, q, p, p][mod] * two55,
b = [p, p, t, v, v, q][mod] * two55;

return [r, g, b, "rgb(" + ~~r + "," + ~~g + "," + ~~b + ")"];
}

// Kick everything off
redraw(0);

/*
// Just an idea I had to kick everything off with some changing colors…
// Probably no way to squeeze this into 1k, but it could probably be a lot smaller than this:
currentX = currentY = 1;
var interval = setInterval(function() {
currentX--;
currentY*=1.05;
redraw(0)
}, 7);

setTimeout(function() {
clearInterval(interval)
}, 700)
*/

})();
#wrapper {
position: relative;
width: 400px;
height: 400px;
cursor: pointer;
}
#dragger {
width: 8px;
height: 8px;
border-radius: 50%;
display: block;
position: absolute;
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id='wrapper'>
</div>

最佳答案

要防止颜色和拖动器发生变化:

if (d > radiusSquared) {
currentX = radius * math.cos(theta);
currentY = radius * math.sin(theta);
theta = atan2(currentY, currentX);
d = currentX * currentX + currentY * currentY;
}else{
label.textContent = b.style.background = hsvToRgb(
(theta + PI) / PI2,
sqrt(d) / radius,
input.value / oneHundred
)[3];
a.putImageData(imageData, 0, 0);
dragger.style.left = (~~currentX + radiusPlusOffset) + 'px';
dragger.style.top = (~~currentY + radiusPlusOffset) + 'px';
}

JSFiddle

至于指针,一种选择是捕捉 Canvas 上的鼠标悬停事件,并根据位置手动设置指针。

关于javascript - 边框半径防止可点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34550434/

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