You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.2 KiB
HTML
111 lines
3.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.6/fabric.min.js"></script>
|
|
<title>Fabric.js Text Editing</title>
|
|
</head>
|
|
<style>
|
|
body {
|
|
background: ivory;
|
|
}
|
|
</style>
|
|
<body>
|
|
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js"></script> -->
|
|
<canvas id="c" width="1300" height="1200" ></canvas>
|
|
<script>
|
|
const canvas = new fabric.Canvas('c')
|
|
|
|
fabric.RectWithText = fabric.util.createClass(fabric.Rect, {
|
|
type: 'rectWithText',
|
|
text: null,
|
|
textOffsetLeft: 0,
|
|
textOffsetTop: 0,
|
|
_prevObjectStacking: null,
|
|
_prevAngle: 0,
|
|
recalcTextPosition: function () {
|
|
const sin = Math.sin(fabric.util.degreesToRadians(this.angle))
|
|
const cos = Math.cos(fabric.util.degreesToRadians(this.angle))
|
|
const newTop = sin * this.textOffsetLeft + cos * this.textOffsetTop
|
|
const newLeft = cos * this.textOffsetLeft - sin * this.textOffsetTop
|
|
const rectLeftTop = this.getPointByOrigin('left', 'top')
|
|
this.text.set('left', rectLeftTop.x + newLeft)
|
|
this.text.set('top', rectLeftTop.y + newTop)
|
|
},
|
|
initialize: function (rectOptions, textOptions, text) {
|
|
this.callSuper('initialize', rectOptions)
|
|
this.text = new fabric.Textbox(text, {
|
|
...textOptions,
|
|
selectable: false,
|
|
evented: false,
|
|
})
|
|
this.textOffsetLeft = this.text.left - this.left
|
|
this.textOffsetTop = this.text.top - this.top
|
|
this.on('moving', () => {
|
|
this.recalcTextPosition()
|
|
})
|
|
this.on('rotating', () => {
|
|
this.text.rotate(this.text.angle + this.angle - this._prevAngle)
|
|
this.recalcTextPosition()
|
|
this._prevAngle = this.angle
|
|
})
|
|
this.on('scaling', (e) => {
|
|
this.recalcTextPosition()
|
|
})
|
|
this.on('added', () => {
|
|
this.canvas.add(this.text)
|
|
})
|
|
this.on('removed', () => {
|
|
this.canvas.remove(this.text)
|
|
})
|
|
this.on('mousedown:before', () => {
|
|
this._prevObjectStacking = this.canvas.preserveObjectStacking
|
|
this.canvas.preserveObjectStacking = true
|
|
})
|
|
//双击
|
|
this.on('mousedblclick', () => {
|
|
this.text.selectable = true
|
|
this.text.evented = true
|
|
this.canvas.setActiveObject(this.text)
|
|
this.text.enterEditing()
|
|
this.selectable = false
|
|
})
|
|
this.on('deselected', () => {
|
|
this.canvas.preserveObjectStacking = this._prevObjectStacking
|
|
})
|
|
this.text.on('editing:exited', () => {
|
|
this.text.selectable = false
|
|
this.text.evented = false
|
|
this.selectable = true
|
|
})
|
|
}
|
|
})
|
|
|
|
const rectOptions = {
|
|
left: 10,
|
|
top: 10,
|
|
width: 200,
|
|
height: 75,
|
|
fill: 'rgba(30, 30, 30, 0.3)',
|
|
}
|
|
const textOptions = {
|
|
left: 35,
|
|
top: 30,
|
|
width: 150,
|
|
fill: 'white',
|
|
shadow: new fabric.Shadow({
|
|
color: 'rgba(34, 34, 100, 0.4)',
|
|
blur: 2,
|
|
offsetX: -2,
|
|
offsetY: 2
|
|
}),
|
|
fontSize: 30,
|
|
}
|
|
const rectWithText = new fabric.RectWithText(rectOptions, textOptions, 'Some text')
|
|
canvas.add(rectWithText)
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|