programing

웹 페이지에 있는 텍스트 그림을 애니메이션으로 만들려면 어떻게 해야 합니까?

projobs 2022. 12. 20. 22:26
반응형

웹 페이지에 있는 텍스트 그림을 애니메이션으로 만들려면 어떻게 해야 합니까?

나는 하나의 단어가 중심이 되는 웹 페이지를 갖고 싶다.

이 단어를 애니메이션으로 그려서 페이지와 같은 방법으로 단어를 "쓰기"하고 싶다. 즉, 한 지점에서 시작하여 시간이 지남에 따라 선과 곡선을 그려 최종 결과가 글리프가 되도록 한다.

이 일이 끝나도 상관없다<canvas>CSS를 사용하다jQuery 。

이거 어떻게 해?샅샅이 뒤져봤지만 아무 소용이 없었다.

이 단어를 애니메이션으로 그려서 페이지가 우리가 쓰는 것과 같은 방식으로 단어를 "쓰기" 할 수 있도록 하고 싶다.

캔버스 버전

이렇게 하면 손으로 쓰는 것과 같은 단일 문자가 그려집니다.긴 대시 패턴을 사용합니다.이 경우 온/오프 순서는 시간이 지남에 따라 문자 단위로 바뀝니다.속도 파라미터도 있습니다.

스냅숏
애니메이션 예시(아래 데모 참조)

리얼리즘과 유기적인 느낌을 높이기 위해 랜덤 문자 간격, y 델타 오프셋, 투명도, 매우 미묘한 회전, 마지막으로 이미 손으로 쓴 글꼴을 추가했습니다.이것들은, 다이나믹 파라메타로 정리할 수 있기 때문에, 폭넓은 「쓰기 스타일」을 제공할 수 있습니다.

보다 사실적으로 보기 위해서는 기본적으로 필요하지 않은 경로 데이터가 필요합니다.그러나 이것은 손으로 쓴 동작에 가까운 짧고 효율적인 코드이며 구현하기 쉽습니다.

구조

대시 패턴을 정의함으로써 행진하는 개미나 점선 등을 만들 수 있습니다.이것에 의해, 「오프」점용의 매우 긴 점을 정의하고, 「온」점수를 서서히 증가시켜, 점길이를 애니메이션 하면서 스트로크 했을 때에 선을 그리는 듯한 착각을 얻을 수 있습니다.

오프 도트가 너무 길기 때문에 반복 패턴이 표시되지 않습니다(사용하는 서체의 크기와 특성에 따라 길이가 달라집니다).글자의 경로에는 길이가 있기 때문에 각 점이 적어도 이 길이를 커버하고 있는지 확인해야 합니다.

둘 이상의 경로(예: O, R, P 등)로 구성된 문자는 아웃라인에 대해, 다른 하나는 중공 부분에 대해, 선은 동시에 그려지는 것처럼 보입니다.이 방법으로는 각 경로 세그먼트에 개별적으로 액세스해야 하기 때문에 많은 조치를 취할 수 없습니다.

호환성.

캔버스 요소를 지원하지 않는 브라우저의 경우 텍스트를 태그 사이에 표시할 수 있습니다(예: 스타일 텍스트).

<canvas ...>
    <div class="txtStyle">STROKE-ON CANVAS</div>
</canvas>

데모

그러면 라이브 애니메이션 스트로크 온(의존 관계 없음)이 생성됩니다.

var ctx = document.querySelector("canvas").getContext("2d"),
    dashLen = 220, dashOffset = dashLen, speed = 5,
    txt = "STROKE-ON CANVAS", x = 30, i = 0;

ctx.font = "50px Comic Sans MS, cursive, TSCu_Comic, sans-serif"; 
ctx.lineWidth = 5; ctx.lineJoin = "round"; ctx.globalAlpha = 2/3;
ctx.strokeStyle = ctx.fillStyle = "#1f2f90";

