瀏覽代碼

Add rotation

Entities can now be rotated. This does not affect
their height. For now, they can only be rotated by
45 degrees at a time. I will work out something nicer
later on.
master
Fen Dweller 4 年之前
父節點
當前提交
2ab9ce7d27
共有 3 個文件被更改,包括 119 次插入19 次删除
  1. +7
    -2
      macrovision.css
  2. +7
    -0
      macrovision.html
  3. +105
    -17
      macrovision.js

+ 7
- 2
macrovision.css 查看文件

@@ -48,7 +48,8 @@ body.smoothing .entity-box {
-moz-user-drag: none;
-o-user-drag: none;
--offset: -100%;
transform: translate(-50%, var(--offset));
--rotation: 30deg;
transform: translate(-50%, var(--offset)) rotate(var(--rotation));
filter: brightness(var(--brightness));
}

@@ -411,7 +412,11 @@ select {

body #test-canvas {
position: fixed;
top: 500vh;
top: 100px;
left: 400px;
z-index: 99999999;
pointer-events: none;
display: none;
}

.switch {


+ 7
- 0
macrovision.html 查看文件

@@ -143,6 +143,13 @@
<div class="options-row">
<button class="options-button" id="options-flip">Flip</button>
</div>
<div class="options-label">
Rotation
</div>
<div class="options-two-buttons" id="options-rotation">
<button id="options-rotate-left">Left</button>
<button id="options-rotate-right">Right</button>
</div>
<div class="options-label">
Brightness
</div>


+ 105
- 17
macrovision.js 查看文件

@@ -1092,6 +1092,7 @@ function makeEntity(info, views, sizes) {
name: info.name,
identifier: info.name,
scale: 1,
rotation: 0,
info: JSON.parse(JSON.stringify(info)),
views: JSON.parse(JSON.stringify(views), math.reviver),
sizes: sizes === undefined ? [] : JSON.parse(JSON.stringify(sizes), math.reviver),
@@ -1681,10 +1682,17 @@ function clearViewOptions() {
const testCanvas = document.createElement("canvas");
testCanvas.id = "test-canvas";

function rotate(point, angle) {
return [
point[0] * Math.cos(angle) - point[1] * Math.sin(angle),
point[0] * Math.sin(angle) + point[1] * Math.cos(angle)
];
}

const testCtx = testCanvas.getContext("2d");
function testClick(event) {

// oh my god I can't believe I'm doing this
testCtx.save();

const target = event.target;
if (rulerMode) {
@@ -1709,19 +1717,59 @@ function testClick(event) {
h /= ratioH;
}

// todo remove some of this unused stuff

const ratio = ratioW * ratioH;
console.log("SDFSDFSD")
console.log(ratio);
const entity = entities[target.parentElement.dataset.key];

const angle = entity.rotation;

var x = event.clientX - target.getBoundingClientRect().x,
y = event.clientY - target.getBoundingClientRect().y,
alpha;
testCtx.canvas.width = w;
testCtx.canvas.height = h;

// Draw image to canvas
// and read Alpha channel value
testCtx.drawImage(target, 0, 0, w, h);
alpha = testCtx.getImageData(Math.floor(x / ratio), Math.floor(y / ratio), 1, 1).data[3]; // [0]R [1]G [2]B [3]A
// If pixel is transparent,

[xTarget,yTarget] = [x,y];
console.log(xTarget);

[actualW, actualH] = [target.getBoundingClientRect().width, target.getBoundingClientRect().height];
xTarget -= actualW/2;
xTarget /= ratio;
xTarget += actualW/2;
yTarget -= actualH/2;
yTarget /= ratio;
yTarget += actualH/2;


testCtx.canvas.width = actualW;
testCtx.canvas.height = actualH;

testCtx.save();

// dear future me: Sorry :(

testCtx.resetTransform();


testCtx.translate(actualW/2, actualH/2);
testCtx.rotate(angle);
testCtx.translate(-actualW/2, -actualH/2);
testCtx.drawImage(target, (actualW/2 - w/2), (actualH/2 - h/2), w, h);
testCtx.fillStyle = "red";
testCtx.fillRect(actualW/2,actualH/2,10,10);

testCtx.restore();

testCtx.fillStyle = "red";
alpha = testCtx.getImageData(xTarget, yTarget, 1, 1).data[3];
testCtx.fillRect(xTarget, yTarget, 3, 3);
// console.log(testCtx.canvas.width, testCtx.canvas.height);
console.log(actualW, actualH);
// console.log(xTarget, yTarget);

// If the pixel is transparent,
// retrieve the element underneath and trigger its click event
if (alpha === 0) {
const oldDisplay = target.style.display;
@@ -1735,6 +1783,7 @@ function testClick(event) {
} else {
clickDown(target.parentElement, event.clientX, event.clientY);
}
testCtx.restore();
}

function arrangeEntities(order) {
@@ -1984,6 +2033,8 @@ function displayEntity(entity, view, x, y, selectEntity = false, refresh = false
img.style.setProperty("--offset", ((-1) * 100) + "%")
}

img.style.setProperty("--rotation", (entity.rotation * 180 / Math.PI) + "deg")

box.dataset.x = x;
box.dataset.y = y;

@@ -2359,7 +2410,7 @@ const settingsData = {
"high",
"medium",
"low",
"bottom"
"bottom",
],
get value() {
return config.groundPos;
@@ -2942,12 +2993,28 @@ document.addEventListener("DOMContentLoaded", () => {

document.querySelector("#options-brightness-down").addEventListener("click", e => {
if (selected) {
entities[selected.dataset.key].brightness = Math.max(entities[selected.dataset.key].brightness -1, 0);
entities[selected.dataset.key].brightness -= 1;
}
document.querySelector("#options-brightness-display").innerText = entities[selected.dataset.key].brightness;
updateSizes();
});

document.querySelector("#options-rotate-left").addEventListener("click", e => {
if (selected) {
entities[selected.dataset.key].rotation -= Math.PI/4;
}
selected.querySelector("img").style.setProperty("--rotation", (entities[selected.dataset.key].rotation * 180 / Math.PI) + "deg")
updateSizes();
});

document.querySelector("#options-rotate-right").addEventListener("click", e => {
if (selected) {
entities[selected.dataset.key].rotation += Math.PI/4;
}
selected.querySelector("img").style.setProperty("--rotation", (entities[selected.dataset.key].rotation * 180 / Math.PI) + "deg")
updateSizes();
});

document.querySelector("#options-flip").addEventListener("click", e => {
if (selected) {
selected.querySelector(".entity-image").classList.toggle("flipped");
@@ -4380,6 +4447,7 @@ function exportScene() {
name: entity.identifier,
customName: entity.name,
scale: entity.scale,
rotation: entity.rotation,
view: entity.view,
x: element.dataset.x,
y: element.dataset.y,
@@ -4502,6 +4570,17 @@ const migrationDefs = [
data.entities.forEach(entity => {
entity.customName = entity.name
});
},
/*
Migration: 3 -> $

Rotation is now stored
*/

data => {
data.entities.forEach(entity => {
entity.rotation = 0
});
}
]

@@ -4527,6 +4606,7 @@ function importScene(data) {
const entity = findEntity(entityInfo.name).constructor();
entity.name = entityInfo.customName;
entity.scale = entityInfo.scale;
entity.rotation = entityInfo.rotation;
entity.priority = entityInfo.priority;
entity.brightness = entityInfo.brightness;
displayEntity(entity, entityInfo.view, entityInfo.x, entityInfo.y);
@@ -4567,17 +4647,25 @@ function renderToCanvas() {

let offset = img.style.getPropertyValue("--offset");
offset = parseFloat(offset.substring(0, offset.length-1))
x = coords.x - img.getBoundingClientRect().width/2;
y = coords.y - img.getBoundingClientRect().height * (-offset/100);

let xSize = img.getBoundingClientRect().width;
let ySize = img.getBoundingClientRect().height;
let xSize = img.width;
let ySize = img.height;
x = coords.x
y = coords.y + ySize/2 + ySize * offset / 100;
const oldFilter = ctx.filter
const brightness = getComputedStyle(element).getPropertyValue("--brightness")
ctx.filter = `brightness(${brightness})`;

ctx.drawImage(img, x, y, xSize, ySize);
ctx.save();
ctx.resetTransform();
ctx.translate(x, y);
console.log(entity.rotation)
ctx.rotate(entity.rotation);
ctx.drawImage(img, -xSize/2, -ySize/2, xSize, ySize);
console.log(x,y)
ctx.restore();
ctx.drawImage(document.querySelector("#rulers"), 0, 0);
ctx.translate(-xSize/2, -ySize/2);

ctx.filter = oldFilter
});


Loading…
取消
儲存