Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Erase do with HTML5 Canvas and diffusion effect     - How to use Java to read OpenOffice document (Programming)

- Increase Linux system security --chattr (Linux)

- CentOS 6 kernel upgrade to Kernel 3.x (Linux)

- CentOS7 set boot directly into the command line interface (Linux)

- 2 minutes to read large data framework Hadoop and Spark similarities and differences (Server)

- To batch create users under Linux (Linux)

- Proxmox VE implement KVM OpenVZ virtualization cloud computing (Server)

- How to use Linux to download music from Grooveshark (Linux)

- Android custom slideshow menu slidmenu (Programming)

- Zorin OS: Linux novice most personal desktop system should be used (Linux)

- DRBD rapid installation and deployment (Server)

- Servlet life cycle works (Programming)

- Several SQL Server data migration / Export Import Practice (Database)

- The top command under Linux (Linux)

- linux server security (Linux)

- How to recover deleted files in Linux systems (Linux)

- DRBD-based installation and configuration of CentOS 6.5 (Server)

- The difference between IPython and Python (Linux)

- awk Programming Model (Programming)

- How to upgrade to Ubuntu 14.04 Linux Kernel 4.4.1 LTS (Linux)

 
         
  Erase do with HTML5 Canvas and diffusion effect
     
  Add Date : 2018-11-21      
         
         
         
  2013 and they had to use canvas to achieve the effect of erasing a requirement that simulate user to erase the blurred glass mist see clear views of interactivity. Fortunately, in 2012, when the time studied learning HTML5 canvas, so in a relatively short time to achieve a program, then continue to explore further updates later in the program to improve the interactive performance, but also enhance the user experience.
Another project earlier this year, proposed a relatively similar needs, but not erase the effect, you need to disperse the haze dynamic display results on a map, this interaction needs a little difficulty, haze edges are blurred , instead of the usual kind of neat.

Here to point out, with the basic principle is to erase the canvas and visual effects opposite from the point of view of visual logic and intuition, wipe the surface image is erased and reveal the underlying pattern, but in the technology, just Instead, they need to be erased, such as blurred image is displayed directly in the glass, and after erasing the display clear pattern is drawn on it, looks like a fuzzy erased glass.

Option Two:Erase continued redraw IDEAS

  Thinking of this program is the use of canvas in the clip, the method can specify the location of a specific shape to crop a picture so that you can achieve the mask effect, because the method when invoked need to specify the location, so to achieve according to finger or mouse to dynamically specify a different location of the most direct way of thinking is the basic idea of ​​canvas animation - continued redraw, is to call the interface in a continuous cycle, the coordinates passed to the interface is the actual position of the finger.

HTML structure:

< Div>

    < Img src = "foo.jpg" style = "position: absolute; width: 100px; height: 100px; left: 0px; top: 0px;" />

    < Canvas texsrc = "foo.jpg" imgsrc = 'bar.jpg' width = "100" height = "100" style = 'position: absolute; width: 100px; height: 100px; left: 0px; top: 0px; background : transparent; '> < / canvas>

< / Div>

As can be seen from the HTML structure mentioned above: the need to be erased image (foo.jpg) is on the ground floor, while the picture is displayed after erasing (bar.jpg) is located in the upper. Because the background canvas style settings for transparent, which will deceive the user visually, it is in fact the top, but as transparent, so in addition to drawing part, the other part of the unseen, which is formed in the lower layer of illusion.

Main JS code is as follows:


