mirror of
https://github.com/andrewstephens75/as-dithered-image.git
synced 2026-04-22 08:09:30 -07:00
Got drag and drop working
This commit is contained in:
@@ -50,7 +50,7 @@ class ASDitheredImage extends HTMLElement {
|
|||||||
this.canvas_.classList.add("ditheredImageStyle")
|
this.canvas_.classList.add("ditheredImageStyle")
|
||||||
shadowDOM.appendChild(this.canvas_)
|
shadowDOM.appendChild(this.canvas_)
|
||||||
|
|
||||||
this.context_ = this.canvas_.getContext("2d")
|
this.context_ = this.canvas_.getContext("2d", { willReadFrequently: true })
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(((entries) => {
|
const resizeObserver = new ResizeObserver(((entries) => {
|
||||||
// browsers generated lots of resize events but we don't want to start refreshing until
|
// browsers generated lots of resize events but we don't want to start refreshing until
|
||||||
@@ -90,6 +90,7 @@ class ASDitheredImage extends HTMLElement {
|
|||||||
|
|
||||||
if ((name === "src")) {
|
if ((name === "src")) {
|
||||||
this.force_refresh_ = true
|
this.force_refresh_ = true
|
||||||
|
this.original_image_ = undefined
|
||||||
this.requestUpdate()
|
this.requestUpdate()
|
||||||
} else if (name === "crunch") {
|
} else if (name === "crunch") {
|
||||||
if (newValue === "auto") {
|
if (newValue === "auto") {
|
||||||
@@ -136,7 +137,7 @@ class ASDitheredImage extends HTMLElement {
|
|||||||
|
|
||||||
getDevicePixelRatio() {
|
getDevicePixelRatio() {
|
||||||
// this should always be an integer for the dithering code to work
|
// this should always be an integer for the dithering code to work
|
||||||
return Math.floor(window.devicePixelRatio)
|
return window.devicePixelRatio
|
||||||
}
|
}
|
||||||
|
|
||||||
// all drawing is funneled through requestUpdate so that multiple calls are coalesced to prevent
|
// all drawing is funneled through requestUpdate so that multiple calls are coalesced to prevent
|
||||||
@@ -166,7 +167,8 @@ class ASDitheredImage extends HTMLElement {
|
|||||||
this.image_loading_ = false
|
this.image_loading_ = false
|
||||||
this.original_image_ = image
|
this.original_image_ = image
|
||||||
this.ignore_next_resize_ = true
|
this.ignore_next_resize_ = true
|
||||||
this.style.aspectRatio = this.original_image_.width + "/" + this.original_image_.height
|
this.canvas_.style.aspectRatio = this.original_image_.width + "/" + this.original_image_.height
|
||||||
|
console.log("Setting Aspect Ratio to ", this.style.aspectRatio)
|
||||||
this.force_refresh_ = true
|
this.force_refresh_ = true
|
||||||
this.requestUpdate()
|
this.requestUpdate()
|
||||||
}).bind(this)
|
}).bind(this)
|
||||||
@@ -182,12 +184,22 @@ class ASDitheredImage extends HTMLElement {
|
|||||||
const rect = this.canvas_.getBoundingClientRect()
|
const rect = this.canvas_.getBoundingClientRect()
|
||||||
let screenPixelsToBackingStorePixels = this.getDevicePixelRatio()
|
let screenPixelsToBackingStorePixels = this.getDevicePixelRatio()
|
||||||
let fractionalPart = screenPixelsToBackingStorePixels - Math.floor(screenPixelsToBackingStorePixels)
|
let fractionalPart = screenPixelsToBackingStorePixels - Math.floor(screenPixelsToBackingStorePixels)
|
||||||
|
|
||||||
|
// that's it! I am officially giving up on trying to account for all the weird pixelDeviceRatios that Chrome likes
|
||||||
|
// to serve up at different zoom levels. I can understand nice fractions like 2.5 but 1.110004 and 0.89233 are just stupid
|
||||||
|
// If the fractional part doesn't make sense then just ignore it. This will give incorrect results but they still look
|
||||||
|
// pretty good if you don't look too closely.
|
||||||
|
if ((1.0 / fractionalPart) > 3) {
|
||||||
|
fractionalPart = 0
|
||||||
|
screenPixelsToBackingStorePixels = Math.round(screenPixelsToBackingStorePixels)
|
||||||
|
}
|
||||||
if (fractionalPart != 0) {
|
if (fractionalPart != 0) {
|
||||||
screenPixelsToBackingStorePixels = Math.round(screenPixelsToBackingStorePixels * Math.round(1.0 / fractionalPart))
|
screenPixelsToBackingStorePixels = Math.round(screenPixelsToBackingStorePixels * Math.round(1.0 / fractionalPart))
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculatedWidth = rect.width * screenPixelsToBackingStorePixels
|
const calculatedWidth = Math.round(rect.width * screenPixelsToBackingStorePixels)
|
||||||
const calculatedHeight = rect.height * screenPixelsToBackingStorePixels
|
const calculatedHeight = Math.round(rect.height * screenPixelsToBackingStorePixels)
|
||||||
|
console.log(calculatedWidth, "x", calculatedHeight, "(" + screenPixelsToBackingStorePixels + ")")
|
||||||
let adjustedPixelSize = screenPixelsToBackingStorePixels * this.crunchFactor_
|
let adjustedPixelSize = screenPixelsToBackingStorePixels * this.crunchFactor_
|
||||||
|
|
||||||
// double check - we may have already painted this image
|
// double check - we may have already painted this image
|
||||||
|
|||||||
36
test.html
36
test.html
@@ -27,10 +27,23 @@
|
|||||||
<option value="4">4</option>
|
<option value="4">4</option>
|
||||||
</select>
|
</select>
|
||||||
<input id="cutoff" type="range" min="0.0" max="1.0" step="0.05" value="any" />
|
<input id="cutoff" type="range" min="0.0" max="1.0" step="0.05" value="any" />
|
||||||
|
<input id="choosefile" type="file" />
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function displayFromFile(file) {
|
||||||
|
if (!file.type.startsWith("image/")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
document.getElementById("picture").setAttribute("src", e.target.result)
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById("dpr").innerText = window.devicePixelRatio
|
document.getElementById("dpr").innerText = window.devicePixelRatio
|
||||||
let select = document.getElementById("crunchselect")
|
let select = document.getElementById("crunchselect")
|
||||||
select.addEventListener("change", e => {
|
select.addEventListener("change", e => {
|
||||||
@@ -42,6 +55,29 @@
|
|||||||
document.getElementById("picture").setAttribute("cutoff", e.target.value)
|
document.getElementById("picture").setAttribute("cutoff", e.target.value)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
document.getElementById("choosefile").addEventListener("change", e => {
|
||||||
|
const files = e.target.files
|
||||||
|
if (files.length == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
displayFromFile(files[0])
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
const pictureElement = document.getElementById("picture")
|
||||||
|
pictureElement.addEventListener("drop", e => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (e.dataTransfer.files.length == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
displayFromFile(e.dataTransfer.files[0])
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
pictureElement.addEventListener("dragover", e => {
|
||||||
|
e.preventDefault() // need this to disable the default
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user