Add output camera framing
This commit is contained in:
1 parent
616ced17ce
commit
23a66c6fdf
19 files changed
+1955
-43
No files matched your search
@@ -102,6 +102,56 @@
|
||||
}
|
||||
return merge(layer.base);
|
||||
}
|
||||
function defaultCameraProps(scene){
|
||||
return {
|
||||
x:0,
|
||||
y:0,
|
||||
width:Math.max(1, Number(scene.canvas && scene.canvas.width) || 1280),
|
||||
height:Math.max(1, Number(scene.canvas && scene.canvas.height) || 720)
|
||||
};
|
||||
}
|
||||
function mergeCameraProps(base, props){
|
||||
props=props||{};
|
||||
function finite(v, fallback){ return typeof v==='number' && isFinite(v) ? v : fallback; }
|
||||
return {
|
||||
x:finite(props.x, base.x),
|
||||
y:finite(props.y, base.y),
|
||||
width:Math.max(1, finite(props.width, base.width)),
|
||||
height:Math.max(1, finite(props.height, base.height))
|
||||
};
|
||||
}
|
||||
function lerpCameraProps(a,b,t){
|
||||
return {
|
||||
x:lerp(a.x,b.x,t),
|
||||
y:lerp(a.y,b.y,t),
|
||||
width:Math.max(1, lerp(a.width,b.width,t)),
|
||||
height:Math.max(1, lerp(a.height,b.height,t))
|
||||
};
|
||||
}
|
||||
function sampleCamera(scene,time){
|
||||
var camera=scene.camera;
|
||||
var base=defaultCameraProps(scene);
|
||||
if(!camera) return base;
|
||||
base=mergeCameraProps(base, camera.base);
|
||||
var kfs=(camera.keyframes||[]).slice().sort(function(a,b){return a.time-b.time;});
|
||||
if(!kfs.length) return base;
|
||||
if(time<=kfs[0].time) return mergeCameraProps(base,kfs[0].props);
|
||||
var last=kfs[kfs.length-1];
|
||||
if(time>=last.time) return mergeCameraProps(base,last.props);
|
||||
for(var i=0;i<kfs.length-1;i++){
|
||||
var a=kfs[i], b=kfs[i+1];
|
||||
if(time>=a.time && time<=b.time){
|
||||
if(a.hold){
|
||||
if(time>=b.time) return mergeCameraProps(base,b.props);
|
||||
return mergeCameraProps(base,a.props);
|
||||
}
|
||||
var raw=(time-a.time)/Math.max(1e-9,b.time-a.time);
|
||||
var tt=easing(b.easing,raw);
|
||||
return lerpCameraProps(mergeCameraProps(base,a.props), mergeCameraProps(base,b.props), tt);
|
||||
}
|
||||
}
|
||||
return base;
|
||||
}
|
||||
function loadImages(assets){
|
||||
var imgs={};
|
||||
var list=assets.filter(function(a){return a.kind==='image';});
|
||||
@@ -267,8 +317,17 @@
|
||||
function drawFrame(time){
|
||||
if(!scene) return;
|
||||
var lw=scene.canvas.width, lh=scene.canvas.height;
|
||||
var useCamera=!!(scene.camera && scene.camera.enabled);
|
||||
var cam=useCamera?sampleCamera(scene,time):null;
|
||||
ctx.setTransform(1,0,0,1,0,0);
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
ctx.save();
|
||||
ctx.beginPath(); ctx.rect(0,0,lw,lh); ctx.clip();
|
||||
if(useCamera){
|
||||
ctx.scale(lw/cam.width, lh/cam.height);
|
||||
ctx.translate(-cam.x,-cam.y);
|
||||
ctx.beginPath(); ctx.rect(0,0,lw,lh); ctx.clip();
|
||||
}
|
||||
if(!scene.backgroundVideo){
|
||||
ctx.fillStyle=scene.canvas.background;
|
||||
ctx.fillRect(0,0,lw,lh);
|
||||
|
||||
Reference in new issue
Block a user