eskimoblood / jim-knopf

:o: small JavaScript library to create knobs using SVG
http://eskimoblood.github.com/jim-knopf/
199 stars 44 forks source link

callback funtion #10

Closed mkeyno closed 7 years ago

mkeyno commented 7 years ago

hi , thanks for light weight library , its really elegant, however I don't know how to link knob to the callback function whenever its value changed , for example I would like to send its data to server when it changed or when receive new value set it position to new value I really appreciated if you could make example for that

eskimoblood commented 7 years ago

Just add an event listener to the input field. And listen for the change event. Here is the code from the example page

mkeyno commented 7 years ago

thanks @eskimoblood for fast reply , I read this example and could get knob value but I couldn't change its value with some code like this

function add_val( )
{
document.getElementById('someIdHere').value=9;

}
eskimoblood commented 7 years ago

Ah ok, then you have to use the update function on the knob instance. https://github.com/eskimoblood/jim-knopf/blob/master/lib/knob.js#L102

mkeyno commented 7 years ago

thanks @eskimoblood , I used following code but nothings happened , what do I miss BR

// my definition
new Knob(document.getElementById('MyRange_bt_ID'), new MyKnob());
//
function add_val( ) // bottom on click
{
var v=document.getElementById('MyRange_bt_ID').value;
v=v+1;
MyKnob.update(v);
}

also if I intend to change direction of Arc instance and value changed from Max to Min value , what properties should be redefined also if I intend to add Text option in special format , for example "Temp" added to value to display like thermometer ,what properties should be redefined really really appreciated

eskimoblood commented 7 years ago

Please take a look at the index.html from gh-pages branch on how to create Knobs.

To set the value you have to call the udpate function on the knob instance not on the input value.

var knob = new Knob(document.getElementById('MyRange_bt_ID')
knob.update(10)

Sorry for the bad API, but this project is some years old and I'm not maintaining it anymore

mkeyno commented 7 years ago

Thanks man , its work great , so sad you not maintaining it anymore but let me tell you somethings , I downloaded all knob lib in github and these two days picking all of it and your lib is the best lib I've ever find in implementation and be lightweight also if you got time I really appreciated if you could look at my little problem, otherwise thanks again and good luck my two predefined SVG "gradian" fill and SVG "inner-shadow" filter not applied to my knob sub elements whereas other style easily has been applied

<input id="temp_env" class="env_class" type="range" min="-1" max="50" data-width="150" data-height="150" data-angleOffset="260" data-angleRange="200">   
<script type="text/javascript">
ENV_TEMP = function() {};
ENV_TEMP.prototype = Object.create(Ui.prototype);
ENV_TEMP.prototype.createElement = function() {
  Ui.prototype.createElement.apply(this, arguments);
  this.addComponent(new Ui.Arc({    arcWidth: this.width/4  }));
  this.addComponent(new Ui.Text());
  this.merge(this.options, {arcWidth: this.width/4});
  var arc = new Ui.El.Arc(this.options);
  arc.setAngle(this.options.anglerange);
  this.el.node.appendChild(arc.node);
  this.el.node.setAttribute("class", "env_class");
};
new Knob(document.getElementById('temp_env'), new ENV_TEMP());    
</script>
<style>
.env_class text {
      font-size: 15px;
      fill: #0000B6;
      font-weight: bold;
      font-family: sans-serif;
      -webkit-transition: all .1s ease-in-out;
    }
.env_class path {  filter: url(#inner-shadow);   stroke: none;  fill: #69D2E7;  }
.env_class path:first-child {    fill:url(#gradian);  stroke: none; }

</style>
<svg>
<filter id='inner-shadow'>
        <!-- Shadow Offset -->
        <feOffset dx='0' dy='5' />
        <!-- Shadow Blur -->
        <feGaussianBlur stdDeviation='5' result='offset-blur' />
        <!-- Invert the drop shadow to create an inner shadow -->
        <feComposite operator='out' in='SourceGraphic' in2='offset-blur' result='inverse' />
        <!-- Color & Opacity -->
        <feFlood flood-color='black' flood-opacity='0.75' result='color' />
        <!-- Clip color inside shadow -->
        <feComposite operator='in' in='color' in2='inverse' result='shadow' />
        <!-- Put shadow over original object -->
        <feComposite operator='over' in='shadow' in2='SourceGraphic' />
    </filter>
<defs>
        <lineargradient id="gradian"x1="0%" x2="100%" y1="40%"  y2="90%">
            <stop offset="0%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
            <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
        </lineargradient>
 </defs>
</svg>
eskimoblood commented 7 years ago

I've tried on JSBin and looks ok for me: http://jsbin.com/lavoyonija/edit?html,output

mkeyno commented 7 years ago

sorry @eskimoblood it was my mistake , actually I use your lib demonstrate live temp of some HVAC system , is there any way to disable eventlistener on special knob so it could just update by server data not by user mouse or keyborad event BR

eskimoblood commented 7 years ago

nope, but if you want you can add a pull request for this: just wrap this lines with a if statement and use the input disabled state to decide if the knob should be changeable by the user.

mkeyno commented 7 years ago

@eskimoblood unfortunately I'm not expert in javascript and sorry to take your time this day so much , however I think function should be look like this , and hope not need more extra line in other function , the sketch is to null the event parameter when user input Boolean false , please let me know if the function is correct

Knob = function(input, ui,bool_event=true) {
  var container = document.createElement('div');
      container.setAttribute('tabindex', 0);
  input.parentNode.replaceChild(container, input);
  input.style.cssText = 'position: absolute; top: -10000px';
  input.setAttribute('tabindex', -1);
     container.appendChild(input);

  var settings = this.settings = this._getSettings(input);

  this.value = input.value = settings.min + settings.range / 2;
  this.input = input;
  this.min = settings.min;

  this.ui = ui;
  this.bool_event = bool_event;

  var events = {
    keydown: this._handleKeyEvents.bind(this),
    mousewheel: this._handleWheelEvents.bind(this),
    DOMMouseScroll: this._handleWheelEvents.bind(this),
    touchstart: this._handleMove.bind(this, 'touchmove', 'touchend'),
    mousedown: this._handleMove.bind(this, 'mousemove', 'mouseup')
  };
if(bool_event)    for (var event in events) {    container.addEventListener(event, events[event], false);  }

  container.style.cssText = 'position: relative; width:' + settings.width + 'px;' + 'height:' + settings.height + 'px;';

  ui.init(container, settings);
  this.container = container;
  this.changed(0);

};
mkeyno commented 7 years ago

thanks @eskimoblood I've update the lib and its work perfectly