当前位置:首页 > 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初始化代码...

水墨动画效果

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

js实现水墨特效

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适合高性能渲染,而动画方法可以创建动态水墨效果。

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

相关文章

css制作特效

css制作特效

CSS 制作特效的方法 CSS 提供了多种方式实现动态和视觉特效,以下是一些常见方法: 动画效果 通过 @keyframes 和 animation 属性创建复杂动画: @keyframes fa…

css能制作特效

css能制作特效

CSS 制作特效的方法 CSS 提供了多种方式来实现网页特效,包括动画、过渡、变形和滤镜等。以下是一些常见的 CSS 特效实现方法: 动画(Animation) 通过 @keyframes 规则定义…

js 实现旗帜特效

js 实现旗帜特效

使用 Canvas 实现旗帜飘动效果 通过 Canvas 绘制旗帜并模拟物理飘动效果,核心是利用正弦函数控制顶点位移: const canvas = document.getElementB…

jquery特效大全

jquery特效大全

jQuery 特效实现方法 滑动特效 通过 slideUp(), slideDown(), slideToggle() 实现元素的滑动显示/隐藏。 $("#element").slideDown…

uniapp滑动特效

uniapp滑动特效

uniapp 滑动特效实现方法 使用swiper组件实现基础滑动 swiper是uniapp内置的滑块视图容器,常用于轮播图或页面切换。通过设置autoplay、interval和circular等参…

css制作特效

css制作特效

CSS 制作特效的方法 阴影效果 使用 box-shadow 属性为元素添加阴影,增强立体感。 .box { box-shadow: 5px 5px 15px rgba(0, 0, 0, 0…