Implement pop-up box based on HTML5 Canvas __html

Source: Internet
Author: User

The demand is common when the user moves the mouse and a pop-up box appears. This is simple when dealing with HTML element implementations, but it no longer works if you are working with a graph of HTML5 Canvas, because Canvas uses a different set of mechanisms, Canvas is a whole, no matter how many graphs are drawn on the Canvas. The graphics themselves are actually part of the canvas and cannot be obtained separately, so there is no way to add JavaScript events directly to a graphic. However, in the HT for Web, this requirement is easy to implement and the scenario is as follows:

This scenario diagram is based on the HT for Web JSON file, and there may be confusion about how to generate such a JSON file, which is based on this though small spite "HTML5 topology Editor" (http://www.hightopo.com/demo/ 2deditor_20151010/ht-2d-editor.html) has been extended to easily customize the topology editor to meet my needs. Not only that, in this demo, the definition of the three types of frame of the vector map ' tips1.json ', ' Tips2.json ', ' Tips3.json ' is through this vector editor (http://www.hightopo.com/demo/ vector-editor/index.html) is simple to draw the next, but also quite useful. In the above scenario, when the user moves the mouse into the grass and other objects, there will be a pop-up box to display its details, demo address: http://www.hightopo.com/demo/blog_meadow_20170605/index.html

Specifically implemented as follows:

preparatory work

Introduction of our HT (http://www.hightopo.com/):

<script src= ' ht.js ' ></script>

Datamodel = new ht. Datamodel ();
Graphview = new Ht.graph.GraphView (Datamodel);
Graphview.addtodom ();


HT provides a custom JSON-formatted vector description format, which is defined by the HT standard in JSON vector formats, can also be used as a picture to register and use, the HT vector is more space-saving than the traditional format, scaling is not distorted, stamping the HT for Web to learn more information. Here, register the three-shape JSON pop-up as a picture for subsequent calls:

Ht. Default.setimage (' Tips1 ', ' Symbols/tips1.json ');
Ht. Default.setimage (' tips2 ', ' Symbols/tips2.json ');
Ht. Default.setimage (' tips3 ', ' Symbols/tips3.json ');

Then get the interactive object, where the property names in each object are the label names that are set for each entity:

Tree
var trees = {
     ' tree1 ': true,
     ' tree2 ': true,
     ' tree3 ': true
};

Grassland
var grass = {
     ' Grass1 ': true,
     ' Grass2 ': true,
     ' GRASS3 ': true
 };
            
Mountain
var mountain = {
    ' mountain ': true
};


Pop-up Box

In fact, the nature of the pop-up box is a node, when the user mouse moves into the move out,

1, control node of the hidden and display can achieve the effect of the bomb frame;

2, the change of mouse position is accompanied by the change of node position;

3, the mouse moved into different objects, node on the map also followed by changes;

4, the value of the property in node also changes with the mouse position.

So, to implement the frame, you should first create a new node and set its hierarchy to ' higher ', and before that, you need to deserialize the JSON file of the scene map and set the deserialized entities to level ' lower ' to prevent being blocked by existing entities:

Ht. Default.xhrload (' Meadow.json ', function (text) {
    Const JSON = ht. Default.parse (text);                    
    if (json.title) document.title = Json.title;
    Datamodel.deserialize (JSON);

    Sets the hierarchy
    Datamodel.each (function (data) {
        data.setlayer (' lower ');
    });

    New node
    var node = new ht. Node ();                    
    NODE.S (' 2d.visible ', false);
    Node.setlayer (' higher ');
    Datamodel.add (node);

})

Then, listen to the MouseMove event on the underlying DIV, determine whether the mouse position is above the three objects, and invoke the layout () function to new layout of node according to the object type:

Graphview.getview (). AddEventListener (' MouseMove ', function (e) {
     node.s (' 2d.visible ', false);
     var hoverdata = Graphview.getdataat (e);
     pos = Graphview.getlogicalpoint (e);
     if (!hoverdata) return; 
     if (Tree[hoverdata.gettag ()]) { 
        Layout (node, POS, ' Tips1 ');
     } else if (Grass[hoverdata.gettag ())) {
        layout (node, POS, ' tips2 ');
     } else if (Mountain[hoverdata.gettag ()]) {
        Layout (node, POS, ' tips3 ');
     }
});


The layout () function has been described in detail in the previous chapter, in which the update of the property value in the frame is to bind the Text property of the JSON file to data binding, the format of the binding is very simple, just replace the previous parameter value with an object with Func attribute. There are several types of func content:

1, function type, call the function directly, and pass in related data and view object, the function return value decides parameter value, namely func (data, view);

2. String Type:

style@*** begins, returns the Data.getstyle (* *) value, where * * represents the property name of the style.

attr@*** begins, returns the Data.getattr (* *) value, where * * Represents the Attr property name.

field@*** begins, the data.*** value is returned, where * * Represents the Attr property name.

If you do not match the above, the string type is invoked directly as the function name of the data object, data*** (view), and the return value as the parameter value.

In addition to the Func property, you can set the Value property as the default value, and if the corresponding func gets a value of undefined or null, the default value defined by the Value property is used, and the details are visible in the HT for Web Data binding manual (http:// www.hightopo.com/guide/guide/core/datamodel/ht-datamodel-guide.html). For example, here, the results of data binding on sunshine values in the ' Tips1.json ' file are as follows:

"Text": {
        "func": "Attr@sunshine",
        "value": "Sunshine Value"
      },

The source code for the layout () function is attached below:


function Layout (node, POS, type) {node.s (' 2d.visible ', true);                   
                Node.setimage (type);
                    if (type = = ' Tips1 ') {node.setposition (pos.x + node.getwidth ()/2, Pos.y-node.getheight ()/2);
                        Node.a ({' Sunshine ': ' Sunshine Value: ' + (pos.x/1000). toFixed (2),
                    ' Rain ': ' Dew Value: ' + (pos.y/1000). toFixed (2), ' love ': ' Compassion value: * *
                });
                    else if (type = = ' Tips2 ') {node.setposition (pos.x, Pos.y-node.getheight ()/2); Node.a ({' temp ': ' Temperature: ', ' humidity ': ' Humidity: ' +math.
                Round (pos.x/100) + '% '});
                    else if (type = = ' tips3 ') {node.setposition (Pos.x-node.getwidth ()/2, Pos.y-node.getheight ()/2);
   Node.a ({                     ' hight ': ' Elevation: ' + math.round (pos.y) + ' m ', ' landscapes ': ' landforms:
                Karst '});
 }
            }

Cloud move

Finally, our demo also has a cloud movement animation effect, in the HT data model-driven graphical components of the design architecture, animation can be understood as some properties from the starting value gradually into the target value of the process, HT provides ht.Default.startAnim animation functions, Ht.Default.startAnim supports frame-based and time-based two ways of animating:

frame-based mode the user can control the animation effect by specifying frames animation frame number and interval animation frame interval parameter.

time-based mode the user only needs to specify the number of milliseconds for the duration animation cycle, and the HT will complete the animation within the specified time period.

For more information, see the HT for WEB.

Here we use the time-based way, the source code is as follows:


var cloud = Datamodel.getdatabytag (' cloud ');
Parent = Datamodel.getdatabytag (' mountain ');
Round1 = Parent.getposition (). X-parent.getwidth ()/2 + cloud.getwidth ()/2;
Round2 = Parent.getposition (). x + parent.getwidth ()/2-cloud.getwidth ()/2;
end = Round1;

Cloud motion animation
var animparam = {
    duration:10000,
    finishfunc:function () {End 
         = (end = = round1)? round2:round 1;
         Ht. Default.startanim (Animparam);
    },
    action:function (V, t) {
         var p = cloud.getposition ();
         Cloud.setposition (p.x + (end-p.x) * V, P.Y);
     }
;
Ht. Default.startanim (Animparam);

Finally, put on our demo for everyone's reference.







Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.