官网
http://fabricjs.com/ 一个canvas框架
项目地址
效果
代码
<template>
<div class="home">
<p>
<label>Pattern left offset</label>
<input type="range" min="0" max="500" value="0" id="img-offset-x">
</p>
<canvas id="canvas" width="1565" height="929"></canvas>
</div>
</template>
<script setup>
import {onMounted} from "vue";
let canvas, rect, patternSourceCanvas, pattern;
fabric.Sprite = fabric.util.createClass(fabric.Image, {
type: 'sprite',
spriteWidth: 50,
spriteHeight: 72,
spriteIndex: 0,
frameTime: 100,
initialize: function(element, options) {
options || (options = { });
options.width = this.spriteWidth;
options.height = this.spriteHeight;
this.callSuper('initialize', element, options);
this.createTmpCanvas();
this.createSpriteImages();
},
createTmpCanvas: function() {
this.tmpCanvasEl = fabric.util.createCanvasElement();
this.tmpCanvasEl.width = this.spriteWidth || this.width;
this.tmpCanvasEl.height = this.spriteHeight || this.height;
},
createSpriteImages: function() {
this.spriteImages = [ ];
var steps = this._element.width / this.spriteWidth;
for (var i = 0; i < steps; i++) {
this.createSpriteImage(i);
}
},
createSpriteImage: function(i) {
var tmpCtx = this.tmpCanvasEl.getContext('2d');
tmpCtx.clearRect(0, 0, this.tmpCanvasEl.width, this.tmpCanvasEl.height);
tmpCtx.drawImage(this._element, -i * this.spriteWidth, 0);
var dataURL = this.tmpCanvasEl.toDataURL('image/png');
var tmpImg = fabric.util.createImage();
tmpImg.src = dataURL;
this.spriteImages.push(tmpImg);
},
_render: function(ctx) {
ctx.drawImage(
this.spriteImages[this.spriteIndex],
-this.width / 2,
-this.height / 2
);
},
play: function() {
var _this = this;
this.animInterval = setInterval(function() {
_this.onPlay && _this.onPlay();
_this.dirty = true;
_this.spriteIndex++;
if (_this.spriteIndex === _this.spriteImages.length) {
_this.spriteIndex = 0;
}
}, this.frameTime);
},
stop: function() {
clearInterval(this.animInterval);
}
});
fabric.Sprite.fromURL = function(url, callback, imgOptions) {
fabric.util.loadImage(url, function(img) {
callback(new fabric.Sprite(img, imgOptions));
});
};
fabric.Sprite.async = true;
function init() {
canvas = new fabric.Canvas('canvas');
rect = new fabric.Rect({
top: 100,
left: 100,
width: 1565,
height: 50, objectCaching: false,
});
canvas.add(rect);
fabric.Image.fromURL('/img/road2.jpg', function(oImg) {
patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(oImg);
patternSourceCanvas.renderAll();
pattern = new fabric.Pattern({
source: patternSourceCanvas.getElement(),
repeat: 'repeat',
});
rect.set('fill', pattern);
canvas.requestRenderAll();
document.getElementById('img-offset-x').oninput = function () {
pattern.offsetX = parseInt(this.value, 10);
console.log(pattern.offsetX)
canvas.requestRenderAll();
};
})
let createSprite = () => {
return function(sprite) {
sprite.set({
left: 500,
top: 500,
});
canvas.add(sprite);
sprite.scale(4).setCoords();
canvas.requestRenderAll();
setTimeout(function() {
sprite.set('dirty', true);
sprite.play();
}, fabric.util.getRandomInt(1, 10) * 100);
};
}
fabric.Sprite.fromURL('/img/fire.png', createSprite(), {
spriteWidth: 1200/15,
spriteHeight: 85,
});
}
function animal () {
if (pattern && patternSourceCanvas)
{
pattern.offsetX = pattern.offsetX + 2;
canvas.requestRenderAll();
}
requestAnimationFrame(animal)
}
onMounted(() => {
init()
animal()
})
</script>
<style lang="less">
.home {
height: 100%;
}
</style>