function CanvasDoodle (canvas) {

        this.canvas = canvas;

        this.ctx = canvas.getContext ( "2d");

        this.imgSrc = canvas.getAttribute ( "imgsrc");

        this.width = canvas.width;

        this.height = canvas.height;

        this.left = parseInt (canvas.style.left);

        this.top = parseInt (canvas.style.top);

        this.touchX = 0;

        this.touchY = 0;

        this.requireLoop = false;

        this.init ();

    }

 

    CanvasDoodle.prototype = {

        init: function () {

            document.body.setAttribute ( "needRefresh", "true");

            var _self = this;

            this.img = new Image ();

            this.img.src = this.imgSrc;

 

            this.canvas.addEventListener ( 'mousedown', function (e) {

                e.preventDefault ();

                _self.requireLoop = true;

                _self.touchX = e.clientX-_self.left, _self.touchY = e.clientY-_self.top;

                _self.loop ();

            }, False);

 

        this.canvas.addEventListener ( 'mousemove', function (e) {

            e.preventDefault ();

            if (_self.requireLoop) {

                _self.touchX = e.clientX-_self.left, _self.touchY = e.clientY-_self.top;

            }

        }, False);

 

            this.canvas.addEventListener ( 'mouseup', function (e) {

                e.preventDefault ();

                _self.requireLoop = false;

            });

        },

        loop: function () {

            if (this.requireLoop) {

                var _self = this;

                requesetAnimFrame (function () {_self.loop ()});

                this.render ();

            }

        },

        render: function () {

            var _self = this;

            _self.ctx.save ();

            _self.ctx.beginPath ();

            _self.ctx.arc (_self.touchX, _self.touchY, 15,0, Math.PI * 2, true);

            _self.ctx.clip ();

            _self.ctx.drawImage (_self.img, 0,0, _self.width, _self.height, 0,0, _self.width, _self.height);

            _self.ctx.restore ();

        }

    };

    new CanvasDoodle (document.getElementById ( 'CanvasDoodle'));

Code is relatively simple, the core part is the render method to draw a circle in the context of the canvas or the current mouse position of the finger, then crop, this will draw a circular pattern next drawImage local time rather than in the context the whole picture. This will draw a lot of small round dynamics in a mouse or finger movement, when put together like erased.

requesetAnimFrame I believe we will not be unfamiliar, it is a cycle call. Here to save the performance, set a variable to indicate whether requireLoop need to redraw only the mouse or pressing the finger contact when set to true, each cycle begins redraw the canvas (that is, calls render), the end of the set to false, stop drawing.

This program is the most primitive program, there are two major drawbacks:

The first cycle is called, although one can determine whether requireLoop redraw, when the interaction happens always in the loop, the performance is not good;

Second cycle call and user interaction speed is not synchronized, the ideal situation is changing every finger or mouse to redraw once, but the reality is not the case, in a very rapid slide, when the coordinates of each acquired dynamically not tightly connected on erasable effect is not continuous, the experience will be worse.

Option Two: No more loops

A program may be the most obvious point is the optimization cycle, its two defects are based on this. Therefore, the main idea of ​​the program two abandoned clip method. But to use the canvas context strokeStyle property, which refers to the drawing styles to draw vector graphics in the canvas when the vector line, which value can be color (color value), gradient (gradient objects), pattern (pattern objects). This program is a program to change the way the canvas drawImg context strokeStyle set to Picture, and then draw a line straight as you draw on it, because the background is the vector line need to show a picture, so to achieve erasure Effect. HTML structure unchanged, JS code is as follows:

function CanvasDoodle (canvas) {
        this.canvas = canvas;
        this.ctx = canvas.getContext ( "2d");
        this.imgSrc = canvas.getAttribute ( "imgsrc");
        this.width = canvas.width;
        this.height = canvas.height;
        this.left = parseInt (canvas.style.left);
        this.top = parseInt (canvas.style.top);
        this.touchX = 0;
        this.touchY = 0;
        this.needDraw = false;
        this.init ();
    }

    CanvasDoodle.prototype = {
        init: function () {
            var _self = this;

            var img = new Image ();
            img.onload = function () {
                var pat = _self.ctx.createPattern (img, "no-repeat");
                _self.ctx.strokeStyle = pat;
                _self.ctx.lineCap = "round";
                _self.ctx.lineJoin = "round";
                _self.ctx.lineWidth = "25";
            }
            img.src = this.imgSrc;
        this.canvas.addEventListener ( 'mousedown', function (e) {
                e.preventDefault ();
                _self.needDraw = true;
                
                _self.ctx.beginPath ();
                _self.ctx.moveTo (e.clientX-_self.left, e.clientY-_self.top);
            }, False);

        this.canvas.addEventListener ( 'mousemove', function (e) {
            e.preventDefault ();
            if (_self.needDraw) {
                _self.ctx.lineTo (e.clientX-_self.left, e.clientY-_self.top);
                _self.ctx.stroke ();
            }
        }, False);

            this.canvas.addEventListener ( 'mouseup', function (e) {
                e.preventDefault ();
                _self.needDraw = false;
            });

        }
    };
    new CanvasDoodle (document.getElementById ( 'CanvasDoodle'));

