添加一个跟随鼠标并根据当前颜色改变颜色的圆圈 |交互式 SVG 着色页 |使用 JavaScript

问题描述 投票:0回答:1

我正在制作一个交互式着色页。用户会看到一个 SVG 图像,当他们从样本中选择一种颜色时,他们可以单击图像的一部分来更改其填充颜色。

到目前为止,我已经有了该部分、图像导出和自定义颜色选择器:

https://codepen.io/candidee/pen/abxvPKV?editors=1100

问题是:我想为用户提供某种当前颜色的指示器。我在想某种跟随鼠标的小圆圈。当用户单击样本颜色时,圆圈的填充/背景颜色应与

_currentFill
的当前值匹配。

我尝试查询 GPT,但运气不佳。这是建议的内容 - 圆圈跟随,但颜色不会改变或更新。

// Function to handle color picker selection
function handleColorPickerSelection(event) {
  // Check if a color picker input element already exists
  if (!document.getElementById('colorPickerInput')) {
    // Create a color picker input element
    var input = document.createElement('input');
    input.type = 'color';
    input.id = 'colorPickerInput'; // Assign an id to the input element

    // Add event listener for color change
    input.addEventListener('change', function() {
      // Set the current fill to the selected color
      var selectedColor = input.value;
      _currentFill = 'fill:' + selectedColor;

      // Remove the input element from the body
      document.body.removeChild(input);
    });

    // Append the input element to the body
    document.body.appendChild(input);

    // Trigger click event on color picker input
    input.click();
  }
}

// Add event listener to the custom swatch for color picker
document.getElementById('colorPickerSwatch').addEventListener('click', handleColorPickerSelection);

// Function to update the position of the color indicator circle
function updateColorIndicator(event) {
  var indicator = document.getElementById('colorIndicator');

  // Update the position of the indicator circle based on the mouse cursor
  indicator.setAttribute('cx', event.clientX - 8); // Adjust for SVG viewBox and circle size
  indicator.setAttribute('cy', event.clientY - 8); // Adjust for SVG viewBox and circle size
}

// Add event listener to update the color indicator position when the mouse moves
document.addEventListener('mousemove', updateColorIndicator);
<div id="sidebar">
  <!-- Colour swatches -->
  <svg id="swatches" width="60px" height="200px" viewBox="-4 -4 60 200" style="stroke: #000;stroke-width: 2; stroke-opacity: 0.1">
    <!-- Rainbow gradient -->
    <defs>
      <linearGradient id="rainbowGradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" stop-color="red"/>
        <stop offset="20%" stop-color="orange"/>
        <stop offset="40%" stop-color="yellow"/>
        <stop offset="60%" stop-color="green"/>
        <stop offset="80%" stop-color="blue"/>
        <stop offset="100%" stop-color="violet"/>
      </linearGradient>
    </defs>
    <!-- Rect for rainbow gradient -->
    <rect id="colorPickerSwatch" x="0" y="100" width="20" height="20" fill="url(#rainbowGradient)" style="stroke:#000;stroke-width:2"/>
    
    <!-- Indicator circle -->
    <circle id="colorIndicator" cx="0" cy="0" r="5" fill="transparent" stroke="#000" stroke-width="2"/>
  </svg>
</div>

javascript html jquery svg mouseevent
1个回答
0
投票

玩玩这个。

你的 mousemove 脚本占用了 CPU,所以选择器没有显示,你就失踪了

indicator.style.fill = input.value;

const indicator = document.getElementById('colorIndicator');
const colorPickerSwatch = document.getElementById('colorPickerSwatch');

// Function to hide the indicator
function hideIndicator() {
  indicator.style.display = 'none';
}

// Function to show the indicator
function showIndicator() {
  indicator.style.display = '';
}

// Add mouseover and mouseout event listeners to the swatch
colorPickerSwatch.addEventListener('mouseover', hideIndicator);
colorPickerSwatch.addEventListener('mouseout', showIndicator);

// Function to handle color picker selection
function handleColorPickerSelection(event) {
  // Create a color picker input element if it does not exist
  if (!document.getElementById('colorPickerInput')) {
    var input = document.createElement('input');
    input.type = 'color';
    input.id = 'colorPickerInput';

    // Add event listener for color change
    input.addEventListener('change', function() {
      // Set the color of the indicator to the selected color
      indicator.style.fill = input.value;
      
      // Show the indicator if it was hidden
      showIndicator();

      // Remove the input element from the body
      document.body.removeChild(input);
    });

    // Append the input element to the body and trigger the color picker
    document.body.appendChild(input);
    input.click();
  }
}

// Add event listener to the swatch for the color picker
colorPickerSwatch.addEventListener('click', handleColorPickerSelection);


// Add event listener to the custom swatch for color picker
document.getElementById('colorPickerSwatch').addEventListener('click', handleColorPickerSelection);

function updateColorIndicator(event) {
  // Check if the mouse is over the colorPickerSwatch
  if (!colorPickerSwatch.contains(event.target)) {
    // Update the position of the indicator circle based on the mouse cursor
    indicator.setAttribute('cx', event.clientX - 8); // Adjust for SVG viewBox and circle size
    indicator.setAttribute('cy', event.clientY - 8); // Adjust for SVG viewBox and circle size
  }
}

document.addEventListener('mousemove', updateColorIndicator);
<div id="sidebar">
  <!-- Colour swatches -->
  <svg id="swatches" width="60px" height="200px" viewBox="-4 -4 60 200" style="stroke: #000;stroke-width: 2; stroke-opacity: 0.1">
    <!-- Rainbow gradient -->
    <defs>
      <linearGradient id="rainbowGradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" stop-color="red"/>
        <stop offset="20%" stop-color="orange"/>
        <stop offset="40%" stop-color="yellow"/>
        <stop offset="60%" stop-color="green"/>
        <stop offset="80%" stop-color="blue"/>
        <stop offset="100%" stop-color="violet"/>
      </linearGradient>
    </defs>
    <!-- Rect for rainbow gradient -->
    <rect id="colorPickerSwatch" x="0" y="100" width="20" height="20" fill="url(#rainbowGradient)" style="stroke:#000;stroke-width:2"/>
    
    <!-- Indicator circle -->
    <circle id="colorIndicator" cx="0" cy="0" r="5" fill="transparent" stroke="#000" stroke-width="2"/>
  </svg>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.