touchevents.lzx
<library>
<mixin name="touchevents">
<doc>
<tag name="shortdesc"><text>A mixin that adds touch events to view.</text></tag>
<text>
<example title="Touch and gesture demo"><programlisting>
<canvas>
<mixin name="limitx">
<attribute name="minx" type="number" value="0"/>
<attribute name="maxx" type="number" value="${canvas.width - this.width}"/>
<setter name="x" args="x">
if (x < this.minx) {
x = minx;
} else if (x > this.maxx) {
x = maxx;
}
super.$lzc$set_x(x);
</setter>
</mixin>
<mixin name="limity">
<attribute name="miny" type="number" value="0"/>
<attribute name="maxy" type="number" value="${canvas.height - this.height}"/>
<setter name="y" args="y">
if (y < this.miny) {
y = miny;
} else if (y > this.maxy) {
y = maxy;
}
super.$lzc$set_y(y);
</setter>
</mixin>
<view width="100" height="100" opacity="${this.activated ? .5 : 1}" bgcolor="${this.pressed ? 'green' : 'red'}" with="swipegesture, touchevents, limitx, limity" transition="x 1s, y 1s" clickable="true">
<handler name="ongesture" args="g">
// activate dragging
this.setAttribute('pressed', true);
this.setAttribute('rotation', g.rotation);
this.setAttribute('xscale', g.scale);
this.setAttribute('yscale', g.scale);
</handler>
<handler name="onswipe" args="s">
var axis = 'x';
if (s.direction === 'up' || s.direction === 'down') {
axis = 'y';
}
this.animate(axis, s.velocity, 1000, true);
//Debug.info('onswipe', axis, s);
</handler>
<dragstate name="dragger" applied="${parent.pressed}"/>
</view>
</canvas>
</programlisting></example>
<p><classname>touchevents</classname> is a mixin intended for use with <sgmltag class="element" role="LzView"><view></sgmltag> and its subclasses.
</p>
</text>
</doc>
<attribute name="activated" type="boolean" value="false
"/>
<attribute name="pressed" type="boolean" value="false
"/>
<event name="ontap"/>
<attribute name="activatetime" type="number" value="100
"/>
<attribute name="presstime" type="number" value="1000
"/>
<attribute name="taplimit" type="number" value="10
"/>
<method name="construct" args="p, a">
super.construct(p,a);
this.__activateDel = new lz.Delegate(this, '__activate');
this.__pressDel = new lz.Delegate(this, '__press');
</method>
<method name="mouseevent" args="name, value=null">
if ($debug) {
//Debug.info('mouseevent %w: %w', name, value)
}
if (name === 'onmousedown') {
this.__positionstate.setAttribute('applied', true);
this.__downtime = (new Date()).getTime();
this.__downpos = this.getMouse();
this.__delta = {absx: -1, absy: -1};
lz.Timer.addTimer(this.__activateDel, this.activatetime)
lz.Timer.addTimer(this.__pressDel, this.presstime)
} else if (name === 'onmousemove') {
var newpos = this.getMouse(),
dx = newpos.x - this.__downpos.x,
absx = Math.abs(dx),
dy = newpos.y - this.__downpos.y,
absy = Math.abs(dy),
dt = (new Date()).getTime() - this.__downtime;
this.__delta = {x: dx, y: dy, t: dt, absx: absx, absy: absy};
if (absx > this.taplimit || absy > this.taplimit) {
lz.Timer.removeTimer(this.__pressDel);
}
lz.Timer.removeTimer(this.__activateDel);
} else if (name === 'onpress') {
this.__deactivate();
} else if (name === 'onmouseup'){
this.__deactivate();
// process tap events
var dt = (new Date()).getTime() - this.__downtime;
if (dt < this.presstime &&
this.__delta.absx < this.taplimit &&
this.__delta.absy < this.taplimit) {
//Debug.info('tap', this.__delta.absx, this.__delta.absy, dt, this.presstime, this.taplimit)
this.mouseevent('ontap');
}
}
super.mouseevent(name, value);
</method>
<method name="__activate" args="ignore=null">
//Debug.info('__activate');
this.setAttribute('activated', true);
</method>
<method name="__deactivate">
//Debug.info('__deactivate');
this.__positionstate.setAttribute('applied', false);
if (this.activated) {
this.setAttribute('activated', false);
}
if (this.pressed) {
this.setAttribute('pressed', false);
}
lz.Timer.removeTimer(this.__activateDel);
lz.Timer.removeTimer(this.__pressDel);
</method>
<method name="__press" args="value">
//Debug.info('_press');
lz.Timer.removeTimer(this.__activateDel);
this.setAttribute('pressed', true);
</method>
<state name="__positionstate">
<handler name="onmousemove" reference="canvas">
this.mouseevent('onmousemove');
</handler>
</state>
</mixin>
<mixin name="swipegesture">
<doc>
<tag name="shortdesc"><text>A mixin that adds the swipe gesture to touch events. Must be mixed in before touchevents, e.g. with="swipegesture, touchevents".</text></tag>
</doc>
<event name="onswipe"/>
<attribute name="swipevelocity" type="number" value="40
"/>
<method name="mouseevent" args="name, value=null">
if (name === 'onmousemove' && this.pressed == false) {
var d = this.__delta;
var swipedirection
if (d.absx > d.absy) {
// horizontal
var v = (1000 * d.x) / d.t;
if (Math.abs(v) >= this.swipevelocity &&
d.absx > this.taplimit) {
swipedirection = v < 0 ? 'left' : 'right';
}
} else {
// vertical
var v = (1000 * d.y) / d.t;
if (Math.abs(v) >= this.swipevelocity &&
d.absy > this.taplimit) {
swipedirection = v < 0 ? 'up' : 'down';
}
}
if (swipedirection) {
this.mouseevent('onswipe', {direction: swipedirection, velocity: v});
}
//Debug.info('onmousemove', d, v);
} else if (name === 'onswipe') {
//Debug.info('onswipe', value);
this.__deactivate();
}
super.mouseevent(name, value);
</method>
</mixin>
</library>
Cross References
Named Instances