3dimageflipdisplaygithub
Version:
This is a simple example demonstrating how to create a 3D image flip display effect using HTML canvas and JavaScript. The entire functionality is contained within a single index.js file.
412 lines (369 loc) • 11.1 kB
JavaScript
class AnimationController {
constructor() {
this.animationSpeed = 1;
this.angleIncrement = 1;
this.paused = false;
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d");
this.canvasWidth = this.canvas.width = 400;
this.canvasHeight = this.canvas.height = 400;
this.imageUrl = "https://via.placeholder.com/400";
this.image = new Image();
this.image.src = this.imageUrl;
this.image.onload = () => this.render();
this.initEventListeners();
}
initEventListeners() {
document.getElementById("speed-up").addEventListener("click", () => {
this.animationSpeed += 0.1;
});
document.getElementById("speed-down").addEventListener("click", () => {
this.animationSpeed -= 0.1;
if (this.animationSpeed < 0) {
this.animationSpeed = 0;
}
});
document.getElementById("pause-play").addEventListener("click", () => {
this.paused = !this.paused;
if (!this.paused) {
this.render();
}
});
}
render() {
if (!this.paused) {
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
this.ctx.save();
this.ctx.translate(this.canvasWidth / 2, this.canvasHeight / 2);
let angle = Math.PI / 180 * this.angleIncrement * this.animationSpeed;
this.ctx.rotate(angle);
this.ctx.drawImage(this.image, -this.canvasWidth / 2, -this.canvasHeight / 2, this.canvasWidth, this.canvasHeight);
this.ctx.restore();
requestAnimationFrame(() => this.render());
}
}
}
const controller = new AnimationController();
import { translate } from "./lib/translate.js";
import { transSingleType } from "./lib/variation.js";
export default class CardData {
constructor(dbData, admin, color) {
this.dbData = dbData;
this.admin = admin;
if (admin.recover) {
for (let key in dbData) {
if (localStorage.getItem(key)) {
dbData[key] = localStorage.getItem(key);
}
}
}
let textUpdate = ["type4", "level", "attack", "defend", "cardbag"];
for (let key of textUpdate) {
Object.defineProperty(this, key, {
get() {
return dbData[key];
},
set(value) {
if (key === "type4") {
value = transSingleType(value);
}
dbData[key] = value;
this.draw();
},
});
}
let fontUpdate = ["name", "desc", "race"];
let tempText = {};
for (let key of fontUpdate) {
tempText[key] = translate(dbData[key]);
Object.defineProperty(this, key, {
get() {
if (this.admin.translate) {
return tempText[key];
} else {
return dbData[key];
}
},
set(value) {
let transValue;
if (this.admin.translate) {
transValue = translate(value);
}
dbData[key] = value;
tempText[key] = transValue;
this.draw(["text"], key);
},
});
}
Object.defineProperty(this, "lb_desc", {
get() {
if (dbData.lb_desc) return dbData.lb_desc;
let desc = this._desc_;
return this._lb_desc;
},
set(value) {
if (this.admin.translate) {
value = translate(value);
}
dbData.lb_desc = value;
this.draw(["text"], "lb_desc");
},
});
Object.defineProperty(this, "lb_num", {
get() {
if (dbData.lb_num) return dbData.lb_num;
let desc = this._desc_;
return this._lb_num;
},
set(value) {
dbData.lb_num = value;
this.draw(["text"], "lb_num");
},
});
Object.defineProperty(this, "type", {
get() {
return dbData.type;
},
set(value) {
let update = ["mold", "level", "attribute"];
if (
(value === "monster" && dbData.type !== "monster") ||
(value !== "monster" && dbData.type === "monster")
) {
dbData.type2 = "tc";
dbData.type3 = null;
dbData.type4 = null;
update.push("type");
}
dbData.type = value;
this.draw(update);
},
});
let moldUpdate = ["type2", "type3"];
for (let key of moldUpdate) {
Object.defineProperty(this, key, {
get() {
return dbData[key];
},
set(value) {
value = transSingleType(value);
dbData[key] = value;
if (dbData["type"] === "monster") {
let fileList = ["mold", "level", "attribute"];
if (dbData["type2"] === "lj") {
fileList = fileList.concat([
"arrow1_0",
"arrow1_1",
"arrow2_0",
"arrow2_1",
]);
}
this.draw(fileList);
} else {
this.draw(["mold", "level", "attribute", "icon"]);
}
},
});
}
Object.defineProperty(this, "attribute", {
get() {
return dbData["attribute"];
},
set(value) {
dbData["attribute"] = value;
this.draw(["attribute"]);
},
});
Object.defineProperty(this, "lang", {
get() {
return this.admin.lang;
},
set(value) {
this.admin.lang = value;
this.draw(["attribute"]);
},
});
Object.defineProperty(this, "copyright", {
get() {
if (dbData.copyright) {
return dbData.copyright;
}
return this.admin.copyright || '';
},
set(value) {
this.admin.copyright = value;
dbData.copyright = value;
this.draw(["text"]);
},
});
Object.defineProperty(this, "link", {
get() {
return this._link_;
},
set(value) {
dbData["link"] = value;
this.draw();
},
});
Object.defineProperty(this, "_id", {
get() {
return dbData["_id"];
},
set(value) {
dbData["_id"] = value;
//this.admin.key = value;
this.draw(["pic"]);
},
});
Object.defineProperty(this, "color", {
get() {
if (!color) {
return this.defaultColor;
}
return color;
},
set(value) {
color = value;
this.draw(["text"]);
},
});
Object.defineProperty(this, "outlineColor", {
set(value) {
outlineColor = value;
this.draw["text"];
},
});
var flash = 0;
Object.defineProperty(this, "flash", {
get() {
return flash;
},
set(value) {
flash = value;
this.draw();
},
});
this.caller = null;
this.getData = function () {
let res = {};
for (let key in dbData) {
res[key] = dbData[key];
}
return res;
};
this.saveToCache = function () {
for (let key in dbData) {
localStorage.setItem(key, dbData[key]);
}
};
}
get _attribute_() {
const attribute = this.attribute;
const trans = this.admin.config.translate;
return trans.attribute[attribute];
}
get isSpecialMonster() {
return ["rh", "ys", "rh", "tt", "cl", "lj"].includes(this.type2);
}
get _ifm_() {
const trans = this.admin.config.translate;
let tc = trans.type.tc;
let xg = trans.type.xg;
let lb = trans.type.lb;
let rc = trans.race;
let brackets = trans.brackets;
const race = this.race;
if (this.type === "monster") {
var txt = brackets[0] + (rc[race] || race);
if (!["tc", "xg", "tk"].includes(this.type2)) {
txt += "/" + trans.type[this.type2];
}
if (this.type3 !== "tc" && this.type3 !== null && this.type3 !== "") {
if (this.type3 === "lb") {
var type3 = lb;
} else {
var type3 = trans.type[this.type3];
}
txt += "/" + type3;
}
if (
this.type4 !== "tc" &&
this.type4 !== null &&
this.type4 !== "" &&
this.type4 !== this.type3
) {
txt += "/" + trans.type[this.type4];
}
if (this.type2 !== "tc" && this.type3 !== "tc" && this.type4 !== "tc") {
txt += "/" + xg + brackets[1];
} else {
if (!this.isSpecialMonster) {
txt += "/" + tc + brackets[1];
} else {
txt += brackets[1];
}
}
return txt;
} else if (this.type === "spell") {
return brackets[0] + trans.spell + brackets[1];
} else {
return brackets[0] + trans.trap + brackets[1];
}
}
get _spellType_() {
let type;
let brackets = this.admin.config.translate.brackets;
if (this.type === "spell") {
let text = this.admin.config.translate.spell;
type = brackets[0] + text;
} else {
let text = this.admin.config.translate.trap;
type = brackets[0] + text;
}
if (["cd", "fj", "sg", "ys", "yx", "zb"].includes(this.type2)) {
type += (this.lang === "en" ? " " : " ") + brackets[1];
} else {
type += brackets[1];
}
return type;
}
get _link_() {
if (this.type2 !== 'lj') {
this.link_num = 0;
return [false, false, false, false, false, false, false, false];
}
let link = [];
if (this.dbData.link instanceof Array && this.dbData.link.length >= 8) {
link = this.dbData.link.slice(0, 8);
} else {
const LINK_DIRECTION_SOUTHWEST = 0x1, LINK_DIRECTION_SOUTH = 0x2, LINK_DIRECTION_SOUTHEAST = 0x4,
LINK_DIRECTION_WEST = 0x8, LINK_DIRECTION_EAST = 0x20, LINK_DIRECTION_NORTHWEST = 0x40, LINK_DIRECTION_NORTH = 0x80,
LINK_DIRECTION_NORTHEAST = 0x100;
const MARKER_POSITIONS = [LINK_DIRECTION_NORTHWEST, LINK_DIRECTION_NORTH, LINK_DIRECTION_NORTHEAST, LINK_DIRECTION_WEST,
LINK_DIRECTION_EAST, LINK_DIRECTION_SOUTHWEST, LINK_DIRECTION_SOUTH, LINK_DIRECTION_SOUTHEAST];
const linkInt = this.defend;
for(const i in MARKER_POSITIONS) {
link.push((linkInt & MARKER_POSITIONS[i]) === MARKER_POSITIONS[i]);
}
}
this.link_num = link.reduce((num, item) => {
num += item ? 1 : 0;
return num;
}, 0);
return link;
}
get defaultColor() {
if (this.type === "monster") {
if (this.type2 === "cl" || this.type2 === "lj") {
return "#fff";
} else {
return "#000";
}
} else {
return "#fff";
}
}
draw(key, who) {
this.admin.cardFile.update(key, who);
}
}