• fabic.js Quadratic Curve /可控制的曲线


    需要绘制一条可控制的贝塞尔曲线,发现fabic官网中一个demo有点类似。感兴趣的可以移步官网查看demo

    官网的demo是对于html 而言的,放在vue中需要变换一下,具体代码如下:

    1. <script>
    2. import { mapGetters } from 'vuex'
    3. // import fabric from 'fabric'
    4. let canvas = ''
    5. export default {
    6. name: 'Dashboard',
    7. computed: {
    8. ...mapGetters([
    9. 'name'
    10. ])
    11. },
    12. data () {
    13. return {
    14. width: window.innerWidth,
    15. height: window.innerHeight,
    16. activeEl: {}// 获取当前点击元素
    17. }
    18. },
    19. mounted () {
    20. const self = this
    21. // canvas = new fabric.StaticCanvas('editorCanvas', {//静态画布,不可以修改
    22. canvas = new fabric.Canvas('editorCanvas', {
    23. width: self.width,
    24. height: self.height,
    25. backgroundColor: '#ffffff'
    26. })
    27. var line = new fabric.Path('M 65 0 Q 100, 100, 200, 0', { fill: '', stroke: 'black', objectCaching: false })
    28. line.path[0][1] = 100
    29. line.path[0][2] = 100
    30. line.path[1][1] = 200
    31. line.path[1][2] = 200
    32. line.path[1][3] = 300
    33. line.path[1][4] = 100
    34. line.selectable = false
    35. canvas.add(line)
    36. var p1 = self.makeCurvePoint(200, 200, null, line, null)
    37. p1.name = 'p1'
    38. canvas.add(p1)
    39. var p0 = self.makeCurveCircle(100, 100, line, p1, null)
    40. p0.name = 'p0'
    41. canvas.add(p0)
    42. var p2 = self.makeCurveCircle(300, 100, null, p1, line)
    43. p2.name = 'p2'
    44. canvas.add(p2)
    45. canvas.on('object:selected', function (opt) {
    46. self.onObjectSelected(opt)
    47. })
    48. canvas.on('object:moving', function (opt) {
    49. self.onObjectMoving(opt)
    50. })
    51. canvas.on('selection:cleared', function (opt) {
    52. self.onSelectionCleared(opt)
    53. // canvas.on({
    54. // 'object:selected': this.onObjectSelected(e),
    55. // 'object:moving': this.onObjectMoving(e),
    56. // 'selection:cleared': this.onSelectionCleared(e)
    57. })
    58. },
    59. methods: {
    60. makeCurveCircle (left, top, line1, line2, line3) {
    61. var c = new fabric.Circle({
    62. left: left,
    63. top: top,
    64. strokeWidth: 5,
    65. radius: 12,
    66. fill: '#fff',
    67. stroke: '#666',
    68. originX: 'center',
    69. originY: 'center'
    70. })
    71. c.hasBorders = c.hasControls = false
    72. c.line1 = line1
    73. c.line2 = line2
    74. c.line3 = line3
    75. return c
    76. },
    77. makeCurvePoint (left, top, line1, line2, line3) {
    78. var c = new fabric.Circle({
    79. left: left,
    80. top: top,
    81. strokeWidth: 8,
    82. originX: 'center',
    83. originY: 'center',
    84. radius: 14,
    85. fill: '#fff',
    86. stroke: '#666'
    87. })
    88. c.hasBorders = c.hasControls = false
    89. c.line1 = line1
    90. c.line2 = line2
    91. c.line3 = line3
    92. return c
    93. },
    94. onObjectSelected (e) {
    95. // console.log(e.target)
    96. var activeObject = e.target
    97. if (activeObject.name == 'p0' || activeObject.name == 'p2') {
    98. activeObject.line2.animate('opacity', '1', {
    99. duration: 200,
    100. onChange: canvas.renderAll.bind(canvas)
    101. })
    102. activeObject.line2.selectable = true
    103. }
    104. },
    105. onSelectionCleared (e) {
    106. var activeObject = e.target
    107. if (activeObject.name == 'p0' || activeObject.name == 'p2') {
    108. activeObject.line2.animate('opacity', '0', {
    109. duration: 200,
    110. onChange: canvas.renderAll.bind(canvas)
    111. })
    112. activeObject.line2.selectable = false
    113. } else if (activeObject.name == 'p1') {
    114. activeObject.animate('opacity', '0', {
    115. duration: 200,
    116. onChange: canvas.renderAll.bind(canvas)
    117. })
    118. activeObject.selectable = false
    119. }
    120. },
    121. onObjectMoving (e) {
    122. if (e.target.name == 'p0' || e.target.name == 'p2') {
    123. var p = e.target
    124. if (p.line1) {
    125. p.line1.path[0][1] = p.left
    126. p.line1.path[0][2] = p.top
    127. } else if (p.line3) {
    128. p.line3.path[1][3] = p.left
    129. p.line3.path[1][4] = p.top
    130. }
    131. } else if (e.target.name == 'p1') {
    132. var p = e.target
    133. if (p.line2) {
    134. p.line2.path[1][1] = p.left
    135. p.line2.path[1][2] = p.top
    136. }
    137. } else if (e.target.name == 'p0' || e.target.name == 'p2') {
    138. var p = e.target
    139. p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top })
    140. p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top })
    141. p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top })
    142. p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top })
    143. }
    144. }
    145. }
    146. }
    147. script>
    148. <style lang="scss" scoped>
    149. style>

    效果如图:

    核心:定义 line时,设置path数组值。变换时修改path数组中的值。直接=

    但是我需要绘制三阶贝塞尔曲线,即要两个控制点。这时候就需要变形一下。

    1. const line = new fabric.Path(`M ${item1.left} ${item1.top} C ${item1.left} ${item2.top}, ${item2.left} ${item1.top}, ${item2.left}, ${item2.top}`, {
    2. ......
    3. /* 起点 */
    4. line.path[0][1] = item1.left
    5. line.path[0][2] = item1.top
    6. /* 控制点1 */
    7. line.path[1][1] = item1.left
    8. line.path[1][2] = item2.top
    9. /* 控制点2 */
    10. line.path[1][3] = item2.left
    11. line.path[1][4] = item1.top
    12. /* 结束点 */
    13. line.path[1][5] = item2.left
    14. line.path[1][6] = item2.top

    修改直接进行重新赋值。

  • 相关阅读:
    到底什么是LPO?
    03_RabbitMQ快速入门案例
    拼多多API批量获取商品详情信息
    前端面试题总结
    mitmproxy 使用
    马来西亚农村致富经 丰收节贸促会-艾迪:跨境电商中国样本
    八股文之redis
    【ffmpeg】音频编码原理
    Stable Diffusion 模型下载:A-Zovya RPG Artist Tools(RPG 大师工具箱)
    Day04 Spring和SpringBoot
  • 原文地址:https://blog.csdn.net/Thea12138/article/details/133079628