Vue3+ts+Fabric.js 实现可拖拽变化的多边形
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
需求:
使用canvas绘制多边形,且多边形的位置,大小和形状可拖动修改
使用Fabric.js
Fabric.js是一个可以简化canvas程序编写的库。 Fabric.js为canvas提供所缺少的对象模型
fabric.js官网
cnpm i fabric -D // 或者 npm i fabric -D
页面引入
import { fabric } from 'fabric'
html代码:
<div class="container">
<div style="border: 1px solid #ccc; margin-right: 10px">
<canvas ref="myCanvas" id="myCanvas" width="800" height="400">
</canvas>
</div>
<el-button type="primary" @click="Edit">切换</el-button>
</div>
.container {
display: flex;
padding: 8px;
.toolBox {
}
}
实现效果:
两个拖动模式
typescript代码:
这里比较麻烦,参考了
我改写成了vue3.0的,且中的this稍微卡顿了半小时
<script lang="ts">
import { defineComponent, reactive, onMounted, toRefs, ref, watch } from 'vue'
import { fabric } from 'fabric'
import _ from 'lodash'
export default defineComponent({
name: 'AreaPlan',
components: {},
setup() {
let canvas: any
const initCanvas = () => {
// 直接获取Dom
canvas = new fabric.Canvas('myCanvas')
// 创建一个矩形数组,上面
let points = [
{
x: 3,
y: 4,
},
{
x: 16,
y: 3,
},
{
x: 30,
y: 5,
},
{
x: 25.0,
y: 55,
},
{
x: 19,
y: 44,
},
{
x: 15,
y: 30,
},
{
x: 15,
y: 55,
},
{
x: 9,
y: 55,
},
{
x: 6,
y: 53,
},
{
x: -2,
y: 55,
},
{
x: -4,
y: 40,
},
{
x: 0,
y: 20,
},
]
let polygon = new fabric.Polygon(points, {
left: 100,
top: 50,
fill: '#D81B60',
strokeWidth: 1,
stroke: 'green',
scaleX: 4,
scaleY: 4,
objectCaching: false,
transparentCorners: false,
cornerColor: 'blue',
})
canvas.viewportTransform = [0.7, 0, 0, 0.7, -50, 50]
canvas.add(polygon)
}
const polygonPositionHandler = (
dim,
finalMatrix,
fabricObject,
constrol
) => {
const index = constrol.pointIndex
var x = fabricObject.points[index].x - fabricObject.pathOffset.x,
y = fabricObject.points[index].y - fabricObject.pathOffset.y
return fabric.util.transformPoint(
{ x: x, y: y },
fabric.util.multiplyTransformMatrices(
fabricObject.canvas.viewportTransform,
fabricObject.calcTransformMatrix()
)
)
}
const actionHandler = (eventData, transform, x, y) => {
var polygon = transform.target,
currentControl = polygon.controls[polygon.__corner],
mouseLocalPosition = polygon.toLocalPoint(
new fabric.Point(x, y),
'center',
'center'
),
polygonBaseSize = polygon._getNonTransformedDimensions(),
size = polygon._getTransformedDimensions(0, 0),
finalPointPosition = {
x:
(mouseLocalPosition.x * polygonBaseSize.x) / size.x +
polygon.pathOffset.x,
y:
(mouseLocalPosition.y * polygonBaseSize.y) / size.y +
polygon.pathOffset.y,
}
polygon.points[currentControl.pointIndex] = finalPointPosition
return true
}
const anchorWrapper = (anchorIndex, fn) => {
return function (eventData, transform, x, y) {
var fabricObject = transform.target,
absolutePoint = fabric.util.transformPoint(
{
x: fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x,
y: fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y,
},
fabricObject.calcTransformMatrix()
),
actionPerformed = fn(eventData, transform, x, y),
newDim = fabricObject._setPositionDimensions({}),
polygonBaseSize = fabricObject._getNonTransformedDimensions(),
newX =
(fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x) /
polygonBaseSize.x,
newY =
(fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y) /
polygonBaseSize.y
fabricObject.setPositionByOrigin(absolutePoint, newX + 0.5, newY + 0.5)
return actionPerformed
}
}
const Edit = () => {
console.log('canvas', canvas)
console.log('Edit')
var poly = canvas.getObjects()[0]
canvas.setActiveObject(poly)
poly.edit = !poly.edit
if (poly.edit) {
var lastControl = poly.points.length - 1
poly.cornerStyle = 'circle'
poly.cornerColor = 'rgba(0,0,255,0.5)'
poly.controls = poly.points.reduce(function (acc, point, index) {
const control = new fabric.Control({
positionHandler: (a, b, c) =>
polygonPositionHandler(a, b, c, control),
actionHandler: anchorWrapper(
index > 0 ? index - 1 : lastControl,
actionHandler
),
actionName: 'modifyPolygon',
pointIndex: index,
})
acc['p' + index] = control
return acc
}, {})
} else {
poly.cornerColor = 'blue'
poly.cornerStyle = 'rect'
poly.controls = fabric.Object.prototype.controls
}
poly.hasBorders = !poly.edit
canvas.requestRenderAll()
}
onMounted(() => {
initCanvas()
})
return {
//把切换事件返回出去
Edit,
}
},
})
</script>
后面修改成为手动标绘多边形,且支持修改的,有时间就会更新,有不足的地方请留言。阿里嘎多~~~~~~。转载请标明出处,谢谢:
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)