svghmi/widget_slider.ysl2
branchsvghmi
changeset 3024 0a9f6f29b7dd
parent 3021 49799de67540
child 3045 f6d428330e04
equal deleted inserted replaced
3023:407a0205405a 3024:0a9f6f29b7dd
       
     1 // widget_slider.ysl2
       
     2 
       
     3 template "widget[@type='Slider']", mode="widget_class"
       
     4     ||
       
     5     class SliderWidget extends Widget{
       
     6         frequency = 5;
       
     7         range = undefined;
       
     8         fi = undefined;
       
     9         drag = false;
       
    10         enTimer = false;
       
    11 
       
    12         dispatch(value) {
       
    13             if(this.value_elt)
       
    14                 this.value_elt.textContent = String(value);
       
    15 
       
    16             this.update_DOM(value, this.handle_elt);
       
    17 
       
    18         }
       
    19 
       
    20         last_drag = false;
       
    21 
       
    22         update_DOM(value, elt){
       
    23             let [min,max,start,totallength] = this.range;
       
    24             let length = Math.max(0,Math.min(totallength,(Number(value)-min)*totallength/(max-min)));
       
    25             let tip = this.range_elt.getPointAtLength(length);
       
    26             elt.setAttribute('transform',"translate("+(tip.x-start.x)+","+(tip.y-start.y)+")");
       
    27 
       
    28             if(this.setpoint_elt != undefined){
       
    29                 if(this.last_drag!= this.drag){
       
    30                     if(this.drag){
       
    31                         this.setpoint_elt.setAttribute("style", this.setpoint_style);
       
    32                     }else{
       
    33                         this.setpoint_elt.setAttribute("style", "display:none");
       
    34                     }
       
    35                     this.last_drag = this.drag;
       
    36                 }
       
    37             }
       
    38         }
       
    39 
       
    40         on_release(evt) {
       
    41             window.removeEventListener("touchmove", this.on_bound_drag, true);
       
    42             window.removeEventListener("mousemove", this.on_bound_drag, true);
       
    43 
       
    44             window.removeEventListener("mouseup", this.bound_on_release, true)
       
    45             window.removeEventListener("touchend", this.bound_on_release, true);
       
    46             window.removeEventListener("touchcancel", this.bound_on_release, true);
       
    47             if(this.drag){
       
    48                 this.drag = false;
       
    49             }
       
    50             this.update_position(evt);
       
    51         }
       
    52 
       
    53 
       
    54         on_drag(evt){
       
    55             if(this.enTimer && this.drag){
       
    56                 this.update_position(evt);
       
    57                 //reset timer
       
    58                 this.enTimer = false;
       
    59                 setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100);
       
    60             }
       
    61         }
       
    62 
       
    63         update_position(evt){
       
    64             var html_dist = 0;
       
    65 
       
    66             //calculate size of widget in html
       
    67             var range_borders = this.range_elt.getBoundingClientRect();
       
    68             var range_length = Math.sqrt( range_borders.height*range_borders.height + range_borders.width*range_borders.width );
       
    69             var [minX,minY,maxX,maxY] = [range_borders.left,range_borders.bottom,range_borders.right,range_borders.top];
       
    70 
       
    71             //get range and mouse coordinates
       
    72             var mouseX = undefined;
       
    73             var mouseY = undefined;
       
    74             if (evt.type.startsWith("touch")){
       
    75                 mouseX = Math.ceil(evt.touches[0].clientX);
       
    76                 mouseY = Math.ceil(evt.touches[0].clientY);
       
    77             }
       
    78             else{
       
    79                 mouseX = evt.pageX;
       
    80                 mouseY = evt.pageY;
       
    81             }
       
    82 
       
    83             //get handle distance from mouse position
       
    84             if (minX > mouseX && minY < mouseY){
       
    85                 html_dist = 0;
       
    86             }
       
    87             else if (maxX < mouseX && maxY > mouseY){
       
    88                 html_dist = range_length;
       
    89             }
       
    90             else{
       
    91                 // calculate distace
       
    92                 if(this.fi > 0.7){
       
    93                     html_dist = (minY - mouseY)/Math.sin(this.fi);
       
    94                 }
       
    95                 else{
       
    96                     html_dist = (mouseX - minX)/Math.cos(this.fi);
       
    97                 }
       
    98 
       
    99                 //check if in range
       
   100                 if (html_dist > range_length){
       
   101                     html_dist = range_length;
       
   102                 }
       
   103                 else if (html_dist < 0){
       
   104                     html_dist = 0;
       
   105                 }
       
   106 
       
   107             }
       
   108 
       
   109             this.svg_dist=Math.ceil((html_dist/range_length)*this.range[1]);
       
   110 
       
   111             this.apply_hmi_value(0, this.svg_dist);
       
   112 
       
   113             // update ghost cursor
       
   114             if(this.setpoint_elt != undefined){
       
   115                 this.request_animate();
       
   116             }
       
   117         }
       
   118 
       
   119         animate(){
       
   120             this.update_DOM(this.svg_dist, this.setpoint_elt);
       
   121         }
       
   122 
       
   123         on_select(evt){
       
   124             this.drag = true;
       
   125             this.enTimer = true;
       
   126             window.addEventListener("touchmove", this.on_bound_drag, true);
       
   127             window.addEventListener("mousemove", this.on_bound_drag, true);
       
   128 
       
   129             window.addEventListener("mouseup", this.bound_on_release, true)
       
   130             window.addEventListener("touchend", this.bound_on_release, true);
       
   131             window.addEventListener("touchcancel", this.bound_on_release, true);
       
   132             this.update_position(evt);
       
   133         }
       
   134 
       
   135         init() {
       
   136             let min = this.min_elt ?
       
   137                         Number(this.min_elt.textContent) :
       
   138                         this.args.length >= 1 ? this.args[0] : 0;
       
   139             let max = this.max_elt ?
       
   140                         Number(this.max_elt.textContent) :
       
   141                         this.args.length >= 2 ? this.args[1] : 100;
       
   142 
       
   143             this.range = [min, max, this.range_elt.getPointAtLength(0),this.range_elt.getTotalLength()];
       
   144             let start = this.range_elt.getPointAtLength(0);
       
   145             let end = this.range_elt.getPointAtLength(this.range_elt.getTotalLength());
       
   146             this.fi = Math.atan2(start.y-end.y, end.x-start.x);
       
   147 
       
   148             this.bound_on_select = this.on_select.bind(this);
       
   149             this.bound_on_release = this.on_release.bind(this);
       
   150             this.on_bound_drag = this.on_drag.bind(this);
       
   151 
       
   152             this.element.addEventListener("mousedown", this.bound_on_select);
       
   153             this.element.addEventListener("touchstart", this.bound_on_select);
       
   154 
       
   155             if(this.setpoint_elt != undefined){
       
   156                 this.setpoint_style = this.setpoint_elt.getAttribute("style");
       
   157                 this.setpoint_elt.setAttribute("style", "display:none");
       
   158             }
       
   159 
       
   160         }
       
   161     }
       
   162     ||
       
   163 
       
   164 template "widget[@type='Slider']", mode="widget_defs" {
       
   165     param "hmi_element";
       
   166     labels("handle range");
       
   167     optional_labels("value min max setpoint");
       
   168     |,
       
   169 }