• Canvas简单动画和像素处理


    动画

    利用JavaScript,可以在canvas元素上很容易地产生动画效果。

    var posX = 20,
        posY = 100;
    
    setInterval(function() {
        context.fillStyle = "black";
        context.fillRect(0,0,canvas.width, canvas.height);
    
        posX += 1;
        posY += 0.25;
    
        context.beginPath();
        context.fillStyle = "white";
    
        context.arc(posX, posY, 10, 0, Math.PI*2, true); 
        context.closePath();
        context.fill();
    }, 30);

    上面代码会产生一个小圆点,每隔30毫秒就向右下方移动的效果。setInterval函数的一开始,之所以要将画布重新渲染黑色底色,是为了抹去上一步的小圆点。

    通过设置圆心坐标,可以产生各种运动轨迹。

    先上升后下降。

    var vx = 10,
        vy = -10,
        gravity = 1;
    
    setInterval(function() {
        posX += vx;
        posY += vy;
        vy += gravity;
        // ...
    });

    上面代码中,x坐标始终增大,表示持续向右运动。y坐标先变小,然后在重力作用下,不断增大,表示先上升后下降。

    小球不断反弹后,逐步趋于静止。

    var vx = 10,
        vy = -10,
        gravity = 1;
    
    setInterval(function() {
        posX += vx;
        posY += vy;
    
        if (posY > canvas.height * 0.75) {
              vy *= -0.6;
              vx *= 0.75;
              posY = canvas.height * 0.75;
        }
    
        vy += gravity;
        // ...
    });

    上面代码表示,一旦小球的y坐标处于屏幕下方75%的位置,向x轴移动的速度变为原来的75%,而向y轴反弹上一次反弹高度的40%。

    像素处理

    通过getImageData方法和putImageData方法,可以处理每个像素,进而操作图像内容。

    假定filter是一个处理像素的函数,那么整个对Canvas的处理流程,可以用下面的代码表示。

    if (canvas.width > 0 && canvas.height > 0) {
    
        var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
    
        filter(imageData);
    
        context.putImageData(imageData, 0, 0);
    
    }

    以下是几种常见的处理方法。

    灰度效果

    灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。

    grayscale = function (pixels) {
        var d = pixels.data;
    
        for (var i = 0; i < d.length; i += 4) {
          var r = d[i];
          var g = d[i + 1];
          var b = d[i + 2];
          d[i] = d[i + 1] = d[i + 2] = (r+g+b)/3;
        }
    
        return pixels;
    };

    复古效果

    复古效果(sepia)则是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。

    sepia = function (pixels) {
        var d = pixels.data;
    
        for (var i = 0; i < d.length; i += 4) {
          var r = d[i];
          var g = d[i + 1];
          var b = d[i + 2];
          d[i]     = (r * 0.393)+(g * 0.769)+(b * 0.189); // red
          d[i + 1] = (r * 0.349)+(g * 0.686)+(b * 0.168); // green
          d[i + 2] = (r * 0.272)+(g * 0.534)+(b * 0.131); // blue
        }
    
        return pixels;
    };

    红色蒙版效果

    红色蒙版指的是,让图像呈现一种偏红的效果。算法是将红色通道设为红、绿、蓝三个值的平均值,而将绿色通道和蓝色通道都设为0。

    red = function (pixels) {
        var d = pixels.data;
    
        for (var i = 0; i < d.length; i += 4) {
          var r = d[i];
          var g = d[i + 1];
          var b = d[i + 2];
          d[i] = (r+g+b)/3;        // 红色通道取平均值
          d[i + 1] = d[i + 2] = 0; // 绿色通道和蓝色通道都设为0
        }
    
        return pixels;
    };

    亮度效果

    亮度效果(brightness)是指让图像变得更亮或更暗。算法将红色通道、绿色通道、蓝色通道,同时加上一个正值或负值。

    brightness = function (pixels, delta) {
        var d = pixels.data;
    
        for (var i = 0; i < d.length; i += 4) {
              d[i] += delta;     // red
              d[i + 1] += delta; // green
              d[i + 2] += delta; // blue   
        }
    
        return pixels;
    };

    反转效果

    反转效果(invert)是指图片呈现一种色彩颠倒的效果。算法为红、绿、蓝通道都取各自的相反值(255-原值)。

    invert = function (pixels) {
        var d = pixels.data;
    
        for (var i = 0; i < d.length; i += 4) {
            d[i] = 255 - d[i];
            d[i+1] = 255 - d[i + 1];
            d[i+2] = 255 - d[i + 2];
        }
    
        return pixels;
    };

    更多参考:

    http://blog.csdn.net/jia20003/article/details/9195915

  • 相关阅读:
    leetcode:655. 输出二叉树
    leetcode:763. 划分字母区间
    leetcode:3. 无重复字符的最长子串
    leetcode:2. 两数相加
    leetcode每日一题:409. 最长回文串
    leetcode:1381. 设计一个支持增量操作的栈
    leetcode:1380. 矩阵中的幸运数
    [数据结构] 迷宫问题(栈和队列,深搜和广搜)
    [数据结构] N皇后问题
    [2011山东ACM省赛] Sequence (动态规划)
  • 原文地址:https://www.cnblogs.com/tianma3798/p/4264857.html
Copyright © 2020-2023  润新知