[关闭]
@lizlalala 2016-12-04T13:42:49.000000Z 字数 3313 阅读 1210

fe日常玩耍之缩小版

js css 日常玩耍 demo svg


  1. 末尾显示省略号(ellipsis)

分两种,单行跟多行。

  1. .ellipsis-single{
  2. width: 200px;
  3. overflow: hidden;
  4. text-overflow: ellipsis;
  5. white-space: nowrap;
  6. }

tagged input

tagged input via vue@luchenCodePen

这个demo目的是:
1. 轮子,交互友好,因为常用pocket跟evernote,就有打tag的场景,但是element没有相应的组件。
2. 实践了一下vue所说的v-model的语法糖。总结来说就是

v-model = value+ $emit('input')
子组件新建一个data,维持从父类传来的props(value)作为初始值,每次子组件data(或者更精确点说是:要传出去的数值)变动时$emit,通知父组件变动。是由内往外的数据传输。


svg 制作进度环

part1:基础知识:

part2: 划重点

  1. 圆环: 用circle+fill:none+stroke绘制而成
  2. slider:用path+arc指令+fill:none去绘制弧
  3. 注意点:
    • viewbox与svg之间的scale和坐标映射问题。整个的绘制是以viewbox为基准的,而交互操作的坐标是需要先转为相对于svg,然后再scale到viewBox的。关于viewbox,viewport等的问题,戳张鑫旭大神的文章科普下理解SVG的viewport,viewBox,preserveAspectRatio
      viewbox的一个好处,可以认为是可以自适应container的同时开发人员可以只针对viewbox的坐标系统进行开发。有点类似于移动端设置rem,开发人员只要对750px的去进行编写各种px,最终都会根据环境去相应的映射到正确的宽高大小。
      • 精度缺失问题: 当percent为100传过去得到弧度制的角度时,因为Math.PI本身无限循环下去,有精度损失。我们看到

        而正常理解中,sin(360°)应该为0。就导致最终画满格的时候会出现这样的情况。

        所以楼主暗搓搓的检测100%时手动变成了99.9%。捂脸...
    • Math.sin等函数接受的是弧度制非角度制,需要预先进行处理
  4. 交互方面:
    设置了点击以及mousemove的部分。
    对于坐标的检测,检测clientX,并映射到viewbox内。然后根据(x-c1)^2 +(y-c2)^2 = r^2。去计算y,而这个时候得到的会有两个y,对称于直径。那么就需要根据clientY去进行筛选匹配,从而得到正确的圆上坐标。,去绘制arc path。然后根据坐标去计算夹角,得到percent。最终更新data。

最终的demo戳这个链接,但是不知道为什么放到codepen里面,第三幅图的数据没有更新(func props没有传下去)。实测是可以的。
See the Pen sliding circle via svg by lu (@luchen) on CodePen.

补充:
因为同时有click跟mousedown,mousemove,mouseup。为了避免冲突,楼主把mouse部分放在了path上,click放在了circle上。具体场景可以看

可以看到当在只注册了mousedown,up的path上进行click,会依次执行down,up。
如果绑在同一个元素上,就有冲突,会执行三条,那么就需要用时间进行下面的区分操作:

在mousedown的时候,记录当前的时间,然后在mouseup的时候,再取当前时间,然后判断这两个时间差,当它大于某个数值的时候(因为如果是click,那么会在很短时间内产生mouseup),就不认为它是click。更精确的还可以加上mousedown和mouseup的坐标,不同则非click。

网上看到一个setTimeout的解决方案,小于200ms的就执行click操作:

  1. $(element).click(function(){
  2. // click code in here
  3. });
  4. $(element).MouseDown(function(){
  5. onMouseDownFlag = false;
  6. mouseDownAndUpTimer = setTimeout(function(){
  7. // OnMouseDown Code in here
  8. onMouseDownFlag = true;
  9. },200);
  10. }).MouseUp(function(){
  11. if(onMouseDownFlag){
  12. // OnMouseUp Code in here
  13. }else{
  14. clearTimeout(mouseDownAndUpTimer); // 清除延迟时间
  15. }
  16. });

PS:
楼主之前看到circle还有一种很巧妙的方法。简要来说是用path(arc)+stroke-dasharray去处理。一个环就是一个stoke-dasharray [first second]。first的长度即为当前percent的亮色部分。second即为灰色的部分。
但是这种方法不是很好做mousemove。所以楼主就作罢嘞


对比一下tagged input和circle,这两个都是vue组件的编写,都涉及父子组件的通信,区别在于,第一种是 子组件新建一个data,维持从父类传来的props作为初始值,每次子组件变动时$emit,通知父组件变动。是由内往外的数据传输。
第二种的version1版本是父组件传props进内部,外部进行变动,反应到子组件,相应变化。(此时没有data.)当需要增加需求(version2,即需要交互滑动circle)时,就需要增加一个currentValue的data,以props percent初始化,一方面需要watch percent的变动(外->内),另一方面当自己变化时,需要告知外部,即调用onPercentChange(val) 的props回调。

references
  1. path in svg
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注