当前位置:首页 > JavaScript

js实现水墨特效

2026-02-02 16:01:41JavaScript

实现水墨特效的方法

水墨特效可以通过Canvas结合图像处理技术实现,以下是一种常见的实现方式:

使用Canvas处理图像

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.src = 'your-image.jpg';
img.onload = function() {
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0);

  // 获取像素数据
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;

  // 应用水墨效果
  for(let i = 0; i < data.length; i += 4) {
    // 灰度化
    const gray = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2];

    // 增加对比度
    const contrast = 1.5;
    const factor = (259 * (contrast + 255)) / (255 * (259 - contrast));
    const newColor = factor * (gray - 128) + 128;

    // 应用水墨风格
    const inkColor = newColor < 128 ? 0 : 255;

    data[i] = inkColor;
    data[i+1] = inkColor;
    data[i+2] = inkColor;
  }

  ctx.putImageData(imageData, 0, 0);
  document.body.appendChild(canvas);
};

水墨扩散效果实现

为了实现更真实的水墨扩散效果,可以添加模糊和边缘检测:

function applyInkEffect(canvas) {
  const ctx = canvas.getContext('2d');
  const tempCanvas = document.createElement('canvas');
  const tempCtx = tempCanvas.getContext('2d');

  tempCanvas.width = canvas.width;
  tempCanvas.height = canvas.height;

  // 1. 灰度处理
  tempCtx.drawImage(canvas, 0, 0);
  const imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
  const data = imageData.data;

  for(let i = 0; i < data.length; i += 4) {
    const gray = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2];
    data[i] = data[i+1] = data[i+2] = gray;
  }
  tempCtx.putImageData(imageData, 0, 0);

  // 2. 边缘检测
  edgeDetection(tempCanvas);

  // 3. 模糊处理
  gaussianBlur(tempCanvas, 2);

  ctx.drawImage(tempCanvas, 0, 0);
}

// 边缘检测函数示例
function edgeDetection(canvas) {
  // Sobel算子实现...
}

// 高斯模糊函数示例
function gaussianBlur(canvas, radius) {
  // 模糊算法实现...
}

使用WebGL实现高性能水墨效果

对于更复杂的水墨渲染,可以使用WebGL:

const vertexShaderSource = `
  attribute vec2 a_position;
  varying vec2 v_texCoord;

  void main() {
    gl_Position = vec4(a_position, 0, 1);
    v_texCoord = a_position * 0.5 + 0.5;
  }
`;

const fragmentShaderSource = `
  precision mediump float;
  varying vec2 v_texCoord;
  uniform sampler2D u_image;

  void main() {
    vec4 color = texture2D(u_image, v_texCoord);
    float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
    vec3 inkColor = vec3(1.0 - smoothstep(0.3, 0.7, gray));
    gl_FragColor = vec4(inkColor, 1.0);
  }
`;

// WebGL初始化代码...

水墨动画效果

实现水墨逐渐扩散的动画效果:

function animateInkSpread(canvas) {
  const ctx = canvas.getContext('2d');
  let radius = 0;
  const maxRadius = Math.max(canvas.width, canvas.height) / 2;

  function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 创建径向渐变模拟扩散
    const gradient = ctx.createRadialGradient(
      canvas.width/2, canvas.height/2, 0,
      canvas.width/2, canvas.height/2, radius
    );

    gradient.addColorStop(0, 'rgba(0,0,0,0.8)');
    gradient.addColorStop(1, 'rgba(0,0,0,0)');

    ctx.fillStyle = gradient;
    ctx.beginPath();
    ctx.arc(canvas.width/2, canvas.height/2, radius, 0, Math.PI * 2);
    ctx.fill();

    radius += 2;
    if(radius < maxRadius) {
      requestAnimationFrame(draw);
    }
  }

  draw();
}

以上方法提供了从简单到复杂的水墨特效实现方案,可以根据需求选择合适的实现方式。Canvas方法适合静态图像处理,WebGL适合高性能渲染,而动画方法可以创建动态水墨效果。

js实现水墨特效

标签: 水墨特效
分享给朋友:

相关文章

vue实现特效

vue实现特效

Vue实现特效的方法 Vue.js可以通过多种方式实现动态特效,包括内置过渡动画、第三方动画库以及结合CSS3或JavaScript原生动画。以下是几种常见的实现方法: 使用Vue过渡系统 Vue提…

vue实现动画特效

vue实现动画特效

Vue 实现动画特效的方法 Vue 提供了多种方式实现动画特效,主要通过内置组件和第三方库结合 CSS 或 JavaScript 完成。以下是常见的实现方法: 使用 Vue 内置过渡组件 Vue 的…

下雪特效vue实现

下雪特效vue实现

下雪特效的 Vue 实现方法 使用 CSS 动画和 Vue 动态渲染 在 Vue 中可以通过动态生成雪花的 DOM 元素,结合 CSS 动画实现下雪效果。创建一个 Vue 组件,随机生成雪花的位置、大…

vue实现滚轮特效

vue实现滚轮特效

vue实现滚轮特效的方法 使用原生事件监听 在Vue组件中通过@wheel事件监听滚轮动作,结合CSS transform属性实现缩放或位移效果。示例代码: <template>…

vue实现交互特效

vue实现交互特效

Vue 实现交互特效的方法 Vue.js 提供了丰富的工具和指令,可以轻松实现各种交互特效。以下是几种常见的实现方式: 使用 Vue 过渡和动画 Vue 的 <transition> 和…

vue实现边框特效

vue实现边框特效

Vue 实现边框特效的方法 边框特效可以通过 CSS 动画、伪元素、SVG 或 JavaScript 动态计算来实现。以下是几种常见的实现方式: 使用 CSS 动画实现动态边框 在 Vue 组件的…