【问题标题】:FadeOut Tv Noise in Canvas after timeout超时后在画布中淡出电视噪声
【发布时间】:2017-09-26 05:46:06
【问题描述】:

我想在一段时间后以更平滑的过渡淡出电视噪音。是否有可能淡出噪音。 我发布的代码已经存在于 stakcoverflow https://stackoverflow.com/a/22085531/7935298

var canvas = document.getElementById('canvas'),
      ctx = canvas.getContext('2d');

  // closer to analouge appearance
  canvas.width = canvas.height = 256;

  function resize() {
      canvas.style.width = window.innerWidth + 'px';
      canvas.style.height = window.innerHeight + 'px';
  }
  resize();
  window.onresize = resize;

  function noise(ctx) {

      var w = ctx.canvas.width,
          h = ctx.canvas.height,
          idata = ctx.createImageData(w, h),
          buffer32 = new Uint32Array(idata.data.buffer),
          len = buffer32.length,
          run = 0,
          color = 10,
          m = Math.random() * 6 + 4,
          band = Math.random() * 256 * 256,
          p = 0,
          i = 0;

      for (; i < len;) {
          if (run < 0) {
              run = m * Math.random();
              p = Math.pow(Math.random(), 0.1);
              if (i > band && i < band + 48 * 256) {
                  p = Math.random();
              }
              color = (255 * p) << 25;
          }
          run -= 1;
          buffer32[i++] = color;
      }

      ctx.putImageData(idata, 0, 0);
  }

  var frame = 0;

  // added toggle to get 30 FPS instead of 60 FPS
  (function loop() {
      frame += 1;
      if (frame % 3) {
          requestAnimationFrame(loop);
          return;
      }
      noise(ctx);
      requestAnimationFrame(loop);
  })();
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    为视频添加噪点。

    是的,可以淡出一些噪音。

    使用 ctx.globalAlpha 混合噪声。由于噪声影响帧内容,您应该将噪声作为双通道进行。使用ctx.globalCompositeOperation="multiply" 后,会为现有像素添加噪点,使用ctx.globalCompositeOperation="source-over" 会降低噪点的饱和度。对于良好的高速噪声 FX,我预先计算带有一点色度噪声的噪声,然后从噪声阵列中切割随机部分以填充像素数据阵列。由于老式噪点通常沿 x 方向被拉出一点(并且为了减少 CPU 负载),我以画布分辨率的 1/3 来创建噪点并拉伸噪点以适应。这会给噪音 FX 带来更好的感觉。

    噪声函数

    以下将为画布添加噪点(假设视频已经渲染到画布上。第一个参数是您想要的噪点量。0 无噪点和 1 完全噪点。

        // following variable are set when noise function first called.
        var canvasNoise; // canvas to hold the noise
        var ctxNoise;    // context of above canvas
        var rawPixels;   // pixel image data
        var rawPixel32Arr;  // pixel image data as 32bit array
        var randomPix;    // array of precalculated noise.
    
       // FXMix the amount of noise to add 0 no noise 1 full noise
       function noise(FXMix) {
            var i,d;
            // if noise canvas not created create it now
            if(canvasNoise === undefined){
                canvasNoise = document.createElement("canvas");
                canvasNoise.width = Math.floor(canvas.width / 3);
                canvasNoise.height = canvas.height;
                ctxNoise = canvasNoise.getContext("2d");
                rawPixels = ctxNoise.createImageData(canvasNoise.width, canvasNoise.height);
                rawPixel32Arr = new Uint32Array(rawPixels.data.buffer);
                // create array of random noise
                randomPix = new Uint32Array(canvasNoise.width * 10);
                i = canvasNoise.width * 10;
                d = randomPix; // alias to make code readable
                while(i--){
                    var r = Math.floor(Math.random() * 255);
                    // create slight croma noise
                    var g = Math.min(255, Math.max(0,Math.floor(r + (Math.random()-0.5) * 32)));
                    var b = Math.min(255, Math.max(0,Math.floor(r + (Math.random()-0.5) * 32)));
    
                    d[i] = 0xFF000000 + (r<<16) + (g<<8) + b;
                }
            }
            // fill the pixel data with random noise from the randomPix array
            i = rawPixel32Arr.length;
            d = rawPixel32Arr; // alias to make code readable
            while(i){
                var len = Math.floor(Math.random() * 100) + 20;
                var start = Math.floor(Math.random() * randomPix.length - len);
                i -= len;
                i = i < 0 ? 0 : i;
                d.set(randomPix.subarray(start,start + len), i);
            }
            // put noise onto canvas
            ctxNoise.putImageData(rawPixels, 0, 0);
    
            // now mix noise over video 
            ctx.globalAlpha = FXMix;
            ctx.globalCompositeOperation = "multiply"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalCompositeOperation = "source-over"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalAlpha = 1;
        }
    

    演示。

    以下演示是对我在回答Fade from black & white to color 时使用的现有演示的更新如果您将鼠标悬停在视频底部,则可以通过混合滑块控制噪音。

    FX 只是对上述 sn-p 函数噪声的轻微修改。

    更新我添加了第二个噪波,它使用第 3 层(使用 ctx.globalCompositeOperation = "lighter" 绘制噪波画布,通过添加乘法运算删除的内容来保持总亮度水平一致。有关详细信息,请参阅噪波函数. 并修复了由于 FX 列表太长和 FX 混合滑块妨碍底部过滤器的过滤器选择错误。

    视频署名可以在视频的开头和结尾标题/字幕中找到(由作者指定)

        //==========================================================================
        // start canvas animation after all the code below has been parsed and executed
        setTimeout(()=>requestAnimationFrame(updateCanvas),0);
        //==========================================================================
        // UI variables
        var showFXName = 0;
        var cursor = "default";
        var overUI = false;
        var sliderAlpha = 1;
        var listAlpha = 1;
        var dragging = false;
        var listWidth = null;
        var playClick = false;
    
    
        //==========================================================================
        // Media setup
        
        var mediaSource = "http://video.webmfiles.org/big-buck-bunny_trailer.webm";
        var mediaSource = "http://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv";
        var muted = true;
        var canvas = document.getElementById("myCanvas"); // get the canvas from the page
        var ctx = canvas.getContext("2d");
        var videoContainer; // object to hold video and associated info
        var video = document.createElement("video"); // create a video element
        video.src = mediaSource;
        // the video will now begin to load.
        // As some additional info is needed we will place the video in a
        // containing object for convenience
        video.autoPlay = false; // ensure that the video does not auto play
        video.loop = true; // set the video to loop.
        video.muted = muted;
        videoContainer = {  // we will add properties as needed
             video : video,
             ready : false,   
        };
        // To handle errors. This is not part of the example at the moment. Just fixing for Edge that did not like the ogv format video
        video.onerror = function(e){
            document.body.removeChild(canvas);
            document.body.innerHTML += "<h2>There is a problem loading the video</h2><br>";
            document.body.innerHTML += "Users of IE9+ , the browser does not support WebM videos used by this demo";
            document.body.innerHTML += "<br><a href='https://tools.google.com/dlpage/webmmf/'> Download IE9+ WebM support</a> from tools.google.com<br> this includes Edge and Windows 10";
            
         }
        video.oncanplay = readyToPlayVideo; // set the event to the play function that 
                                          // can be found below
        //==========================================================================
        var FXMix = 1;
        var FX = {}
        var FXList = [];
        var currentFX = "";
        var animateFXMix = false; // if true thr FXMix is animated over time. This flag is cleared to false once a frame
    
    
        //==========================================================================
        // Mix noise variables. Created when filter first used.
        var canvasNoise;
        var ctxNoise;
        var rawPixels;
        var rawPixel32Arr;
        
        //==========================================================================
        // Mix function are in this section
        function addOverlay(type){
            if(FXMix > 0){
                ctx.globalCompositeOperation = type; 
                ctx.globalAlpha = FXMix;
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.globalAlpha = 1;
                ctx.globalCompositeOperation = "source-over"; 
            }
        }
        function addMix(type,video){
            if(FXMix > 0){
                ctx.globalCompositeOperation = type; 
                ctx.globalAlpha = FXMix;
                ctx.drawImage(video,0, 0, canvas.width, canvas.height);
                ctx.globalAlpha = 1;
                ctx.globalCompositeOperation = "source-over"; 
            }
        }
        function fill(style){  // draws a rectangle over the canvas using style as the colour
            ctx.globalAlpha = FXMix;
            ctx.fillStyle = style;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.globalAlpha = 1;
        }
        function mask(direction){
            ctx.globalCompositeOperation = "destination-in"; 
            ctx.fillStyle = "black";
            ctx.globalAlpha = 1;
            if(direction === "Vertical"){
                ctx.fillRect(0, 0, canvas.width, canvas.height * FXMix);
            }else if(direction === "Horizontal"){
                ctx.fillRect(0, 0, canvas.width  * FXMix, canvas.height);
            }
            ctx.globalCompositeOperation = "destination-atop"; 
            // assuming bacground is black. But you could use anything including a second video
            // using "destination-atop" only draws on transparent pixels.
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.globalCompositeOperation = "source-over"; 
        }
        function glowBar(RGB, direction){ // RGB is array of channel values 0-255
            var grad;
            var col = "rgba("+RGB[0]+","+RGB[1]+","+RGB[2]+",";
            if(direction === "Vertical"){
                grad = ctx.createLinearGradient(0,0,0,canvas.height * 0.1);
            }else if(direction === "Horizontal"){
                grad = ctx.createLinearGradient(0,0,canvas.width * 0.1,0);
            }
            grad.addColorStop(0.0, col + "0.0)");
            grad.addColorStop(0.3, col + "0.8)");
            grad.addColorStop(0.4, col + "1.0)");
            grad.addColorStop(0.6, col + "1.0)");
            grad.addColorStop(0.7, col + "0.8)");
            grad.addColorStop(1.0, col + "0.0)");
            ctx.fillStyle = grad;
            if(direction === "Vertical"){
                ctx.setTransform(1,0,0,1,0,canvas.height * FXMix - canvas.height * 0.05);
                ctx.fillRect(0, 0, canvas.width, canvas.height * 0.1);
                ctx.setTransform(1,0,0,1.1,0,canvas.height * FXMix -canvas.height * 0.05 * 1.1 );
                ctx.globalCompositeOperation = "lighter"; 
                ctx.fillRect(0, 0, canvas.width, canvas.height * 0.1);
            }else if(direction === "Horizontal"){
                ctx.setTransform(1,0,0,1,canvas.width * FXMix -canvas.width * 0.05, 0);
                ctx.fillRect(0, 0, canvas.width * 0.1, canvas.height);
                ctx.setTransform(1.1,0,0,1,canvas.width * FXMix -canvas.width * 0.05 * 1.1, 0);
                ctx.globalCompositeOperation = "lighter"; 
                ctx.fillRect(0, 0, canvas.width * 0.1, canvas.height);
            }
            ctx.globalCompositeOperation = "source-over"; 
            ctx.setTransform(1,0,0,1,0,0);
        }
    
    
        
        function noise(type) {
            var i,d;
            if(canvasNoise === undefined){
                canvasNoise = document.createElement("canvas");
                canvasNoise.width = Math.floor(canvas.width / 3);
                canvasNoise.height = canvas.height;
                ctxNoise = canvasNoise.getContext("2d");
                rawPixels = ctxNoise.createImageData(canvasNoise.width, canvasNoise.height);
                rawPixel32Arr = new Uint32Array(rawPixels.data.buffer);
                randomPix = new Uint32Array(canvasNoise.width * 10);
                i = canvasNoise.width * 10;
                d = randomPix; // alias to make code readable
                while(i--){
                    var r = Math.floor(Math.random() * 255);
                    // create slight croma noise
                    var g = Math.min(255, Math.max(0,Math.floor(r + (Math.random()-0.5) * 32)));
                    var b = Math.min(255, Math.max(0,Math.floor(r + (Math.random()-0.5) * 32)));
    
                    d[i] = 0xFF000000 + (r<<16) + (g<<8) + b;
                }
            }
            i = rawPixel32Arr.length;
            d = rawPixel32Arr; // alias to make code readable
            while(i){
                var len = Math.floor(Math.random() * 100) + 20;
                var start = Math.floor(Math.random() * randomPix.length - len);
                i -= len;
                i = i < 0 ? 0 : i;
                d.set(randomPix.subarray(start,start + len), i);
            }
    
            ctxNoise.putImageData(rawPixels, 0, 0);
        if(type === "Addative"){
            ctx.globalAlpha = FXMix;
            ctx.globalCompositeOperation = "multiply"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalCompositeOperation = "lighter"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalCompositeOperation = "source-over"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalAlpha = 1;
            
            
        }else{
            ctx.globalAlpha = FXMix;
            ctx.globalCompositeOperation = "multiply"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalCompositeOperation = "source-over"; 
            ctx.drawImage(canvasNoise,0,0,canvas.width,canvas.height)
            ctx.globalAlpha = 1;
        }
        }
        function addFX(name, func) {
            FXList.push(name);
            FX[name] = func;
            currentFX = name;
        }
    
        //==========================================================================
        // avialable composite operations 
        // multiply,screen,overlay,color-dodge,color-burn,hard-light,soft-light,difference,
        // exclusion,hue,saturation,color,luminosity
        addFX("Noise",       (vid)=>{ noise() })
        addFX("Noise 2",       (vid)=>{ noise("Addative") })
        addFX("V scanner",   (vid)=>{ animateFXMix = true; mask("Vertical"); glowBar([100,200,255], "Vertical") })
        addFX("H scanner",   (vid)=>{ animateFXMix = true; mask("Horizontal"); glowBar([100,255,200], "Horizontal") })
        addFX("Ligher",      (vid)=>{ addMix("lighter",vid) } );
        addFX("Ligher+",     (vid)=>{ addMix("lighter", vid); addMix("lighter",vid); addMix("lighter", vid) } );
        addFX("Darken",      (vid)=>{ addMix("multiply", vid) } );
        addFX("Darken+",     (vid)=>{ addMix("multiply", vid); addMix("multiply",vid); addMix("multiply", vid) } );
        addFX("Saturate",    ()   =>{ ctx.fillStyle = "#F00"; addOverlay("saturation") });
        addFX("Negative",    (vid)=>{ ctx.fillStyle = "#FFF"; addOverlay("difference") } );
        addFX("Sepia",       (vid)=>{ fill("#F94"); addMix("luminosity", vid) } );
        addFX("BlackWhite",  (vid)=>{ ctx.fillStyle = "#888"; addOverlay("color") } );
        addFX("B&W Negative",(vid)=>{ ctx.fillStyle = "#FFF";   addOverlay("difference"); ctx.fillStyle = "#888"; addOverlay("color") } );
        addFX("B&W Lighten", (vid)=>{ addMix("lighter", vid); ctx.fillStyle = "#888"; addOverlay("color") } );
        addFX("None",        ()   =>{});
    
        // end of FX mixing
        //==========================================================================
    
    
        function readyToPlayVideo(event){ // this is a referance to the video
            // the video may not match the canvas size so find a scale to fit
            videoContainer.scale = Math.min(
                                 canvas.width / this.videoWidth, 
                                 canvas.height / this.videoHeight); 
            videoContainer.ready = true;
            // the video can be played so hand it off to the display function
    
            // add instruction
            document.getElementById("playPause").textContent = "Click video to play/pause.";
            document.querySelector(".mute").textContent = "Mute";
        }
        function updateCanvas(time){
            ctx.fillStyle = "#222";
            ctx.fillRect(0,0,canvas.width,canvas.height)
            // only draw if loaded and ready
            if(videoContainer !== undefined && videoContainer.ready){ 
                // find the top left of the video on the canvas
                video.muted = muted;
                var scale = videoContainer.scale;
                var vidH = videoContainer.video.videoHeight;
                var vidW = videoContainer.video.videoWidth;
                var top = canvas.height / 2 - (vidH /2 ) * scale;
                var left = canvas.width / 2 - (vidW /2 ) * scale;
                // now just draw the video the correct size
                ctx.drawImage(videoContainer.video, left, top, vidW * scale, vidH * scale);
                FX[currentFX](videoContainer.video);
                if(videoContainer.video.paused){ // if not playing show the paused screen 
                    drawPayIcon();
                }
                overUI = false;
                cursor = "default";
                drawSlider();
                drawList();
                if(mouse.over){
                    if(!overUI){
                        if((mouse.button&1)===1){ // bit field
                            playClick = true;
                        }
                        if((mouse.button&1)===0 && playClick){ // bit field
                            playClick = false;
                            playPauseClick();
                        }
                        cursor = "pointer";
                    }
                }
                if(showFXName > 0){
                    showFXName = Math.max(0,showFXName - 0.05);
                    ctx.globalAlpha = Math.min(1,showFXName);
                    ctx.font = "32px Arial";
                    ctx.textAlign = "center";
                    ctx.textbaseLine = "middle";
                    ctx.fillStyle = "white";
                    ctx.strokeStyle = "black";
                    ctx.lineJoin = "round"
                    ctx.strokeText(currentFX,canvas.width/2,canvas.height/2);
                    ctx.fillText(currentFX,canvas.width/2,canvas.height/2);
                    ctx.globalAlpha = 1;
                }
                canvas.style.cursor = cursor;
                if(animateFXMix){
                    FXMix = Math.sin(time / 400) * 0.5 + 0.5;
                    FXMix = FXMix < 0 ? 0 : FXMix > 1 ? 1 : FXMix; // Clamp to 0-1 or may get flicker on some FX
                    
                    animateFXMix = false;
                }
            }else{
                drawLoadingAnim(time);
            }
            // all done for display 
            // request the next frame in 1/60th of a second
            requestAnimationFrame(updateCanvas);
        }
        function getMaxListWidth(){
            ctx.font = "12px arial";
            FXList.forEach(text => {listWidth = Math.max(listWidth,ctx.measureText(text).width)})
        }
    
        function drawList(){
            if(listWidth === null){
                getMaxListWidth();
                listWidth += 10;
            }
            if(!overUI && mouse.over && mouse.x > canvas.width - listWidth){
                listAlpha = 1;
                overUI = true;
            }else{
                listAlpha = Math.max(0,listAlpha - 0.05);
            }
            if(listAlpha > 0){
                ctx.font = "12px arial";
                var textH = 14;
                var border = 10;
                ctx.textAlign = "right";
                ctx.textBaseline = "middle";
                ctx.globalAlpha = listAlpha;
                 ctx.fillStyle = "black";
                 ctx.strokeStyle = "white";        
                var len = FXList.length;
                var h = len * textH;
                var y = canvas.height / 2 - h/2;
                var x = canvas.width - border * 2;
                ctx.fillRect(x - listWidth,y - border, listWidth+border,h + border );
                ctx.strokeRect(x - listWidth,y - border, listWidth + border,h + border );
                ctx.fillStyle = "white"
                for(var i = 0; i < len; i ++){
                    var yy = y + i * textH;
                    if(FXList[i] === currentFX){
                        ctx.fillStyle = "#0FF";
                        ctx.fillText(FXList[i],x,yy);
                        ctx.fillStyle = "white"
                    }else
                    if(mouse.x > canvas.width - listWidth && mouse.y > yy - textH/2 && mouse.y < yy + textH /2){
                        ctx.fillStyle = "#0F0";
                        ctx.fillText(FXList[i],x,yy);
                        ctx.fillStyle = "white"
                        cursor = "pointer";
                        if((mouse.button & 1) === 1){
                            currentFX =FXList[i];
                            showFXName = 4;
                        }
                    }else{
                        ctx.fillText(FXList[i],x,yy);
                    }
                }
                ctx.globalAlpha = 1;
            }
        }
    
        function drawSlider(){
            if(currentFX === "None"){
                sliderAlpha = 0;
                return;
            }
            if(dragging){
                animateFXMix = false;  // dont animate if slider being dragged
            }
            var cw = canvas.width;
            var ch = canvas.height;
            var handle = 5;
            var inset = 10
            var x = inset;
            var w = cw - inset*2;
            var h = 20;
            var y = ch - inset - h;
            var pos =  FXMix * w + x;;
            if(mouse.y > y - h* 1.2){
                cursor = "e-resize";
                overUI = true;
                if((mouse.button&1) && !dragging){  // bit field
                    dragging = true;
                }
            }else{
                cursor = "pointer";
            }
            if(dragging){
                overUI = true;
                cursor = "e-resize";
                sliderAlpha = 1;
                pos = mouse.x - x;
                FXMix = Math.min(1,Math.max(0,pos / w));
                if( (mouse.button&1) === 0 ){ //bit field
                    dragging = false;
                }
            }
            if(!dragging && mouse.y > y-h*2 && mouse.over){
                sliderAlpha = 1;
            }else{
                if(sliderAlpha > 0){
                    sliderAlpha = Math.max(0,sliderAlpha- 0.05);
                }
            }
            if(sliderAlpha === 0){
                return;
            }
            ctx.globalAlpha =  sliderAlpha;
            ctx.font = "18px arial";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            var amount = FXMix;
            ctx.fillStyle = "black";
            ctx.strokeStyle = "white";
            ctx.fillRect(x,y,w,h);
            ctx.strokeRect(x,y,w,h);
            ctx.fillStyle = "white";
            ctx.fillText(currentFX + " "+ (FXMix * 100).toFixed(0)+"%",w/2,y + h / 2);
            pos = amount * w + x;
            ctx.fillStyle = "white";
            ctx.strokeStyle = "black";
            ctx.fillRect(pos-handle*2,y-handle,handle* 4,h + handle * 2);
            ctx.strokeRect(pos-handle*2,y-handle,handle* 4,h + handle * 2);
            ctx.strokeRect(pos-1,y-handle * 0.5,2,h + handle);
            ctx.globalAlpha =  1;
        }
        function drawPayIcon(){
             ctx.fillStyle = "#DDD"; // colour of play icon
             ctx.globalAlpha = 0.75; // partly transparent
             ctx.beginPath(); // create the path for the icon
             var size = (canvas.height / 2) * 0.5;  // the size of the icon
             ctx.moveTo(canvas.width/2 + size/2, canvas.height / 2); // start at the pointy end
             ctx.lineTo(canvas.width/2 - size/2, canvas.height / 2 + size);
             ctx.lineTo(canvas.width/2 - size/2, canvas.height / 2 - size);
             ctx.closePath();
             ctx.fill();
             ctx.globalAlpha = 1; // restore alpha
        }
        function drawLoadingAnim(time){
             ctx.strokeStyle = "#8DF"; // colour of play icon
             ctx.lineCap = "round";
             ctx.globalAlpha = 0.75; // partly transparent
             ctx.lineWidth = 6;
             ctx.beginPath(); // create the path for the icon
             var size = (canvas.height / 2) * 0.5;  // the size of the icon
             ctx.arc(canvas.width / 2 , canvas.height / 2, size, time / 100, time / 100 + 2);
             ctx.stroke();
             ctx.lineWidth = 1;
             ctx.globalAlpha = 1; // restore alpha
            
        }
    
    
        mouse = (function(){
            var mouse = {
                x : 0, y : 0, w : 0, 
                button : 0,
                over : false,
                bm : [1, 2, 4, 6, 5, 3], 
                active : false,
                bounds : null, 
                border : {top : 10, left : 10},
                mouseEvents : "mousemove,mousedown,mouseup,mouseout,mouseover,contextmenu".split(",")
            };
            var m = mouse;
            function mouseMove(e) {
                var t = e.type;
                m.bounds = m.element.getBoundingClientRect();
                m.x = e.clientX - m.bounds.left - m.border.left; 
                m.y = e.clientY - m.bounds.top - m.border.top;
                
                if (t === "mousedown") { 
                    m.button |= m.bm[e.which-1]; 
                } else if (t === "mouseup") { 
                    m.button &= m.bm[e.which + 2]; 
                }else if (t === "mouseout") { 
                    m.button = 0; 
                    m.over = false; 
                }else if (t === "mouseover") { 
                    m.over = true; 
                }
                e.preventDefault();
            }
            m.start = function (element) {
                m.element = element;
                m.mouseEvents.forEach( n => { m.element.addEventListener(n, mouseMove); } );
                m.active = true;
                //m.border.top = Number(element.style.borderTopWidth.replace(/[a-zA-Z]/g,""));
                //m.border.left = Number(element.style.borderLeftWidth.replace(/[a-zA-Z]/g,""));
            }
            m.remove = function () {
                if (m.element !== undefined) {
                    m.mouseEvents.forEach(n => { m.element.removeEventListener(n, mouseMove); } );
                    m.active = false;
                    m.element = undefined;
                }
            }
            return mouse;
        })();
    
    
    
    
        function playPauseClick(){
             if(videoContainer !== undefined && videoContainer.ready){
                  if(videoContainer.video.paused){                                 
                        videoContainer.video.play();
                  }else{
                        videoContainer.video.pause();
                  }
             }
        }
        function videoMute(){
            muted = !muted;
        	if(muted){
                 document.querySelector(".mute").textContent = "Mute";
            }else{
                 document.querySelector(".mute").textContent= "Sound on";
            }
    
    
        }
        // register the event
        //canvas.addEventListener("click",playPauseClick);
        document.querySelector(".mute").addEventListener("click",videoMute)
        setTimeout(()=>{mouse.start(canvas)},100);
        body {
            font :14px  arial;
            text-align : center;
            background : #36A;
        }
        h2 {
            color : white;
        }
        canvas {
            border : 10px white solid;
            cursor : pointer;
        }
        a {
          color : #F93;
        }
        .mute {
            cursor : pointer;
            display: initial;   
        }
        <h2>Simple video FX via canvas "globalCompositeOperation"</h2>
        <p>This example show how to use the 2d context "globalCompositeOperation" property to create a variety of FX. Video may take a few moment to load.
        </p>
        <p>Play pause video with click. Move to bottom of video to see FX mix slider (Not available if filter None). Move to right to get filter selection and select the filter example. Happy filtering</p>
        <canvas id="myCanvas" width = "532" height ="300" ></canvas><br>
        <h3><div id = "playPause">Loading content.</div></h3>
        <div class="mute"></div><br>

    【讨论】:

      猜你喜欢
      • 2014-03-27
      • 2014-08-07
      • 2016-02-07
      • 1970-01-01
      • 2013-02-26
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      相关资源
      最近更新 更多