Лотти Анимация на холсте фабрики
Можно ли загрузить анимацию Лотти в холст fabricjs?
Я пробовал следующие образцы
bodymovin.loadAnimation({
wrapper: animateElement, // div element
loop: true,
animType: 'canvas', // fabricjs canvas
animationData: dataValue, // AE json
rendererSettings: {
scaleMode: 'noScale',
clearCanvas: true,
progressiveLoad: false,
hideOnTransparent: true,
}
});
canvas.add(bodymovin);
canvas.renderAll();
Я не могу добавить анимацию в полотно JS ткани. если кто-то преодолеет эту проблему, пожалуйста, прокомментируйте ее
3 ответа
Я могу опоздать, чтобы ответить на этот вопрос, но для всех, кто ищет, эта ручка может дать вам несколько советов: https://codepen.io/shkaper/pen/oEKEgG
Идея здесь, в первую очередь, состоит в том, чтобы расширить fabric.Image класс, переопределяющий его внутренний метод рендеринга, для рендеринга содержимого произвольного холста, который вы сами предоставляете:
fabric.AEAnimation = fabric.util.createClass(fabric.Image, {
drawCacheOnCanvas: function(ctx) {
ctx.drawImage(this._AECanvas, -this.width / 2, -this.height / 2);
},
})
Вы можете сделать этот холст аргументом конструктора, например
initialize: function (AECanvas, options) {
options = options || {}
this.callSuper('initialize', AECanvas, options)
this._AECanvas = AECanvas
},
Тогда вам просто нужно использовать средство рендеринга холста lottie, чтобы нарисовать анимацию на холсте и передать его в новый объект fabric.AEAnimation.
Если вам поможет, я создал этот класс Lottie с поддержкой экспорта toObject/JSON
import { fabric } from 'fabric'
import lottie from 'lottie-web'
const Lottie = fabric.util.createClass(fabric.Image, {
type: 'lottie',
lockRotation: true,
lockSkewingX: true,
lockSkewingY: true,
srcFromAttribute: false,
initialize: function (path, options) {
if (!options.width) options.width = 480
if (!options.height) options.height = 480
this.path = path
this.tmpCanvasEl = fabric.util.createCanvasElement()
this.tmpCanvasEl.width = options.width
this.tmpCanvasEl.height = options.height
this.lottieItem = lottie.loadAnimation({
renderer: 'canvas',
loop: true,
autoplay: true,
path,
rendererSettings: {
context: this.tmpCanvasEl.getContext('2d'),
preserveAspectRatio: 'xMidYMid meet',
},
})
// this.lottieItem.addEventListener('DOMLoaded', () => {
// console.log('DOMLoaded')
// })
this.lottieItem.addEventListener('enterFrame', (e) => {
this.canvas?.requestRenderAll()
})
this.callSuper('initialize', this.tmpCanvasEl, options)
},
play: function () {
this.lottieItem.play()
},
stop: function () {
this.lottieItem.stop()
},
getSrc: function () {
return this.path
},
})
Lottie.fromObject = function (_object, callback) {
const object = fabric.util.object.clone(_object)
fabric.Image.prototype._initFilters.call(object, object.filters, function (filters) {
object.filters = filters || []
fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function (resizeFilters) {
object.resizeFilter = resizeFilters[0]
fabric.util.enlivenObjects([object.clipPath], function (enlivedProps) {
object.clipPath = enlivedProps[0]
const fabricLottie = new fabric.Lottie(object.src, object)
callback(fabricLottie, false)
})
})
})
}
Lottie.async = true
export default Lottie
Чтобы создать элемент Lottie, просто передайте JSON
const fabricImage = new fabric.Lottie('https://assets5.lottiefiles.com/private_files/lf30_rttpmsbc.json', {
scaleX: 0.5,
})
canvas.add(fabricImage)
Я бы предположил, что, комбинируя ваш код с чем-то похожим на https://itnext.io/video-element-serialization-and-deserialization-of-canvas-fc5dbf47666d. В зависимости от вашего сценария вы можете использовать что-то вроде http://fabricjs.com/interaction-with-objects-outside-canvas