init
This commit is contained in:
@@ -0,0 +1,401 @@
|
||||
MAX_ZOOM = 5;
|
||||
MIN_ZOOM = 0.1;
|
||||
SCROLL_SENSITIVITY = 0.0005;
|
||||
|
||||
var PublishStories = {
|
||||
main: undefined,
|
||||
back: undefined,
|
||||
video: undefined,
|
||||
videoSelect: undefined,
|
||||
canvas: undefined,
|
||||
imageCanvas: undefined,
|
||||
|
||||
canvasMinWidth: 1080,
|
||||
canvasMinHeight: 1920,
|
||||
|
||||
cameraOffset: { x: 0, y: 0 },
|
||||
cameraZoom: 1,
|
||||
isDragging: false,
|
||||
dragStart: { x: 0, y: 0 },
|
||||
initialPinchDistance: null,
|
||||
lastZoom: 1,
|
||||
|
||||
init: function () {
|
||||
PublishStories_ajaxGetContactsCount();
|
||||
|
||||
MovimTpl.loadingPage();
|
||||
|
||||
MovimTpl.pushAnchorState('story', function () {
|
||||
document.querySelector('#publishstories').classList = '';
|
||||
PublishStories.close();
|
||||
});
|
||||
|
||||
PublishStories.main = document.querySelector('#publishstories');
|
||||
PublishStories.back = document.querySelector("#publishstories #publishstoriesback");
|
||||
PublishStories.video = document.querySelector("#publishstories video");
|
||||
PublishStories.videoSelect = document.querySelector("#publishstories select#publishstoriessource");
|
||||
PublishStories.canvas = document.querySelector('#publishstories canvas');
|
||||
|
||||
PublishStories.main.addEventListener('mousemove', PublishStories.onMainPointerMove);
|
||||
|
||||
PublishStories.canvas.addEventListener('mousedown', PublishStories.onPointerDown);
|
||||
PublishStories.canvas.addEventListener('touchstart', (e) => PublishStories.handleTouch(e, PublishStories.onPointerDown));
|
||||
PublishStories.canvas.addEventListener('mouseup', PublishStories.onPointerUp);
|
||||
PublishStories.canvas.addEventListener('touchend', (e) => PublishStories.handleTouch(e, PublishStories.onPointerUp));
|
||||
PublishStories.canvas.addEventListener('mousemove', PublishStories.onPointerMove);
|
||||
PublishStories.canvas.addEventListener('touchmove', (e) => PublishStories.handleTouch(e, PublishStories.onPointerMove));
|
||||
PublishStories.canvas.addEventListener('wheel', (e) => PublishStories.adjustZoom(e.deltaY * SCROLL_SENSITIVITY));
|
||||
|
||||
PublishStories.main.querySelector('#publishstoriesswitch').onclick = () => {
|
||||
PublishStories.videoSelect.selectedIndex++;
|
||||
if (PublishStories.videoSelect.selectedIndex == -1) {
|
||||
PublishStories.videoSelect.selectedIndex = 0;
|
||||
}
|
||||
|
||||
Toast.send(PublishStories.videoSelect.options[PublishStories.videoSelect.selectedIndex].label);
|
||||
PublishStories.getStream();
|
||||
};
|
||||
|
||||
PublishStories.main.classList = 'show';
|
||||
PublishStories.back.onclick = () => { history.back(); };
|
||||
|
||||
PublishStories.close();
|
||||
PublishStories.getStream(true);
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
if (PublishStories.imageCanvas == undefined) return;
|
||||
|
||||
PublishStories.canvas.width = PublishStories.canvasMinWidth;
|
||||
PublishStories.canvas.height = PublishStories.canvasMinHeight;
|
||||
|
||||
let context = PublishStories.canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, PublishStories.canvas.width, PublishStories.canvas.height)
|
||||
context.fillStyle = MovimUtils.imageToHex(PublishStories.imageCanvas);
|
||||
context.fillRect(0, 0, PublishStories.canvas.width, PublishStories.canvas.height);
|
||||
|
||||
// Let's move!
|
||||
context.translate(PublishStories.canvas.width / 2, PublishStories.canvas.height / 2);
|
||||
context.scale(PublishStories.cameraZoom, PublishStories.cameraZoom);
|
||||
context.translate(
|
||||
-PublishStories.canvas.width / 2 + PublishStories.cameraOffset.x,
|
||||
-PublishStories.canvas.height / 2 + PublishStories.cameraOffset.y
|
||||
);
|
||||
|
||||
let adjustedHeight = PublishStories.canvas.height > PublishStories.imageCanvas.height
|
||||
? PublishStories.imageCanvas.height
|
||||
: PublishStories.canvas.height;
|
||||
|
||||
let ratio = adjustedHeight / PublishStories.imageCanvas.height;
|
||||
|
||||
context.drawImage(
|
||||
PublishStories.imageCanvas,
|
||||
PublishStories.canvas.width / 2 - PublishStories.imageCanvas.width * ratio / 2,
|
||||
PublishStories.canvas.height / 2 - adjustedHeight / 2,
|
||||
PublishStories.imageCanvas.width * ratio,
|
||||
adjustedHeight
|
||||
);
|
||||
|
||||
requestAnimationFrame(PublishStories.draw);
|
||||
},
|
||||
|
||||
goToPublish: function () {
|
||||
let title = PublishStories.main.querySelector('form textarea[name=title]');
|
||||
|
||||
if (title.value == '') {
|
||||
PublishStories_ajaxNoTitle();
|
||||
return;
|
||||
}
|
||||
|
||||
PublishStories.main.classList.add('publish');
|
||||
},
|
||||
|
||||
goToEdit: function () {
|
||||
PublishStories.main.classList.remove('publish');
|
||||
},
|
||||
|
||||
publish: function () {
|
||||
PublishStories.main.querySelector('#publishactions').classList.add('uploading');
|
||||
|
||||
PublishStories.canvas.toBlob(
|
||||
function (blob) {
|
||||
Upload.prepare(blob);
|
||||
Upload.name = 'story.jpg';
|
||||
Upload.init(true);
|
||||
},
|
||||
'image/jpeg',
|
||||
0.85
|
||||
);
|
||||
},
|
||||
|
||||
close: function () {
|
||||
if (!PublishStories.video) return;
|
||||
|
||||
let stream = PublishStories.video.srcObject;
|
||||
|
||||
if (stream) {
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
}
|
||||
|
||||
PublishStories.video.srcObject = null;
|
||||
PublishStories.imageCanvas = undefined;
|
||||
PublishStories.main.querySelector('form').reset();
|
||||
PublishStories.main.querySelector('#publishactions').classList = '';
|
||||
|
||||
PublishStories.reset();
|
||||
PublishStories.main.classList = '';
|
||||
PublishStories.main == undefined;
|
||||
},
|
||||
|
||||
openImage: function () {
|
||||
PublishStories.main.querySelector('input[type=file]').click();
|
||||
},
|
||||
|
||||
applyImage: function () {
|
||||
file = PublishStories.main.querySelector('input[type=file]').files[0];
|
||||
|
||||
if (!file.type.match(/image.*/)) {
|
||||
console.log("Not a picture !");
|
||||
PublishStories.reset();
|
||||
} else {
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.addEventListener('load', function (ev) {
|
||||
var image = new Image();
|
||||
image.src = reader.result;
|
||||
image.onload = function () {
|
||||
PublishStories.drawMediaToImageCanvas(image, image.width, image.height, 1);
|
||||
PublishStories.draw();
|
||||
PublishStories.main.classList = 'edit';
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
shoot: function () {
|
||||
if (PublishStories.imageCapture) {
|
||||
PublishStories.imageCapture.grabFrame()
|
||||
.then(image => {
|
||||
PublishStories.drawMediaToImageCanvas(
|
||||
image,
|
||||
image.width,
|
||||
image.height,
|
||||
PublishStories.getRatioFromHeight(image.height)
|
||||
);
|
||||
|
||||
PublishStories.draw();
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
|
||||
} else {
|
||||
PublishStories.drawMediaToImageCanvas(
|
||||
PublishStories.video,
|
||||
PublishStories.video.videoWidth,
|
||||
PublishStories.video.videoHeight,
|
||||
PublishStories.getRatioFromHeight(PublishStories.video.videoHeight)
|
||||
);
|
||||
|
||||
PublishStories.video.pause();
|
||||
PublishStories.draw();
|
||||
}
|
||||
|
||||
PublishStories.main.classList = 'edit';
|
||||
},
|
||||
|
||||
getRatioFromHeight: function (height) {
|
||||
let ratio = PublishStories.canvasMinHeight / height;
|
||||
if (ratio < 1) ratio = 1;
|
||||
|
||||
return ratio;
|
||||
},
|
||||
|
||||
drawMediaToImageCanvas: function (media, width, height, ratio) {
|
||||
PublishStories.imageCanvas = document.createElement('canvas');
|
||||
PublishStories.imageCanvas.width = width * ratio;
|
||||
PublishStories.imageCanvas.height = height * ratio;
|
||||
|
||||
var context = PublishStories.imageCanvas.getContext('2d');
|
||||
context.drawImage(media, 0, 0, PublishStories.imageCanvas.width, PublishStories.imageCanvas.height);
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
if (PublishStories.videoSelect.options.length > 0) {
|
||||
PublishStories.main.classList = 'shoot';
|
||||
PublishStories.video.play();
|
||||
} else {
|
||||
PublishStories.main.classList = 'shoot error';
|
||||
}
|
||||
|
||||
PublishStories.cameraOffset = { x: 0, y: 0 };
|
||||
PublishStories.cameraZoom = PublishStories.lastZoom = 1;
|
||||
},
|
||||
|
||||
getStream: function (init) {
|
||||
PublishStories.main.classList = 'wait';
|
||||
|
||||
if (PublishStories.video.srcObject) {
|
||||
PublishStories.video.srcObject.getTracks().forEach(track => track.stop());
|
||||
}
|
||||
|
||||
const videoSource = PublishStories.videoSelect.value;
|
||||
const constraints = {
|
||||
video: {
|
||||
deviceId: videoSource ? { exact: videoSource } : undefined,
|
||||
width: { ideal: 1920 },
|
||||
height: { ideal: 1920 }
|
||||
}
|
||||
};
|
||||
|
||||
navigator.mediaDevices.getUserMedia(constraints)
|
||||
.then(stream => {
|
||||
MovimTpl.finishedPage();
|
||||
PublishStories.gotStream(stream);
|
||||
|
||||
if (init) {
|
||||
navigator.mediaDevices.enumerateDevices().then(PublishStories.gotDevices);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
MovimTpl.finishedPage();
|
||||
PublishStories.noStream()
|
||||
});
|
||||
},
|
||||
|
||||
noStream: function (stream) {
|
||||
PublishStories.main.classList = 'shoot error';
|
||||
},
|
||||
|
||||
gotStream: function (stream) {
|
||||
PublishStories.main.classList = 'shoot';
|
||||
|
||||
PublishStories.videoSelect.selectedIndex = [...PublishStories.videoSelect.options].
|
||||
findIndex(option => option.text === stream.getVideoTracks()[0].label);
|
||||
PublishStories.video.srcObject = stream;
|
||||
PublishStories.video.play();
|
||||
|
||||
// We try to use ImageCapture
|
||||
if (typeof (ImageCapture) != 'undefined') {
|
||||
const track = stream.getVideoTracks()[0];
|
||||
PublishStories.imageCapture = new ImageCapture(track);
|
||||
}
|
||||
|
||||
// If we cancel after the authorization was given
|
||||
if (PublishStories.main.classList == '') {
|
||||
PublishStories.close();
|
||||
};
|
||||
},
|
||||
|
||||
gotDevices: function (devicesInfo) {
|
||||
PublishStories.videoSelect.innerHTML = '';
|
||||
|
||||
for (const deviceInfo of devicesInfo) {
|
||||
if (deviceInfo.kind === 'videoinput') {
|
||||
const option = document.createElement('option');
|
||||
option.value = deviceInfo.deviceId;
|
||||
option.text = deviceInfo.label || `Camera ${PublishStories.videoSelect.length + 1}`;
|
||||
|
||||
if (!PublishStories.videoSelect.querySelector('option[value="' + deviceInfo.deviceId + '"]')) {
|
||||
PublishStories.videoSelect.appendChild(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PublishStories.videoSelect.options.length >= 2) {
|
||||
document.querySelector("#publishstories #publishstoriesswitch").classList.add('enabled');
|
||||
}
|
||||
},
|
||||
|
||||
onPointerDown: function (e) {
|
||||
PublishStories.isDragging = true
|
||||
PublishStories.dragStart.x = MovimUtils.getEventLocation(e).x / PublishStories.cameraZoom - PublishStories.cameraOffset.x
|
||||
PublishStories.dragStart.y = MovimUtils.getEventLocation(e).y / PublishStories.cameraZoom - PublishStories.cameraOffset.y
|
||||
},
|
||||
|
||||
onPointerUp: function (e) {
|
||||
PublishStories.isDragging = false
|
||||
PublishStories.initialPinchDistance = null
|
||||
PublishStories.lastZoom = PublishStories.cameraZoom
|
||||
},
|
||||
|
||||
onMainPointerMove: function (e) {
|
||||
if (!PublishStories.main.classList.contains('edit') || !MovimUtils.getEventLocation(e)) return;
|
||||
|
||||
let borders = PublishStories.canvas.getBoundingClientRect();
|
||||
|
||||
if (MovimUtils.getEventLocation(e).x < borders.left
|
||||
|| MovimUtils.getEventLocation(e).x > borders.right
|
||||
|| MovimUtils.getEventLocation(e).y < borders.top
|
||||
|| MovimUtils.getEventLocation(e).y > borders.bottom) {
|
||||
PublishStories.onPointerUp(e);
|
||||
}
|
||||
},
|
||||
|
||||
onPointerMove: function (e) {
|
||||
if (PublishStories.isDragging) {
|
||||
PublishStories.cameraOffset.x = MovimUtils.getEventLocation(e).x / PublishStories.cameraZoom - PublishStories.dragStart.x
|
||||
PublishStories.cameraOffset.y = MovimUtils.getEventLocation(e).y / PublishStories.cameraZoom - PublishStories.dragStart.y
|
||||
}
|
||||
},
|
||||
|
||||
handleTouch: function (e, singleTouchHandler) {
|
||||
if (e.touches.length == 1) {
|
||||
singleTouchHandler(e)
|
||||
}
|
||||
else if (e.type == "touchmove" && e.touches.length == 2) {
|
||||
PublishStories.isDragging = false
|
||||
PublishStories.handlePinch(e)
|
||||
}
|
||||
},
|
||||
|
||||
handlePinch: function (e) {
|
||||
e.preventDefault()
|
||||
|
||||
let touch1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }
|
||||
let touch2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }
|
||||
|
||||
// This is distance squared, but no need for an expensive sqrt as it's only used in ratio
|
||||
let currentDistance = (touch1.x - touch2.x) ** 2 + (touch1.y - touch2.y) ** 2
|
||||
|
||||
if (PublishStories.initialPinchDistance == null) {
|
||||
PublishStories.initialPinchDistance = currentDistance
|
||||
}
|
||||
else {
|
||||
PublishStories.adjustZoom(null, currentDistance / PublishStories.initialPinchDistance)
|
||||
}
|
||||
},
|
||||
|
||||
adjustZoom: function (zoomAmount, zoomFactor) {
|
||||
if (!PublishStories.isDragging) {
|
||||
if (zoomAmount) {
|
||||
PublishStories.cameraZoom += zoomAmount
|
||||
}
|
||||
else if (zoomFactor) {
|
||||
PublishStories.cameraZoom = zoomFactor * PublishStories.lastZoom
|
||||
}
|
||||
|
||||
PublishStories.cameraZoom = Math.min(PublishStories.cameraZoom, MAX_ZOOM)
|
||||
PublishStories.cameraZoom = Math.max(PublishStories.cameraZoom, MIN_ZOOM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MovimEvents.registerWindow('loaded', 'publishstories', () => {
|
||||
Upload.attach((file) => {
|
||||
if (PublishStories.main && PublishStories.main.classList.contains('publish')) {
|
||||
PublishStories.main.querySelector('#publishactions').classList.remove('uploading');
|
||||
PublishStories.main.querySelector('#publishactions').classList.add('publishing');
|
||||
PublishStories_ajaxPublish(MovimUtils.formToJson('metadata'), file.id);
|
||||
}
|
||||
});
|
||||
|
||||
Upload.fail(() => {
|
||||
PublishStories.main.querySelector('#publishactions').classList.remove('uploading');
|
||||
});
|
||||
|
||||
Upload.progress((percent) => {
|
||||
if (PublishStories.main != undefined && PublishStories.main.classList.contains('publish')) {
|
||||
PublishStories.main.querySelector('#publishactionsprogress').innerHTML =
|
||||
percent + '%';
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user