You can see, has no cycle call, and only when it is set in the initialization strokeStyle a picture, move the mouse directly when lineTo then stroke it, that is simple and efficient, and even fast-moving the mouse does not appear jagged edge, so this improved scheme completely replace a program.

New needs, new solutions

I believe this should be the beginning of haze including women and children, since a former CCTV reporter at their own expense to do a long-term investigation and made a speech, set off a firestorm. This requirement is in this period presented. I want to dynamically display disperse haze effect on the map.

Let's simply point

Here, we first analyze another slightly simpler needs, step by step.

That alterations are required to show haze diffusion effect, this would be relatively easy to implement, because the haze can be understood as a uniform gray, if not uniform, can also be expressed as from the center to the edge of the shades of gray gradient, spoke of canvas above the strokeStyle gradient can be set, so you can just use a gradient fuzzy edges. (And also to animate the canvas several css3, such as from small to large, from dark or bright).

HTML structure is essentially the same, the main JS code is as follows:

function CanvasFade (canvas) {
    this.canvas = canvas;
    this.ctx = canvas.getContext ( "2d");
    this.width = canvas.width;
    this.height = canvas.height;
}

CanvasFade.prototype = {
    draw: function (config) {
        var _self = this;
        var cfg = config config: {x: 200, y: 200, r: 120};?
        var ratio = cfg.r / 2;
        var grd = _self.ctx.createRadialGradient (cfg.x, cfg.y, 0.000, cfg.x, cfg.y, cfg.r);
        grd.addColorStop (0.000, 'rgba (255, 0, 0, 0.900)');
        grd.addColorStop (0.5, 'rgba (255, 0, 0, 0.600)');
        grd.addColorStop (1.0, 'rgba (255, 0, 0, 0.000)');
        _self.ctx.fillStyle = grd;
        _self.ctx.arc (cfg.x, cfg.y, cfg.r, 0, Math.PI * 2, true);
        _self.ctx.fill ();
    }
};
var canvasFade = new CanvasFade (Jquery ( '# theCanvas') [0]);
canvasFade.draw ({x: 100, y: 200y, r: 20r});

It can be seen very simple to implement, this code is used for testing the color value is red, it looks like the hot zone map, to achieve haze diffusion only need to change the color values

Unyielding person

Only from the visual point of view, these two requirements are very close, so it is easy to mistake the target will be realized. Program development is a major feature [There is more to it then meets the eyes]. Those looks very cool interactions for developers can be very easy to implement, because vendors may have realized at the bottom. Those seemingly simple thing, you may need to spend more effort, which often become a reason for personnel and product developers friction.

We analyze the needs of haze covering itself on the map, not even (of course, can also be reduced to a uniform, this is not the main difficulty points), the main problem is displayed after the haze to disperse the haze does not cover map instead of pure color (you can see the end the gif image). Blur the edges is difficult to achieve, because the set strokeStyle time, if you set the color for the gradient, it is easy to realize edge blur, but you can only use the color values, if strokeStyle set pattern, you can use pictures, but then would not be able to set the gradient, the edge is neatly cut, can not meet demand, and after repeated attempts to help google, finally found a clue on stackoverflow, it seems to have a foreign man also hit a similar demand, but he was very strokeStyle cleverly bypass this problem, so the final implementation is inspired by his realization, not by me original.

