svghmi/widget_circularslider.ysl2
author Edouard Tisserant
Mon, 10 Aug 2020 11:30:06 +0200
branchsvghmi
changeset 3018 22b969b409b0
parent 3013 0ea6b4f435de
child 3045 f6d428330e04
permissions -rw-r--r--
Merge
3013
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     1
// widget_circuralslider.ysl2
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     2
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     3
template "widget[@type='CircularSlider']", mode="widget_class"
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     4
    ||
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     5
    class CircularSliderWidget extends Widget{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     6
        frequency = 5;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     7
        range = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     8
        circle = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
     9
        handle_pos = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    10
        drag = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    11
        enTimer = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    12
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    13
        dispatch(value) {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    14
            if(!this.drag){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    15
                if(this.value_elt)
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    16
                    this.value_elt.textContent = String(value);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    17
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    18
                this.handle_position(value);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    19
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    20
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    21
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    22
        handle_position(value){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    23
            let [min,max,totalDistance] = this.range;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    24
            let length = Math.max(0,Math.min((totalDistance),(Number(value)-min)/(max-min)*(totalDistance)));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    25
            let tip = this.range_elt.getPointAtLength(length);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    26
            this.handle_elt.setAttribute('transform',"translate("+(tip.x-this.handle_pos.x)+","+(tip.y-this.handle_pos.y)+")");
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    27
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    28
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    29
        on_release(evt) {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    30
            if(this.drag){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    31
                this.drag = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    32
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    33
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    34
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    35
        update_position(evt){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    36
            if(this.drag && this.enTimer){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    37
                var svg_dist = 0;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    38
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    39
                //calculate center of widget in html
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    40
                // --TODO maybe it would be better to bind this part to window change size event ???
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    41
                let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    42
                let [cX, cY,fiStart,fiEnd,minMax,x1,y1,width,height] = this.circle;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    43
                let htmlCirc = this.range_elt.getBoundingClientRect();
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    44
                let cxHtml = ((htmlCirc.right-htmlCirc.left)/(width)*(cX-x1))+htmlCirc.left;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    45
                let cyHtml = ((htmlCirc.bottom-htmlCirc.top)/(height)*(cY-y1))+htmlCirc.top;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    46
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    47
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    48
                //get mouse coordinates
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    49
                let mouseX = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    50
                let mouseY = undefined;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    51
                if (evt.type.startsWith("touch")){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    52
                    mouseX = Math.ceil(evt.touches[0].clientX);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    53
                    mouseY = Math.ceil(evt.touches[0].clientY);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    54
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    55
                else{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    56
                    mouseX = evt.pageX;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    57
                    mouseY = evt.pageY;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    58
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    59
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    60
                //calculate angle
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    61
                let fi = Math.atan2(cyHtml-mouseY, mouseX-cxHtml);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    62
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    63
                // transform from 0 to 2PI
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    64
                if (fi > 0){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    65
                    fi = 2*Math.PI-fi;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    66
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    67
                else{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    68
                    fi = -fi;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    69
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    70
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    71
                //offset it to 0
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    72
                fi = fi - fiStart;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    73
                if (fi < 0){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    74
                    fi = fi + 2*Math.PI;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    75
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    76
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    77
                //get handle distance from mouse position
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    78
                if(fi<fiEnd){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    79
                    svg_dist=(fi)/(fiEnd)*(this.range[1]-this.range[0]);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    80
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    81
                else if(fiEnd<fi && fi<fiEnd+minMax){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    82
                    svg_dist = this.range[1];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    83
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    84
                else{
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    85
                    svg_dist = this.range[0];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    86
                }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    87
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    88
                //redraw handle --TODO is it fast enough if I just call change_hmi_value???
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    89
                this.handle_position(svg_dist);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    90
                if(this.value_elt)
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    91
                    this.value_elt.textContent = String(Math.ceil(svg_dist));
3018
Edouard Tisserant
parents: 3013
diff changeset
    92
                this.apply_hmi_value(0, Math.ceil(svg_dist));
3013
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    93
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    94
                //reset timer
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    95
                this.enTimer = false;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    96
                setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    97
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    98
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
    99
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   100
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   101
        on_select(evt){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   102
            this.drag = true;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   103
            this.enTimer = true;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   104
            this.update_position(evt);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   105
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   106
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   107
        init() {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   108
            //get min max
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   109
            let min = this.min_elt ?
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   110
                        Number(this.min_elt.textContent) :
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   111
                        this.args.length >= 1 ? this.args[0] : 0;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   112
            let max = this.max_elt ?
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   113
                        Number(this.max_elt.textContent) :
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   114
                        this.args.length >= 2 ? this.args[1] : 100;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   115
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   116
            //fiStart ==> offset
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   117
            let fiStart = Number(this.range_elt.getAttribute('sodipodi:start'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   118
            let fiEnd = Number(this.range_elt.getAttribute('sodipodi:end'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   119
            fiEnd = fiEnd - fiStart;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   120
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   121
            //fiEnd ==> size of angle
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   122
            if (fiEnd < 0){
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   123
                fiEnd = 2*Math.PI + fiEnd;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   124
            }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   125
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   126
            //min max barrier angle
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   127
            let minMax = (2*Math.PI - fiEnd)/2;
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   128
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   129
            //get parameters from svg
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   130
            let cX = Number(this.range_elt.getAttribute('sodipodi:cx'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   131
            let cY = Number(this.range_elt.getAttribute('sodipodi:cy'));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   132
            this.range_elt.style.strokeMiterlimit="0"; //eliminates some weird border around html object
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   133
            this.range = [min, max,this.range_elt.getTotalLength()];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   134
            let cPos = this.range_elt.getBBox();
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   135
            this.handle_pos = this.range_elt.getPointAtLength(0);
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   136
            this.circle = [cX, cY,fiStart,fiEnd,minMax,cPos.x,cPos.y,cPos.width,cPos.height];
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   137
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   138
            //init events
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   139
            this.handle_elt.addEventListener("touchstart", hmi_widgets[this.element_id].on_select.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   140
            this.handle_elt.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   141
            this.element.addEventListener("mousedown", hmi_widgets[this.element_id].on_select.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   142
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   143
            window.addEventListener("touchmove", hmi_widgets[this.element_id].update_position.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   144
            window.addEventListener("mousemove", hmi_widgets[this.element_id].update_position.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   145
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   146
            window.addEventListener("mouseup", hmi_widgets[this.element_id].on_release.bind(this))
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   147
            window.addEventListener("touchend", hmi_widgets[this.element_id].on_release.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   148
            window.addEventListener("touchcancel", hmi_widgets[this.element_id].on_release.bind(this));
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   149
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   150
        }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   151
    }
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   152
    ||
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   153
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   154
template "widget[@type='CircularSlider']", mode="widget_defs" {
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   155
    param "hmi_element";
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   156
    labels("handle range");
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   157
    optional_labels("value min max");
0ea6b4f435de Create new CircularSlider widget which extand class widget
usveticic
parents:
diff changeset
   158
    |,
3018
Edouard Tisserant
parents: 3013
diff changeset
   159
}