(function loop() {
  ctx.clearRect(x, 0, 60, 150);
  ctx.setLineDash([dashLen - dashOffset, dashOffset - speed]); // create a long dash mask
  dashOffset -= speed;                                         // reduce dash length
  ctx.strokeText(txt[i], x, 90);                               // stroke letter

  if (dashOffset > 0) requestAnimationFrame(loop);             // animate
  else {
    ctx.fillText(txt[i], x, 90);                               // fill final letter
    dashOffset = dashLen;                                      // prep next char
    x += ctx.measureText(txt[i++]).width + ctx.lineWidth * Math.random();
    ctx.setTransform(1, 0, 0, 1, 0, 3 * Math.random());        // random y-delta
    ctx.rotate(Math.random() * 0.005);                         // random rotation
    if (i < txt.length) requestAnimationFrame(loop);
  }
})();
canvas {background:url(http://i.imgur.com/5RIXWIE.png)}
<canvas width=630></canvas>

2019년 편집


사실적인 애니메이션을 만들 수 있는 Javascript 라이브러리를 만들었습니다.사용하기 쉽고 글꼴 역할을 하는 특수 JSON 파일이 필요합니다.

var vara = new Vara("#container", "https://rawcdn.githack.com/akzhy/Vara/ed6ab92fdf196596266ae76867c415fa659eb348/fonts/Satisfy/SatisfySL.json", [{
  text: "Hello World!!",
  fontSize: 48,
  y:10
}, {
  text: "Realistic Animations",
  fontSize: 34,
  color:"#f44336"
}], {
  strokeWidth: 2,
  textAlign:"center"
});
#container {
  padding: 30px;
}
<script src="https://rawcdn.githack.com/akzhy/Vara/16e30acca2872212e28735cfdbaba696a355c780/src/vara.min.js"></script>
<div id="container"></div>

문서와 예는 Github 페이지를 참조하십시오.그리고 코드펜


이전 답변

에서는 snap하여 snap.js를 으로 만듭니다.tspan.stroke-dashoffset.

var s = Snap('svg');
var text = 'Some Long Text'
var len = text.length;
var array = [];
for (var x = 0; x < len; x++) {
  var t = text[x]
  array.push(t);
}
var txt = s.text(50, 50, array)
$('tspan').css({
  'font-size': 50,
  fill: 'none',
  stroke: 'red',
  "stroke-width":2,
  'stroke-dasharray': 300,
  'stroke-dashoffset': 300
})

$('tspan').each(function(index) {
  $(this).stop(true, true).delay(300 * index).animate({
    'stroke-dashoffset': 0,
  }, 300, function() {
    $(this).css('fill', 'red')
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
</svg>

이전 답변


의 svg를 사용합니다.stroke-dasharray

text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  -webkit-animation: draw 8s forwards;
}
@-webkit-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  -webkit-animation: draw 8s forwards;
  -moz-animation: draw 8s forwards;
  -o-animation: draw 8s forwards;
  -ms-animation: draw 8s forwards;
  animation: draw 8s forwards;
}
@-webkit-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@-moz-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@-o-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@-ms-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
<svg width="500" height="500">
  <text x="100" y="80" fill="none" stroke="black" stroke-width="1" font-size="50">Some text</text>
</svg>

keyframes할 수 요.

<svg width="500" height="500">
  <text x="100" y="80" fill="none" stroke="black" stroke-width="5" font-size="50"  stroke-dasharray="1000"
  stroke-dashoffset="1000">Some text
  <animate attributeName="stroke-dashoffset"
    from="1000"
    to="0" 
    dur="8s"
      fill="freeze">
          
      </animate> </text>
</svg>

IE 지원에는 jquery/javascript를 사용할 수 있습니다.

$('text').animate({
    'stroke-dashoffset':'0'
},8000)
text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
  <text x="100" y="80" fill="none" stroke="black" stroke-width="1" font-size="50" 
 >Some text
  </text>
</svg>

CSS만:

@keyframes fadein_left {
  from {
    left: 0;
  }
  to {
    left: 100%;
  }
}

#start:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0%;
  opacity: 0.7;
  height: 25px;
  background: #fff;
  animation: fadein_left 3s;
}
<div id="start">
  some text some text some text some text some text
</div>

많은 테스트를 거친 후, 여기 몇 가지 노트가 있습니다.목표는 사용자의 상호 작용이 필요한 DOM 무거운 페이지에 빠른 텍스트 데이터를 최소 차단 방식으로 표시하는 것입니다.

물론 같은 일을 할 수 있는 많은 방법이 있다.이 예에서는 차이가 명확하지 않을 수 있습니다.복잡한 인터페이스에 적용됩니다.

가장 느린 속도:innerHTML인라인 스타일링.DOM을 사용하다브라우저는 기차를 유지하기 위해 열심히 일하고 있다.에러가 빨리 발생해, 메모리 누전과 프리즈의 원인이 됩니다.

setInterval(function(){
  out.innerHTML = `<span style="position:fixed;top:${~~(Math.random() * 220)}px">${Math.random() * 1000}<span>`
},1)
<h1 id="out"></h1>

훨씬 더 나은 방법:사용.textContent,requestAnimationFrame'API' api.이 작업은 훨씬 더 원활히 진행됩니다. DOM dom dom dom 、 DOM dom 。사용자 상호 작용에 의해 거부감이 차단되지 않습니다.인터페이스의 응답성을 유지하기 위해 일부 응답을 건너뛸 수 있습니다.

let job
const paint = () => {
  job = requestAnimationFrame(paint)
  out.textContent = Math.random() * 1000
  out.animate([{top: ~~(Math.random() * 220)+"px"},{top:0}],{duration: 1,iterations: 1})
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(paint)
#out{
position: fixed}
<h1 id="out"></h1>

위의 예에서는 텍스트 오버플로우용으로 DOM이 재계산되고 있습니다.디버거가 강하게 점멸하고 있는 것을 알 수 있습니다.이것은 계단식 요소에서 매우 중요합니다!이렇게 해도 Javascript 및 사용자 스크롤 속도가 느려질 수 있습니다.

여기에 이미지 설명 입력

파워:css만으로 데이터를 갱신할 수 있습니다.content규칙 "css" 입니다.그러면 텍스트를 선택할 수 없습니다.

let job
const paint = () => {
  job = requestAnimationFrame(paint)
  out.setAttribute('data-before', Math.random() * 1000)
  out.animate([{top: ~~(Math.random() * 220)+"px"},{top:0}],{duration: 1,iterations: 1})
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(paint)
#out{
  position: fixed
  
  }
#out:before {
   content: attr(data-before)
 }
<h1 id="out"></h1>

여기에 이미지 설명 입력

테스트 결과, javascript 엔진은 다른 작업을 빠르게 건너뛰고 있습니다.경우에 따라서는, 상기의 예보다 조금 늦게 기동할 수 있습니다.하지만 그것 말고도, 이것은 사용자 스크롤을 차단하지 않고, 디버거 또한 더 이상 점프하지 않는 것을 좋아한다.

언급URL : https://stackoverflow.com/questions/29911143/how-can-i-animate-the-drawing-of-text-on-a-web-page

반응형