transform: scaleX(-1) されている要素のx座標を求める @see https://blog.shimabox.net/2019/03/18/face_recognition_with_clmtrakr-js_and_draw_henohenomoheji/
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>transform: scaleX(-1) されている要素のx座標を求める</title> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width,initial-scale=1"> | |
<style> | |
body { | |
background: #b1acacb3; | |
} | |
.container { | |
height: 100vh; | |
display: flex; | |
align-items: center; | |
flex-direction: column; | |
} | |
.container h3 { | |
margin: 0; | |
} | |
.container canvas { | |
width: 320px; | |
height: 240px; | |
background: #fff; | |
} | |
.canvas-wrapper { | |
height: 100vh; | |
display: flex; | |
flex-direction: column; | |
justify-content: space-around; | |
} | |
#transform-scaleX-canvas { | |
transform: scaleX(-1); | |
} | |
.desc { | |
font-weight: bold; | |
text-align: center; | |
display: block; | |
font-size: 0.9em; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="buttons"> | |
<input type="radio" name="scaleX" value="1" id="style_1" checked> | |
<label for="style_1">離す</label> | |
</input> | |
<input type="radio" name="scaleX" value="2" id="style_2"> | |
<label for="style_2">くっつける</label> | |
</input> | |
<input type="radio" name="scaleX" value="3" id="style_3"> | |
<label for="style_3">重ねる</label> | |
</input> | |
</div> | |
<div class="canvas-wrapper"> | |
<div class="desc"><span>通常</span></div> | |
<canvas id="canvas"></canvas> | |
<div class="desc"><span>transform: scaleX(-1)</span></div> | |
<canvas id="transform-scaleX-canvas"></canvas> | |
<div class="desc"><span>(transform: scaleX(-1) されている要素の)<br>x座標 = canvas幅 - x座標 - 文字の幅</span></div> | |
<canvas id="not-scaleX-canvas"></canvas> | |
</div> | |
</div> | |
<script> | |
'use strict'; | |
const txt = 'あ'; | |
const positionX = 200; | |
// Top. | |
const canvas = document.querySelector('#canvas'); | |
const ctx = canvas.getContext('2d'); | |
ctx.font = "4em 'sans-serif'"; | |
const ctxFontWidth = ctx.measureText(txt).width; | |
ctx.fillText(txt, positionX, ctxFontWidth); | |
// Middle. | |
const scaleXCanvas = document.querySelector('#transform-scaleX-canvas'); | |
const scaleXCanvasCtx = scaleXCanvas.getContext('2d'); | |
scaleXCanvasCtx.font = "4em 'sans-serif'"; | |
const scaleXCtxFontWidth = scaleXCanvasCtx.measureText(txt).width; | |
scaleXCanvasCtx.fillText(txt, positionX, scaleXCtxFontWidth); | |
// Bottom. | |
const notScaleXCanvas = document.querySelector('#not-scaleX-canvas'); | |
const notScaleXCanvasCtx = notScaleXCanvas.getContext('2d'); | |
notScaleXCanvasCtx.font = "4em 'sans-serif'"; | |
const notScaleXCtxFontWidth = notScaleXCanvasCtx.measureText(txt).width; | |
const notScaleXCanvasWidth = notScaleXCanvas.width; | |
// transform: scaleX(-1) されている要素のx座標 = canvasサイズ - x座標 - 文字の幅 | |
const notScaleXPositionX = notScaleXCanvasWidth - positionX - notScaleXCtxFontWidth; | |
notScaleXCanvasCtx.fillText(txt, notScaleXPositionX, notScaleXCtxFontWidth); | |
const wrapper = document.querySelector('.canvas-wrapper'); | |
const buttons = document.querySelector('.buttons'); | |
const radioButtons = document.querySelectorAll('.buttons input[type="radio"]'); | |
Array.from(radioButtons, function(radio) { | |
radio.addEventListener('change', function(e){ | |
switch (this.value) { | |
case "2": | |
toggleDesc(false); | |
wrapper.style.justifyContent = 'initial'; | |
buttons.style.margin = '0 0 4em 0'; | |
scaleXCanvas.style.background = 'rgba(255,255,255, 1)'; | |
scaleXCanvas.style.position = 'relative'; | |
notScaleXCanvas.style.background = 'rgba(255,255,255, 1)'; | |
notScaleXCanvas.style.position = 'relative'; | |
break; | |
case "3": | |
toggleDesc(false); | |
wrapper.style.justifyContent = 'initial'; | |
buttons.style.margin = '0 0 4em 0'; | |
scaleXCanvas.style.background = 'rgba(255,255,255, 0)'; | |
scaleXCanvas.style.position = 'absolute'; | |
notScaleXCanvas.style.background = 'rgba(255,255,255, 0)'; | |
notScaleXCanvas.style.position = 'absolute'; | |
break; | |
case "1": | |
default: | |
toggleDesc(true); | |
wrapper.style.justifyContent = 'space-around'; | |
buttons.style.margin = 0; | |
scaleXCanvas.style.background = 'rgba(255,255,255, 1)'; | |
scaleXCanvas.style.position = 'relative'; | |
notScaleXCanvas.style.background = 'rgba(255,255,255, 1)'; | |
notScaleXCanvas.style.position = 'relative'; | |
} | |
}); | |
}); | |
const desc = document.querySelectorAll('.desc'); | |
function toggleDesc(isShow) { | |
Array.from(desc, function(elem) { | |
if (isShow === true) { | |
elem.style.display = 'block'; | |
} else { | |
elem.style.display = 'none'; | |
} | |
}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment