我设计了一个颜色选择器,从中可以在画布旁边显示所选的颜色。现在的问题是,即使位置相对,我每次尝试将指示器拖出画布时,也是如此。
每次我尝试将指示器拖出画布时。我在下图中高亮显示了指示器
var canvas = document.getElementById('color-picker');
var context = canvas.getContext('2d');
var w = 250;
var h = 250;
canvas.width = w;
canvas.height = h;
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x;
for (var angle = 0; angle <= 360; angle += 1) {
var startAngle = (angle - 2) * Math.PI / 180;
var endAngle = angle * Math.PI / 180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, false);
context.closePath();
var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'hsl(' + angle + ', 10%, 100%)');
gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 50%)');
context.fillStyle = gradient;
context.fill();
}
var m = {
x: canvas.width / 2,
y: canvas.height / 2
};
var drag = false;
var location_path = document.getElementById('_lp_');
var lp_width = location_path.offsetWidth;
var lp_height = location_path.offsetHeight;
var container = document.getElementById('container');
var selected_color = document.getElementById('selected_color');
var def_color = "#f8fff9";
selected_color.style.backgroundColor = def_color;
container.addEventListener('mousedown', dragged, false);
container.addEventListener('mousemove', moving, false);
window.addEventListener('mouseup', noDrag, false);
function dragged() {
drag = true;
}
function noDrag() {
drag = false;
}
function moving(e) {
if (drag) {
var ink_x = (e.clientX - container.offsetLeft);
var ink_y = (e.clientY - container.offsetTop);
m.x = e.clientX - container.offsetLeft - lp_width / 2;
m.y = e.clientY - container.offsetTop - lp_height - 10; //why 10? 10 for padding
if (Distance(ink_x, ink_y, w / 2, h / 2) > radius) {
drag = false;
}
location_path.style.left = m.x + 'px';
location_path.style.top = m.y + 'px';
var getData = context.getImageData(ink_x, ink_y, 1, 1);
var pxl = getData.data;
var r = pxl[0];
var g = pxl[1];
var b = pxl[2];
var a = pxl[3];
// indicator.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
selected_color.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
}
}
function rgb2hex(red, green, blue) {
var rgb = blue | (green << 8) | (red << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1)
}
function Distance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
.lighting-wrapper {
margin: 5% auto;
}
.lighting-left,
.lighting-right {
padding: 50px;
}
.lighting-color-picker-wrapper,
.lighting-selected-color-wrapper {
position: relative;
width: 250px;
height: 250px;
margin: 150px auto;
border-radius: 50%;
}
.location-path {
position: absolute;
width: 40px;
height: 40px;
padding: 10px;
background: #fff;
border-radius: 50%;
border-bottom-left-radius: 0%;
top: 58px;
left: 92px;
transform: rotate(-45deg);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
user-select: none;
transition: all 0.1s;
}
<div class="container">
<div class="lighting-wrapper shadow-sm">
<div class="row align-items-center">
<div class="col-md-6 d-flex justify-content-center lighting-left">
<div class="lighting-color-picker-wrapper" id="container">
<canvas id="color-picker" class="position-relative"></canvas>
<div id="_lp_" class="location-path"></div>
</div>
</div>
<div class="col-md-6 d-flex justify-content-center lighting-right">
<div class="lighting-selected-color-wrapper" id="selected_color">
</div>
</div>
</div>
</div>
</div>
答案 0 :(得分:0)
看起来您的代码受页面滚动的影响。
尝试将“ e.clientY”更改为“ e.pageY”。
var canvas = document.getElementById('color-picker');
var context = canvas.getContext('2d');
var w = 250;
var h = 250;
canvas.width = w;
canvas.height = h;
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x;
for (var angle = 0; angle <= 360; angle += 1) {
var startAngle = (angle - 2) * Math.PI / 180;
var endAngle = angle * Math.PI / 180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, false);
context.closePath();
var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'hsl(' + angle + ', 10%, 100%)');
gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 50%)');
context.fillStyle = gradient;
context.fill();
}
var m = {
x: canvas.width / 2,
y: canvas.height / 2
};
var drag = false;
var location_path = document.getElementById('_lp_');
var lp_width = location_path.offsetWidth;
var lp_height = location_path.offsetHeight;
var container = document.getElementById('container');
var selected_color = document.getElementById('selected_color');
var def_color = "#f8fff9";
selected_color.style.backgroundColor = def_color;
container.addEventListener('mousedown', dragged, false);
container.addEventListener('mousemove', moving, false);
window.addEventListener('mouseup', noDrag, false);
function dragged() {
drag = true;
}
function noDrag() {
drag = false;
}
function moving(e) {
if (drag) {
var ink_x = (e.pageX - container.offsetLeft);
var ink_y = (e.pageY - container.offsetTop);
if (Distance(ink_x, ink_y, w / 2, h / 2) > radius) {
var vector = { x: ink_x - w / 2, y: ink_y - h / 2 };
normalize(vector);
ink_x = Math.trunc(vector.x * radius) + w / 2;
ink_y = Math.trunc(vector.y * radius) + h / 2;
drag = false;
}
m.x = ink_x - lp_width / 2;
m.y = ink_y - lp_height - 10; //why 10? 10 for padding
location_path.style.left = m.x + 'px';
location_path.style.top = m.y + 'px';
var getData = context.getImageData(ink_x, ink_y, 1, 1);
var pxl = getData.data;
var r = pxl[0];
var g = pxl[1];
var b = pxl[2];
var a = pxl[3];
// indicator.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
selected_color.style.background = "rgb(" + r + ',' + g + ',' + b + ")";
}
}
function rgb2hex(red, green, blue) {
var rgb = blue | (green << 8) | (red << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1)
}
function Distance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
function normalize(vector) {
var length = Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));
vector.x = vector.x / length;
vector.y = vector.y / length;
}
.lighting-wrapper {
margin: 5% auto;
}
.lighting-left,
.lighting-right {
padding: 50px;
}
.lighting-color-picker-wrapper,
.lighting-selected-color-wrapper {
position: relative;
width: 250px;
height: 250px;
margin: 150px auto;
border-radius: 50%;
}
.location-path {
position: absolute;
width: 40px;
height: 40px;
padding: 10px;
background: #fff;
border-radius: 50%;
border-bottom-left-radius: 0%;
top: 58px;
left: 92px;
transform: rotate(-45deg);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
user-select: none;
transition: all 0.1s;
}
<div class="container">
<div class="lighting-wrapper shadow-sm">
<div class="row align-items-center">
<div class="col-md-6 d-flex justify-content-center lighting-left">
<div class="lighting-color-picker-wrapper" id="container">
<canvas id="color-picker" class="position-relative"></canvas>
<div id="_lp_" class="location-path"></div>
</div>
</div>
<div class="col-md-6 d-flex justify-content-center lighting-right">
<div class="lighting-selected-color-wrapper" id="selected_color">
</div>
</div>
</div>
</div>
</div>