Skip to content
This repository has been archived by the owner on Jul 8, 2020. It is now read-only.

Commit

Permalink
Merge pull request #102 from shundroid/#76
Browse files Browse the repository at this point in the history
fixed #76 Sequence-Viewにアニメーションを追加
  • Loading branch information
dadaa committed May 9, 2016
2 parents 27c85a3 + 7aee5ea commit ff75587
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 53 deletions.
2 changes: 0 additions & 2 deletions js/canvas-model.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import eventPublisher from "./publisher";

// HTMLCanvasElementをラップし, canvasRenderingContext2Dに関する操作を提供する
function CanvasModel(element) {
this.element = element;
Expand Down
33 changes: 24 additions & 9 deletions js/frames-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,34 @@ function FramesController(canvas) {
eventPublisher.subscribe("currentFrameId", updateImageDataToNextData);
}

// パラメータ id : どこの後ろに追加するのか(今は実装していない)
FramesController.prototype.append = function(id) {
// パラメータ frameId : どこの後ろに追加するのか(今は実装していない)
FramesController.prototype.append = function(frameId) {
const frame = new Frame();
// 今はいいが、あとで splice に変える
this.frames.push(frame);
eventPublisher.publish("frames", this.frames);
eventPublisher.publish("frames", {
frames: this.frames,
action: "append",
actionFrame: this.frames.length - 1
});
};

FramesController.prototype.remove = function(id) {
FramesController.prototype.remove = function(frameId) {
if (this.frames.length <= 1) {
throw new Error("残りフレーム数が1なので、削除することができません。");
}
let nextCurrentFrameId = this.currentFrameId;
if (this.currentFrameId >= this.frames.length - 1) {
nextCurrentFrameId--;
}
this.frames.splice(id, 1);
this.frames.splice(frameId, 1);
this.canvasModel.setImageData(
this.getFrameById(nextCurrentFrameId).imageData);
eventPublisher.publish("frames", this.frames);
eventPublisher.publish("frames", {
frames: this.frames,
action: "remove",
actionFrame: frameId
});
eventPublisher.publish("currentFrameId", nextCurrentFrameId);
};

Expand All @@ -55,9 +63,12 @@ FramesController.prototype.moveFrame = function(frameId, moveDirection) {
this.frames[frameId] = frameTmp;
// currentFrameの内容が変わった可能性があるため、再描画する
this.canvasModel.setImageData(this.frames[this.currentFrameId].imageData);
eventPublisher.publish("frames", this.frames);
eventPublisher.publish("frames", {
frames: this.frames,
action: "moveUp",
actionFrame: frameId
});
} else if (moveDirection === "down") {
// ここに下に移動する方法も書いて
if (frameId >= this.frames.length - 1) {
return;
}
Expand All @@ -66,7 +77,11 @@ FramesController.prototype.moveFrame = function(frameId, moveDirection) {
this.frames[frameId] = frameTmp;

this.canvasModel.setImageData(this.frames[this.currentFrameId].imageData);
eventPublisher.publish("frames", this.frames);
eventPublisher.publish("frames", {
frames: this.frames,
action: "moveDown",
actionFrame: frameId
});
}
};

Expand Down
147 changes: 105 additions & 42 deletions js/view/sequence-view.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import eventPublisher from "./../publisher";

const DISABLE_FRAME_ID = -1;

function SequencePanel(elem, framesController) {
this.elem = elem;
this.maxFrameId = 0;
this.currentFrameId = 0;
this.framesController = framesController;
eventPublisher.subscribe("currentFrameId", (currentFrameId) => {
this.currentFrameId = currentFrameId;
this.setCurrentFrame(currentFrameId);
});
eventPublisher.subscribe("frames", (frames) => {
this.clear();
for (this.maxFrameId = 0;
this.maxFrameId < frames.length; this.maxFrameId++) {
this.append(this.maxFrameId);
eventPublisher.subscribe("frames", (frameDetail) => {
if (frameDetail.action === "append") {
this.append();
} else if (frameDetail.action === "remove") {
this.remove(frameDetail.actionFrame);
} else if (frameDetail.action === "moveUp") {
this.moveUp(frameDetail.actionFrame);
} else if (frameDetail.action === "moveDown") {
this.moveDown(frameDetail.actionFrame);
}
this.maxFrameId--; // 1つ多くなってしまうから
this.setCurrentFrame(this.currentFrameId);
});
document.getElementById("sequence-add-btn").addEventListener("click", () => {
this.framesController.append(++this.maxFrameId);
this.framesController.append();
});
}

Expand All @@ -37,68 +40,128 @@ function SequencePanel(elem, framesController) {
</div>
</div>
*/
function getFrameTemplate(
frameId,
mousedownFrameCallback,
mousedownRemoveCallback,
frameUpBtnCallback,
frameDownBtnCallback) {
SequencePanel.prototype.getFrameTemplate = function(frameId) {
let frame = document.createElement("div");
let frameDeleteBtn = document.createElement("button");
let frameUpBtn = document.createElement("button");
let frameDownBtn = document.createElement("button");
frame.dataset.frameIndex = frameId;
frame.classList.add("thumbnail");
frame.addEventListener("mousedown", mousedownFrameCallback);
frame.addEventListener("mousedown", (event) => {
// 子要素のmousedownによる発生を防ぐ
if (event.target.classList.contains("thumbnail")) {
eventPublisher.publish("currentFrameId", frame.dataset.frameIndex);
this.setCurrentFrame(frame);
}
});
frameDeleteBtn.classList.add("frame-delete");
frameUpBtn.classList.add("frame-up");
frameUpBtn.addEventListener("mousedown", frameUpBtnCallback);
frameUpBtn.addEventListener("mousedown", () => {
this.framesController.moveFrame(parseInt(frame.dataset.frameIndex), "up");
});
frameDownBtn.classList.add("frame-down");
frameDownBtn.addEventListener("mousedown", frameDownBtnCallback);
frameDownBtn.addEventListener("mousedown", () => {
this.framesController.moveFrame(parseInt(frame.dataset.frameIndex), "down");
});
frameDeleteBtn.innerHTML = "<i class=\"fa fa-times\"></i>";
frameDeleteBtn.addEventListener("mousedown", mousedownRemoveCallback);
frameDeleteBtn.addEventListener("mousedown", () => {
// フレーム数が1つの時は、エラーになるため削除しない。
if (this.getMaxFrameId() > 0) {
this.framesController.remove(frame.dataset.frameIndex);
}
});
frameUpBtn.innerHTML = "<i class=\"fa fa-sort-asc\"></i>";
frameDownBtn.innerHTML = "<i class=\"fa fa-sort-desc\"></i>";
frame.appendChild(frameDeleteBtn);
frame.appendChild(frameUpBtn);
frame.appendChild(frameDownBtn);

return frame;
}
};

SequencePanel.prototype.appendToggleFrameEffect = function(frame, isAppend) {
let direction = isAppend ? "alternate" : "alternate-reverse";
frame.animate(
[{ transformOrigin: "0px 0px", transform: "scaleY(0)" },
{ transformOrigin: "0px 100%", transform: "scaleY(1)" }],
{ direction: direction, duration: 250,
fill: "both", easing: "ease-in-out" });
};
SequencePanel.prototype.appendMoveFrameEffect = function(
frame, isMoveDown, frameHeight) {
let beginningValue = (isMoveDown ? "" : "-") + frameHeight;
frame.animate(
[{ transform: `translateY(${beginningValue})` },
{ transform: "translateY(0px)" }],
{ direction: "alternate", duration: 250,
fill: "both", easing: "ease-in-out" });
};

SequencePanel.prototype.append = function() {
let newFrame = this.getFrameTemplate(0);
// 追加アニメーションを実行
this.appendToggleFrameEffect(newFrame, true);

SequencePanel.prototype.append = function(frameId) {
let newFrame = getFrameTemplate(frameId, (event) => {
// 子要素のmousedownによる発生を防ぐ
if (event.target.classList.contains("thumbnail")) {
eventPublisher.publish("currentFrameId", frameId);
this.setCurrentFrame(newFrame);
}
}, () => {
// フレーム数が1つの時は、エラーになるため削除しない。
if (this.maxFrameId > 0) {
this.framesController.remove(frameId);
}
}, () => {
this.framesController.moveFrame(frameId, "up");
}, () => {
this.framesController.moveFrame(frameId, "down");
});
this.elem.appendChild(newFrame);
this.renumber();
};

SequencePanel.prototype.clear = function() {
this.elem.innerHTML = "";
};

SequencePanel.prototype.remove = function(frame) {
SequencePanel.prototype.remove = function(frameId) {
let frame = this.elem.querySelector(`[data-frame-index=\"${frameId}\"]`);
frame.dataset.frameIndex = DISABLE_FRAME_ID;
this.appendToggleFrameEffect(frame, false);

this.renumber();

setTimeout(() => {
this.elem.removeChild(frame);
}, 250);
};

SequencePanel.prototype.renumber = function() {
let children = this.elem.children;
let disableFrameCount = 0;
let childNode;
let index = 0;
while (
typeof (childNode = children[index + disableFrameCount]) !== "undefined") {
if (typeof childNode.dataset === "undefined" ||
parseInt(childNode.dataset.frameIndex) === -1) {
disableFrameCount++;
continue;
}
childNode.dataset.frameIndex = index++;
}
this.setCurrentFrame(this.currentFrameId);
};

SequencePanel.prototype.getMaxFrameId = function() {
return this.elem.children.length - 1;
};

SequencePanel.prototype.moveUp = function() {
// TODO
SequencePanel.prototype.moveUp = function(frameId) {
// 表示上では、frameIdの1つ上の要素を下にしているのと同じである。
this.moveDown(frameId - 1);
};

SequencePanel.prototype.moveDown = function() {
// TODO
SequencePanel.prototype.moveDown = function(frameId) {
let moveDownFrame =
this.elem.querySelector(`[data-frame-index=\"${frameId}\"]`);
let moveUpFrame =
this.elem.querySelector(`[data-frame-index=\"${(frameId + 1)}\"]`);
this.elem.removeChild(moveDownFrame);
this.elem.insertBefore(moveDownFrame, moveUpFrame);

this.renumber();

this.appendMoveFrameEffect(moveDownFrame, true,
getComputedStyle(moveUpFrame).height);
this.appendMoveFrameEffect(moveUpFrame, false,
getComputedStyle(moveDownFrame).height);
};

SequencePanel.prototype.setCurrentFrame = function(frameIndex) {
Expand Down

0 comments on commit ff75587

Please sign in to comment.