This commit is contained in:
th committed 2026-04-19 21:13:53 +02:00
1 parent cc6b11e61d
commit b977ee35a8
11 files changed
+1641 -310

No files matched your search

+81 -37
View File
@@ -89,6 +89,19 @@ const ENGINE_SOURCE = `(function(){
var kfs=scene.layers[i].keyframes;
for(var j=0;j<kfs.length;j++){ if(kfs[j].time>max) max=kfs[j].time; }
}
var instances=scene.clipInstances||[];
var clips=scene.clips||[];
var clipById={};
for(var ci=0;ci<clips.length;ci++) clipById[clips[ci].id]=clips[ci];
for(var ii=0;ii<instances.length;ii++){
var inst=instances[ii];
var cl=clipById[inst.clipId];
if(!cl) continue;
var trimS=inst.trimStart||0;
var trimE=inst.trimEnd||0;
var end=inst.startTime+Math.max(0,cl.duration-trimS-trimE);
if(end>max) max=end;
}
if(max<=0) return scene.duration;
return Math.min(max,scene.duration);
}
@@ -127,6 +140,44 @@ const ENGINE_SOURCE = `(function(){
draw(t);
requestAnimationFrame(frame);
}
function drawLayer(layer,time){
var asset=assetMap[layer.assetId];
if(!asset||!layer.visible)return;
var p=sample(layer,time);
ctx.save();
ctx.globalAlpha=ctx.globalAlpha*p.opacity;
ctx.translate(p.x,p.y);
ctx.rotate(p.rotation*Math.PI/180);
ctx.scale(p.scaleX,p.scaleY);
if(asset.kind==='rect'){
var rOffX=layer.offsetX!=null?layer.offsetX:asset.width/2;
var rOffY=layer.offsetY!=null?layer.offsetY:asset.height/2;
ctx.fillStyle=p.fill||asset.fill;
ctx.fillRect(-rOffX,-rOffY,asset.width,asset.height);
}else if(asset.kind==='circle'){
var cOffX=layer.offsetX!=null?layer.offsetX:0;
var cOffY=layer.offsetY!=null?layer.offsetY:0;
ctx.fillStyle=p.fill||asset.fill;
ctx.beginPath();
ctx.arc(-cOffX,-cOffY,asset.radius,0,Math.PI*2);
ctx.fill();
}else if(asset.kind==='text'){
var tOffX=layer.offsetX!=null?layer.offsetX:0;
var tOffY=layer.offsetY!=null?layer.offsetY:0;
ctx.fillStyle=p.fill||asset.fill;
ctx.font=asset.fontSize+'px sans-serif';
ctx.textBaseline='top';
ctx.fillText(asset.text,-tOffX,-tOffY);
}else if(asset.kind==='image'){
var img=imgs[asset.id];
if(img){
var iOffX=layer.offsetX!=null?layer.offsetX:asset.width/2;
var iOffY=layer.offsetY!=null?layer.offsetY:asset.height/2;
ctx.drawImage(img,-iOffX,-iOffY,asset.width,asset.height);
}
}
ctx.restore();
}
function draw(time){
var lw=scene.canvas.width,lh=scene.canvas.height;
var cw=size.w,ch=size.h;
@@ -144,45 +195,38 @@ const ENGINE_SOURCE = `(function(){
ctx.clip();
ctx.fillStyle=scene.canvas.background;
ctx.fillRect(0,0,lw,lh);
for(var i=scene.layers.length-1;i>=0;i--){
var layer=scene.layers[i];
if(!layer.visible)continue;
var asset=assetMap[layer.assetId];
if(!asset)continue;
var p=sample(layer,time);
ctx.save();
ctx.globalAlpha=ctx.globalAlpha*p.opacity;
ctx.translate(p.x,p.y);
ctx.rotate(p.rotation*Math.PI/180);
ctx.scale(p.scaleX,p.scaleY);
if(asset.kind==='rect'){
var rOffX=layer.offsetX!=null?layer.offsetX:asset.width/2;
var rOffY=layer.offsetY!=null?layer.offsetY:asset.height/2;
ctx.fillStyle=p.fill||asset.fill;
ctx.fillRect(-rOffX,-rOffY,asset.width,asset.height);
}else if(asset.kind==='circle'){
var cOffX=layer.offsetX!=null?layer.offsetX:0;
var cOffY=layer.offsetY!=null?layer.offsetY:0;
ctx.fillStyle=p.fill||asset.fill;
ctx.beginPath();
ctx.arc(-cOffX,-cOffY,asset.radius,0,Math.PI*2);
ctx.fill();
}else if(asset.kind==='text'){
var tOffX=layer.offsetX!=null?layer.offsetX:0;
var tOffY=layer.offsetY!=null?layer.offsetY:0;
ctx.fillStyle=p.fill||asset.fill;
ctx.font=asset.fontSize+'px sans-serif';
ctx.textBaseline='top';
ctx.fillText(asset.text,-tOffX,-tOffY);
}else if(asset.kind==='image'){
var img=imgs[asset.id];
if(img){
var iOffX=layer.offsetX!=null?layer.offsetX:asset.width/2;
var iOffY=layer.offsetY!=null?layer.offsetY:asset.height/2;
ctx.drawImage(img,-iOffX,-iOffY,asset.width,asset.height);
var layerById={};
for(var li=0;li<scene.layers.length;li++)layerById[scene.layers[li].id]=scene.layers[li];
var clipById2={};
var clips2=scene.clips||[];
for(var ci2=0;ci2<clips2.length;ci2++)clipById2[clips2[ci2].id]=clips2[ci2];
var instByTrack={};
var instances=scene.clipInstances||[];
for(var iInst=0;iInst<instances.length;iInst++){
var iE=instances[iInst];
(instByTrack[iE.clipTrackId]=instByTrack[iE.clipTrackId]||[]).push(iE);
}
var order=scene.trackOrder||[];
if(!order.length){for(var lj=0;lj<scene.layers.length;lj++)order.push(scene.layers[lj].id);}
for(var oi=order.length-1;oi>=0;oi--){
var id=order[oi];
var lyr=layerById[id];
if(lyr){ drawLayer(lyr,time); continue; }
var tInsts=instByTrack[id]||[];
for(var ti=0;ti<tInsts.length;ti++){
var inst2=tInsts[ti];
var clip2=clipById2[inst2.clipId];
if(!clip2)continue;
var tS=inst2.trimStart||0;
var tE=inst2.trimEnd||0;
var visible=Math.max(0,clip2.duration-tS-tE);
var offset=time-inst2.startTime;
if(offset<0||offset>visible)continue;
var localT=tS+offset;
for(var cl2=clip2.layers.length-1;cl2>=0;cl2--){
drawLayer(clip2.layers[cl2],localT);
}
}
ctx.restore();
}
ctx.restore();
}