Look at the code:

function clipArc (ctx, x, y, r, f) {
    var temp = document.createElement ( 'canvas'),
        tx = temp.getContext ( '2d');
    temp.width = ctx.canvas.width;
    temp.height = ctx.canvas.height;
    tx.translate (-temp.width, 0);
    tx.shadowOffsetX = temp.width;
    tx.shadowOffsetY = 0;
    tx.shadowColor = '# 000';

    tx.shadowBlur = f;
    tx.arc (x, y, r, 0, 2 * Math.PI);
    tx.closePath ();
    tx.fill ();

    ctx.save ();
    ctx.globalCompositeOperation = 'destination-in';
    ctx.drawImage (temp, 0, 0);
    ctx.restore ();
}

function CanvasFade (canvas) {
    this.canvas = canvas;
    this.ctx = canvas.getContext ( "2d");
    this.imgSrc = canvas.getAttribute ( "imgSrc");
    this.width = canvas.width;
    this.height = canvas.height;
}

CanvasFade.prototype = {
    init: function (config) {
        var _self = this;
        var cfg = config config: {x: 100, y: 100, r: 120, f: 40}?;
        var img = new Image ();
        img.onload = function () {
            var pat = _self.ctx.createPattern (img, "no-repeat");
            _self.ctx.fillStyle = pat;
            _self.ctx.fillRect (0, 0, _self.width, _self.height);
            clipArc (_self.ctx, cfg.x, cfg.y, cfg.r, cfg.f);
        };
        img.src = this.imgSrc;
    }
};
var c = document.querySelector ( '# theCanvas');
var cf = new CanvasFade (c);
cf.init ();

Here's the secret weapon is the use of shadow, a shadow that is, inside the canvas to draw graphics, they can add shadows to graphics, and shadows may have blurred edge effect. Here in the actual drawing, create a transitional canvas (the canvas itself does not draw graphics, mainly from shearing blur effect), pan left to the canvas with a width so that it can be moved out of the current canvas depending on the range, but the subtlety is that it is right to set the context shadowOffsetX a width so that the shadows inside any pattern just falls on the correct position of the current canvas, where it set up a shadow color is black, but there are certain the feathering (tx.shadowBlur = f), another secret weapon is globalCompositeOperation, this attribute is used to set how to source a (new) image is rendered to the target (existing) on ​​the image

You can see the actual effect is still very good. And animated form can be more diverse, and this form can also have more varieties to meet a wider range of needs.
     
         
         
         
  More:      
 
- J2EE Example of Filter (Programming)
- HTML5 Fundamentals study notes (Programming)
- VMware virtual machines to install virt-manager unable to connect to libvirt's approach (Linux)
- Do not find ifconfig eth0 and IP address under CentOS6.5 (Linux)
- Install Redis 2.6 5.5 32 position CentOS error resolved (Linux)
- MySQL Data Types (Database)
- Linux foundation tutorial: how to modify the host name on CentOS or RHEL 7 (Linux)
- Oracle metadata Reconstruction experiments (Database)
- Using Python to find a particular file extension directory (Programming)
- Linux Demo dd IO test (Linux)
- Sublime Text 3 best features, plug-ins and settings (Linux)
- Docker Basic and Advanced (Linux)
- Linux rights management (Linux)
- Replace element and non-replaced elements of learning (Programming)
- CentOS7 method to upgrade the kernel to 3.18 (Linux)
- Radius server setup under CentOS (Server)
- Differential test piece using MongoDB performance YCSB (Database)
- Use IF NOT EXISTS create a data table (Database)
- Wi-Fi hackers use to attack your seven methods (Linux)
- Linux System Getting Started Learning: Disable HTTP forwarding wget in (Linux)
     
           
     
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.